分析OpenSurf(4)

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

void Surf::getDescriptor(bool bUpright)
{
  int y, x, sample_x, sample_y, count=0;
  int i = 0, ix = 0, j = 0, jx = 0, xs = 0, ys = 0;
  float scale, *desc, dx, dy, mdx, mdy, co, si;
  float gauss_s1 = 0.f, gauss_s2 = 0.f;
  float rx = 0.f, ry = 0.f, rrx = 0.f, rry = 0.f, len = 0.f;
  float cx = -0.5f, cy = 0.f; //Subregion centers for the 4x4 gaussian weighting
  
  Ipoint *ipt = &ipts[index];
  scale = ipt->scale;//尺度
  x = fRound(ipt->x);
  y = fRound(ipt->y);//空间位置  
  desc = ipt->descriptor;
  
  if (bUpright)
  {//不需旋转的情况
    co = 1;
    si = 0;
  }
  else
  {//需要旋转调整选取邻域的情况
    co = cos(ipt->orientation);
    si = sin(ipt->orientation);
  }
  
  i = -8;
  
  //Calculate descriptor for this interest point
  while(i < 12)
  {
    j = -8;
    i = i-4;
    cx += 1.f;
    cy = -0.5f;
  
    while(j < 12) 
    {
      dx=dy=mdx=mdy=0.f;//特征向量的构成
      cy += 1.f;
  
      j = j - 4;
  
      ix = i + 5;//ix=i0+1,这里面i0和j0分别取得的值为-8,-3,2,7
      jx = j + 5;//iy=j0+1
  
      xs = fRound(x + ( -jx*scale*si + ix*scale*co));
      ys = fRound(y + ( jx*scale*co + ix*scale*si));
      //fRound为4舍五入算法,最近邻插值寻找旋转对应点
  
      for (int k = i; k < i + 9; ++k) 
      {
        for (int l = j; l < j + 9; ++l) 
        {
          //Get coords of sample point on the rotated axis
          sample_x = fRound(x + (-l*scale*si + k*scale*co));
          sample_y = fRound(y + ( l*scale*co + k*scale*si));
  
          //Get the gaussian weighted x and y responses
          gauss_s1 = gaussian(xs-sample_x,ys-sample_y,2.5f*scale);
          rx = haarX(sample_y, sample_x, 2*fRound(scale));
          ry = haarY(sample_y, sample_x, 2*fRound(scale));
  
          //Get the gaussian weighted x and y responses on rotated axis
          rrx = gauss_s1*(-rx*si + ry*co);
          rry = gauss_s1*(rx*co + ry*si);
  
          dx += rrx;
          dy += rry;
          mdx += fabs(rrx);
          mdy += fabs(rry);
  
        }
      }
  
      //Add the values to the descriptor vector
      gauss_s2 = gaussian(cx-2.0f,cy-2.0f,1.5f);
  
      desc[count++] = dx*gauss_s2;
      desc[count++] = dy*gauss_s2;
      desc[count++] = mdx*gauss_s2;
      desc[count++] = mdy*gauss_s2;
  
      len += (dx*dx + dy*dy + mdx*mdx + mdy*mdy) * gauss_s2*gauss_s2;
      j += 9;
    }
    i += 9;
  }
  
  //Convert to Unit Vector   特征向量归一化
  len = sqrt(len);
  for(int i = 0; i < 64; ++i)
    desc[i] /= len;
  
}

其中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)就不用再做解释了吧。

 

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

 来个截图~~

分析OpenSurf(4)_第1张图片

谢谢大家~

转载请注明blue_lghttp://www.cnblogs.com/blue-lg/archive/2012/07/20/2600436.html



你可能感兴趣的:(OpenSURF)