< meta http-equiv="description" content="由于各层大小不一致,顾在比较大小的时候,要统一到统一尺度下,在getResponse()里面有所体现,即先计算两者尺度之比,比如尺度之比为2,最上层当前点为(20,25),那么需要比较的紧邻下层点为(40,50)而不是下层的(20,25)。"/>

blue_lg的surf c++源码 解析(四)

[来源] 达内    [编辑] 达内   [时间]2012-08-30

由于各层大小不一致,顾在比较大小的时候,要统一到统一尺度下,在getResponse()里面有所体现,即先计算两者尺度之比,比如尺度之比为2,最上层当前点为(20,25),那么需要比较的紧邻下层点为(40,50)而不是下层的(20,25)。

(接上文) 

③根据上一步计算每层的每个点的det(Happrox),判断极值点。

在fasthessian.cpp里面找到getIpoints(),下面开始抽取每组(共octaves组)相邻的3层(共有4层,每组有2个这样层的满足):                            

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_486401" class="syntaxhighlighter collapsed nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: visible !important; padding-top: 0px"> < div class="toolbar" style="z-index: 10 !important; box-sizing: content-box !important; border-bottom: rgb(204,204,204) 1px solid; position: static !important; border-left: rgb(204,204,204) 1px solid; padding-bottom: 0px !important; line-height: 2em !important; background-color: rgb(245,245,245) !imp ortant; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0.8em !important; outline-width: 0px !important; width: auto !important; bottom: auto !important; padding-right: 0.8em !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Co urier, monospace !important; float: none !important; height: auto !important; color: blue !important; font-size: 1em !important; vertical-align: baseline !important; overflow: visible !important; border-top: rgb(204,204,204) 1px solid; top: 1px !important; right: 1px !important; border-right: rgb(204,204,204) 1px solid; padding-top: 0.1em !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> View Code

  在判断的时候用到了isExtremum()和interpolateExtremum()子函数,在当前cpp内找到它们,并分析。

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_883711" class="syntaxhighlighter collapsed nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: visible !important; padding-top: 0px"> < div class="toolbar" style="z-index: 10 !important; box-sizing: content-box !important; border-bottom: rgb(204,204,204) 1px solid; position: static !important; border-left: rgb(204,204,204) 1px solid; padding-bottom: 0px !important; line-height: 2em !important; background-color: rgb(245,245,245) !imp ortant; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0.8em !important; outline-width: 0px !important; width: auto !important; bottom: auto !important; padding-right: 0.8em !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Co urier, monospace !important; float: none !important; height: auto !important; color: blue !important; font-size: 1em !important; vertical-align: baseline !important; overflow: visible !important; border-top: rgb(204,204,204) 1px solid; top: 1px !important; right: 1px !important; border-right: rgb(204,204,204) 1px solid; padding-top: 0.1em !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> View Code

  大家务必 意,由于各层大小不一致,顾在比较大小的时候,要统一到统一尺度下,在getResponse()里面有所体现,即先计算两者尺度之比,比如尺度之比为2,最上层当前点为(20,25),那么需要比较的紧邻下层点为(40,50)而不是下层的(20,25)。再看若当前点为极值点,那么调用 interpolateExtremum():

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_329672" class="syntaxhighlighter collapsed nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: visible !important; padding-top: 0px"> < div class="toolbar" style="z-index: 10 !important; box-sizing: content-box !important; border-bottom: rgb(204,204,204) 1px solid; position: static !important; border-left: rgb(204,204,204) 1px solid; padding-bottom: 0px !important; line-height: 2em !important; background-color: rgb(245,245,245) !imp ortant; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0.8em !important; outline-width: 0px !important; width: auto !important; bottom: auto !important; padding-right: 0.8em !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Co urier, monospace !important; float: none !important; height: auto !important; color: blue !important; font-size: 1em !important; vertical-align: baseline !important; overflow: visible !important; border-top: rgb(204,204,204) 1px solid; top: 1px !important; right: 1px !important; border-right: rgb(204,204,204) 1px solid; padding-top: 0.1em !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> View Code

  本函数实现功能,利用插值精确计算极值点在原图像中的位置,并保存在ipt中。

      打开interpolateStep,其中deriv3D是求当前点的3的方向上的一阶导,hessian3D是求当前点的3维hessian二阶导,最后计算出3个方向的偏差值xi,xr,xc .

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_800737" class="syntaxhighlighter collapsed nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: visible !important; padding-top: 0px"> < div class="toolbar" style="z-index: 10 !important; box-sizing: content-box !important; border-bottom: rgb(204,204,204) 1px solid; position: static !important; border-left: rgb(204,204,204) 1px solid; padding-bottom: 0px !important; line-height: 2em !important; background-color: rgb(245,245,245) !imp ortant; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0.8em !important; outline-width: 0px !important; width: auto !important; bottom: auto !important; padding-right: 0.8em !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Co urier, monospace !important; float: none !important; height: auto !important; color: blue !important; font-size: 1em !important; vertical-align: baseline !important; overflow: visible !important; border-top: rgb(204,204,204) 1px solid; top: 1px !important; right: 1px !important; border-right: rgb(204,204,204) 1px solid; padding-top: 0.1em !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> View Code

  下面开始在特征点周围提取特征描述符


④ 提取特征描述符

转到surf.cpp里寻找getDescriptors(),由于upright初始化设置为false(为特征点分配主方向,并旋转找到邻域提取特征描述符),若为true,则直接提取邻域特征描述符。

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_41834" class="syntaxhighlighter collapsed nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: visible !important; padding-top: 0px"> < div class="toolbar" style="z-index: 10 !important; box-sizing: content-box !important; border-bottom: rgb(204,204,204) 1px solid; position: static !important; border-left: rgb(204,204,204) 1px solid; padding-bottom: 0px !important; line-height: 2em !important; background-color: rgb(245,245,245) !imp ortant; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0.8em !important; outline-width: 0px !important; width: auto !important; bottom: auto !important; padding-right: 0.8em !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Co urier, monospace !important; float: none !important; height: auto !important; color: blue !important; font-size: 1em !important; vertical-align: baseline !important; overflow: visible !important; border-top: rgb(204,204,204) 1px solid; top: 1px !important; right: 1px !important; border-right: rgb(204,204,204) 1px solid; padding-top: 0.1em !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> View Code

  其实两者区别在于提取特征描述符之前判断upright的时候是否需要多调用一句getOrientation()就是了。前者不考虑旋转,两幅图只是尺度有异,而后者还考虑了旋转不变性,更加全面。

 几个地方:   

1.如论文提出的采取r=6的圆域,共计包含109个像素点,大家可以算算,在此不多解释了。

2.像素点的方向由harrx和harry计算得到,相当于梯度公式里面的dx和dy,然后利用getAngle得到θ(分布在0~2∏,而不是简单的tan-1 (harrx/harry)取值在0~∏)。

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_852131" class="syntaxhighlighter nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: auto !important; padding-top: 0px"> < div class="toolbar" style="background-image: none !important; z-index: 10 !important; box-sizing: content-box !important; border-bottom: medium none; position: absolute !important; border-left: medium none; padding-bottom: 0px !important; line-height: 2em !important; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0px !important; outline-width: 0px !important; width: 11px !important; bottom: auto !important; padding-right: 0px !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Courier, monospace !important; float: none !im portant; height: 11px !important; color: rgb(255,255,255) !important; font-size: 10px !important; vertical-align: baseline !important; overflow: visible !important; border-top: medium none; top: 1px !important; right: 1px !important; border-right: medium none; padding-top: 0px !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> ?
< table border="0" cellspacing="0" cellpadding="0" style="background-image: none !important; box-sizing: content-box !important; position: static !important; border-bottom-style: solid; border-bottom-color: rgb(192,192,192); text-align: left !important; padding-bottom: 0px !important; line-height: 2em !important; border-right-style: solid; border-top-color: rgb(192,192,192); margin: 0px auto; outline-style: none !important; outline-color: invert !important; padding-left: 0px !important; outline-width: 0px !important; width: 998px; bottom: auto !important; padding-right: 0px !important; border-co llapse: collapse; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Courier, monospace !important; border-top-style: solid; float: none !important; height: auto !important; border-right-color: rgb(192,192,192); font-size: 12px !important; vertical-align: baseline !important; border-l eft-style: solid; overflow: visible !important; border-left-color: rgb(192,192,192); top: auto !important; right: auto !important; padding-top: 0px !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px">
//! Calculate Haar wavelet responses in x direction
inline float Surf::haarX(int row, int column, int s)
{
   return   BoxIntegral(img, row-s/2, column, s, s/2)
     -1 * BoxIntegral(img, row-s/2, column-s/2, s, s/2);
}
 
//-------------------------------------------------------
 
//! Calculate Haar wavelet responses in y direction
inline float Surf::haarY(int row, int column, int s)
{
   return   BoxIntegral(img, row, column-s/2, s/2, s)
     -1 * BoxIntegral(img, row-s/2, column-s/2, s/2, s);
}
 
float Surf::getAngle(float X, float Y) //计算每个点的方向角
{
   if (X > 0 && Y >= 0)
     return  atan(Y/X);
 
   if (X < 0 && Y >= 0)
     return  pi - atan(-Y/X);
 
   if (X < 0 && Y < 0)
     return  pi + atan(Y/X);
 
   if (X > 0 && Y < 0)
     return  2*pi - atan(-Y/X);
 
   return  0;
}

  图示如右                          harr  (黑色代表-1,白色为1,即白色区域积分值减去黑色区域积分值)

 

在getOrienation()里面resx和resy分别是上面计算出来的harrx和harry分别乘上高斯模板系数gauss25。

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_482654" class="syntaxhighlighter nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: auto !important; padding-top: 0px"> < div class="toolbar" style="background-image: none !important; z-index: 10 !important; box-sizing: content-box !important; border-bottom: medium none; position: absolute !important; border-left: medium none; padding-bottom: 0px !important; line-height: 2em !important; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0px !important; outline-width: 0px !important; width: 11px !important; bottom: auto !important; padding-right: 0px !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Courier, monospace !important; float: none !im portant; height: 11px !important; color: rgb(255,255,255) !important; font-size: 10px !important; vertical-align: baseline !important; overflow: visible !important; border-top: medium none; top: 1px !important; right: 1px !important; border-right: medium none; padding-top: 0px !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> ?
< table border="0" cellspacing="0" cellpadding="0" style="background-image: none !important; box-sizing: content-box !important; position: static !important; border-bottom-style: solid; border-bottom-color: rgb(192,192,192); text-align: left !important; padding-bottom: 0px !important; line-height: 2em !important; border-right-style: solid; border-top-color: rgb(192,192,192); margin: 0px auto; outline-style: none !important; outline-color: invert !important; padding-left: 0px !important; outline-width: 0px !important; width: 998px; bottom: auto !important; padding-right: 0px !important; border-co llapse: collapse; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Courier, monospace !important; border-top-style: solid; float: none !important; height: auto !important; border-right-color: rgb(192,192,192); font-size: 12px !important; vertical-align: baseline !important; border-l eft-style: solid; overflow: visible !important; border-left-color: rgb(192,192,192); top: auto !important; right: auto !important; padding-top: 0px !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px">
void Surf::getOrientation()
{
   ......
    //将像素点按方向角分配到6个宽为60度的区间去,比如说可以将80度分配到ang1=90度,因为90-30<80<90+30
    // loop slides pi/3 window around feature point
   for (ang1 = 0; ang1 < 2*pi;  ang1+=0.15f) {
     ang2 = ( ang1+pi/3.0f > 2*pi ? ang1-5.0f*pi/3.0f : ang1+pi/3.0f); //保证ang1+60 不会大于360度
     sumX = sumY = 0.f;
     for (unsigned int k = 0; k < Ang.size(); ++k) //对于半径为6的圆邻域,这里面的Ang.size()=109
     {
       // get angle from the x-axis of the sample point
       const float & ang = Ang[k];
       // determine whether the point is within the window
       if   (ang1 < ang2 && ang1 < ang && ang < ang2)
       {
         sumX+=resX[k]; 
         sumY+=resY[k];
       }
       else  if  (ang2 < ang1 &&
         ((ang > 0 && ang < ang2) || (ang > ang1 && ang < 2*pi) ))
       {
         sumX+=resX[k]; 
         sumY+=resY[k];
       }
     }
     // if the vector produced from this window is longer than all
     // previous vectors then this forms the new dominant direction
     if   (sumX*sumX + sumY*sumY > max) //寻找一个ang1使得角度在此区间的长度最大 ,然后计算出累加的resx和resy,得出的方向角
     {
       // store largest orientation
       max = sumX*sumX + sumY*sumY;
       orientation = getAngle(sumX, sumY);
     }
   }
   // assign orientation of the dominant response vector
   ipt->orientation = orientation;
}

  好了,终于要开始提取特征描述符了哈~.~

< div class="cnblogs_Highlighter" style="text-align: left; padding-bottom: 0px; line-height: 19px; background-color: rgb(254,254,242); margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 13px; padding-top: 0px">
< div id="highlighter_46684" class="syntaxhighlighter collapsed nogutter javascript" style="position: relative !important; padding-bottom: 0px; background-color: rgb(255,255,255) !important; margin: 1em 0px; padding-left: 0px; width: 998px; padding-right: 0px; font-size: 1em !important; overflow: visible !important; padding-top: 0px"> < div class="toolbar" style="z-index: 10 !important; box-sizing: content-box !important; border-bottom: rgb(204,204,204) 1px solid; position: static !important; border-left: rgb(204,204,204) 1px solid; padding-bottom: 0px !important; line-height: 2em !important; background-color: rgb(245,245,245) !imp ortant; margin: 0px; outline-style: none !important; outline-color: invert !important; padding-left: 0.8em !important; outline-width: 0px !important; width: auto !important; bottom: auto !important; padding-right: 0.8em !important; font-family: 'Courier New', Consolas, 'Bitstream Vera Sans Mono', Co urier, monospace !important; float: none !important; height: auto !important; color: blue !important; font-size: 1em !important; vertical-align: baseline !important; overflow: visible !important; border-top: rgb(204,204,204) 1px solid; top: 1px !important; right: 1px !important; border-right: rgb(204,204,204) 1px solid; padding-top: 0.1em !important; left: auto !important; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px"> View Code

  其中i和j分别取的值为-8,-3,2,7,很明显i,j确定的邻域为7-(-8)+1=16,16x16的邻域,旋转对应的在原图像的点位置为   

                               xs = fRound(x + ( -jx*scale*si + ix*scale*co));                   ys = fRound(y + ( jx*scale*co + ix*scale*si));

                               co = cos(ipt->orientation);                                                  si = sin(ipt->orientation);                        【ipt->orientation为特征点的方向角】

共有 4x4个子块(9x9=81个像素点),每个子块分别计算了其中16个dx,dy,|dx|,|dy|之和(当然还要考虑高斯滤波权重系数),则最终的特征描述符为4x4x4=64维向量。

 

main.cpp内mainImage函数内部drawIpoints(img, ipts)就不用再做解释了吧。

 

搞了一天,终于搞完了~~

 来个截图~~

谢谢大家~(全文结束,转自cnblogs,达内c++培训整理)

资源下载