⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sift.cpp

📁 linux操作系统下的sift算法
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  filter = 0 ;  if( octaves ) {    for(int o = 0 ; o < O ; ++o) {      delete [] octaves[ o ] ;    }    delete [] octaves ;  }  octaves = 0 ;    if( temp ) {    delete [] temp ;     }  temp = 0  ; }// ===================================================================//                                                         getKeypoint// -------------------------------------------------------------------/** @brief Get keypoint from position and scale ** ** The function returns a keypoint with a given position and ** scale. Note that the keypoint structure contains fields that make ** sense only in conjunction with a specific scale space. Therefore ** the keypoint structure should be re-calculated whenever the filter ** is applied to a new image, even if the parameters @a x, @a y and ** @a sigma do not change. ** ** @param x x coordinate of the center. ** @peram y y coordinate of the center. ** @param sigma scale. ** @return Corresponing keypoint. **/Sift::KeypointSift::getKeypoint(VL::float_t x, VL::float_t y, VL::float_t sigma) const{  // keypoints are restricted to have  //  * si in the range smin+1 smax-2   //  * o  in the range omin,omin+O-1  //  // Depending on the values of smin and smax, often the same  // keypoint can have multiple equivalent indexes si,o. In this  // case we choose the one with biggest index o (save computation).  //  // In addition, we relax a bit the requirements on si. We start by  // letting si vary in the range smin,smax-1 and we compute both o  // and si. Then we clamp si to the range smin+1,smax-2. This allows  // us to be more consistent with the way SIFT descriptors are  // usually generated (indeed for the SIFT detector si is always in  // the range smin+1,smax-2, but in some cases round(s) != s because  // of the quadratic interpolation in scale).  /* We do this in steps. Let phi=log2(sigma/sigma0)         1) find max o : o+smin/S < phi, i.e. o=floor(phi+smin/S).    2) clamp this vlaue to the range [omin,omin+O-1]    3) compute the fractional scale index s = S(phi-o)    4) round the fractional scale index to get si = round(s)    5) clamp si to the range [smin+1,smax-2]  */  int o,ix,iy,is ;  VL::float_t s,phi ;  phi = log2(sigma/sigma0) ;  o   = fast_floor( phi + VL::float_t(smin)/S ) ;  o   = std::min(o,omin+O-1) ;  o   = std::max(o,omin) ;  s   = S*(phi-o) ;  is  = int(s + 0.5) ;  is  = std::max(is,smax-2) ;  is  = std::min(is,smin+1) ;    VL::float_t per = getOctaveSamplingPeriod(o) ;  ix = int(x * per + 0.5) ;  iy = int(y * per + 0.5) ;    Keypoint key ;  key.o  = o ;  key.ix = ix ;  key.iy = iy ;  key.is = is ;  key.x = x ;  key.y = y ;  key.s = s ;    key.sigma = sigma ;    return key ;}// ===================================================================//                                                           process()// -------------------------------------------------------------------/** @brief Compute Gaussian Scale Space ** ** The method computes the Gaussian scale space of the specified ** image. The scale space data is managed internally and can be ** accessed by means of getOctave() and getLevel(). ** ** @remark Calling this method will delete the list of keypoints ** constructed by detectKeypoints(). ** ** @param _im_pt pointer to image data. ** @param _width image width. ** @param _height image height . **/voidSift::process(const pixel_t* _im_pt, int _width, int _height){  using namespace Detail ;  width  = _width ;  height = _height ;  prepareBuffers() ;    VL::float_t sigmak = powf(2.0f, 1.0 / S) ;  VL::float_t dsigma0 = sigma0 * sqrt (1.0f - 1.0f / (sigmak*sigmak) ) ;    // -----------------------------------------------------------------  //                                                 Make pyramid base  // -----------------------------------------------------------------  if( omin < 0 ) {    copyAndUpsampleRows(temp,       _im_pt, width,  height  ) ;    copyAndUpsampleRows(octaves[0], temp,   height, 2*width ) ;          for(int o = omin + 1 ; o < 0 ; ++o) {      copyAndUpsampleRows(temp,       octaves[0], width  << -o,    height << -o) ;      copyAndUpsampleRows(octaves[0], temp,       height << -o, 2*(width  << -o)) ;                }  } else if( omin > 0 ) {    copyAndDownsample(octaves[0], _im_pt, width, height, 1 << omin) ;  } else {    copy(octaves[0], _im_pt, width, height) ;  }  {    VL::float_t sa = sigma0 * powf(sigmak, smin) ;     VL::float_t sb = sigman / powf(2.0f,   omin) ; // review this    if( sa > sb ) {      VL::float_t sd = sqrt ( sa*sa - sb*sb ) ;      smooth( octaves[0], temp, octaves[0],               getOctaveWidth(omin),              getOctaveHeight(omin),               sd ) ;    }  }  // -----------------------------------------------------------------  //                                                      Make octaves  // -----------------------------------------------------------------  for(int o = omin ; o < omin+O ; ++o) {    // Prepare octave base    if( o > omin ) {      int sbest = std::min(smin + S, smax) ;      copyAndDownsample(getLevel(o,   smin ), 				getLevel(o-1, sbest),				getOctaveWidth(o-1),				getOctaveHeight(o-1), 2 ) ;      VL::float_t sa = sigma0 * powf(sigmak, smin      ) ;      VL::float_t sb = sigma0 * powf(sigmak, sbest - S ) ;      if(sa > sb ) {        VL::float_t sd = sqrt ( sa*sa - sb*sb ) ;        smooth( getLevel(o,0), temp, getLevel(o,0),                 getOctaveWidth(o), getOctaveHeight(o),                sd ) ;      }    }    // Make other levels    for(int s = smin+1 ; s <= smax ; ++s) {      VL::float_t sd = dsigma0 * powf(sigmak, s) ;      smooth( getLevel(o,s), temp, getLevel(o,s-1),              getOctaveWidth(o), getOctaveHeight(o),              sd ) ;    }  }}/** @brief Sift detector ** ** The function runs the SIFT detector on the stored Gaussian scale ** space (see process()). The detector consists in three steps ** ** - local maxima detection; ** - subpixel interpolation; ** - rejection of weak keypoints (@a threhsold); ** - rejection of keypoints on edge-like structures (@a edgeThreshold). ** ** As they are found, keypoints are added to an internal list.  This ** list can be accessed by means of the member functions ** getKeypointsBegin() and getKeypointsEnd(). The list is ordered by ** octave, which is usefult to speed-up computeKeypointOrientations() ** and computeKeypointDescriptor(). **/voidSift::detectKeypoints(VL::float_t threshold, VL::float_t edgeThreshold){  keypoints.clear() ;  int nValidatedKeypoints = 0 ;  // Process one octave per time  for(int o = omin ; o < omin + O ; ++o) {            int const xo = 1 ;    int const yo = getOctaveWidth(o) ;    int const so = getOctaveWidth(o) * getOctaveHeight(o) ;    int const ow = getOctaveWidth(o) ;    int const oh = getOctaveHeight(o) ;    VL::float_t xperiod = getOctaveSamplingPeriod(o) ;    // -----------------------------------------------------------------    //                                           Difference of Gaussians    // -----------------------------------------------------------------    pixel_t* dog = temp ;    tempIsGrad = false ;    {      pixel_t* pt = dog ;      for(int s = smin ; s <= smax-1 ; ++s) {        pixel_t* srca = getLevel(o, s  ) ;        pixel_t* srcb = getLevel(o, s+1) ;        pixel_t* enda = srcb ;        while( srca != enda ) {          *pt++ = *srcb++ - *srca++ ;        }      }    }        // -----------------------------------------------------------------    //                                           Find points of extremum    // -----------------------------------------------------------------    {      pixel_t* pt  = dog + xo + yo + so ;      for(int s = smin+1 ; s <= smax-2 ; ++s) {        for(int y = 1 ; y < oh - 1 ; ++y) {          for(int x = 1 ; x < ow - 1 ; ++x) {                      pixel_t v = *pt ;                        // assert( (pt - x*xo - y*yo - (s-smin)*so) - dog == 0 ) ;            #define CHECK_NEIGHBORS(CMP,SGN)                    \            ( v CMP ## = SGN 0.8 * threshold &&     \              v CMP *(pt + xo) &&                   \              v CMP *(pt - xo) &&                   \              v CMP *(pt + so) &&                   \              v CMP *(pt - so) &&                   \              v CMP *(pt + yo) &&                   \              v CMP *(pt - yo) &&                   \                                                    \              v CMP *(pt + yo + xo) &&              \              v CMP *(pt + yo - xo) &&              \              v CMP *(pt - yo + xo) &&              \              v CMP *(pt - yo - xo) &&              \                                                    \              v CMP *(pt + xo      + so) &&         \              v CMP *(pt - xo      + so) &&         \              v CMP *(pt + yo      + so) &&         \              v CMP *(pt - yo      + so) &&         \              v CMP *(pt + yo + xo + so) &&         \              v CMP *(pt + yo - xo + so) &&         \              v CMP *(pt - yo + xo + so) &&         \              v CMP *(pt - yo - xo + so) &&         \                                                    \              v CMP *(pt + xo      - so) &&         \              v CMP *(pt - xo      - so) &&         \              v CMP *(pt + yo      - so) &&         \              v CMP *(pt - yo      - so) &&         \              v CMP *(pt + yo + xo - so) &&         \              v CMP *(pt + yo - xo - so) &&         \              v CMP *(pt - yo + xo - so) &&         \              v CMP *(pt - yo - xo - so) )                        if( CHECK_NEIGHBORS(>,+) || CHECK_NEIGHBORS(<,-) ) {                            Keypoint k ;              k.ix = x ;              k.iy = y ;              k.is = s ;              keypoints.push_back(k) ;            }            pt += 1 ;          }          pt += 2 ;        }        pt += 2*yo ;      }    }    // -----------------------------------------------------------------    //                                               Refine local maxima    // -----------------------------------------------------------------    { // refine      KeypointsIter siter ;      KeypointsIter diter ;            for(diter = siter = keypointsBegin() + nValidatedKeypoints ;           siter != keypointsEnd() ;           ++siter) {               int x = int( siter->ix ) ;        int y = int( siter->iy ) ;        int s = int( siter->is ) ;                        VL::float_t Dx=0,Dy=0,Ds=0,Dxx=0,Dyy=0,Dss=0,Dxy=0,Dxs=0,Dys=0 ;        VL::float_t  b [3] ;        pixel_t* pt ;        int dx = 0 ;        int dy = 0 ;        // must be exec. at least once        for(int iter = 0 ; iter < 5 ; ++iter) {          VL::float_t A[3*3] ;                    x += dx ;          y += dy ;          pt = dog             + xo * x            + yo * y            + so * (s - smin) ;#define at(dx,dy,ds) (*( pt + (dx)*xo + (dy)*yo + (ds)*so))#define Aat(i,j)     (A[(i)+(j)*3])                        /* Compute the gradient. */          Dx = 0.5 * (at(+1,0,0) - at(-1,0,0)) ;          Dy = 0.5 * (at(0,+1,0) - at(0,-1,0));          Ds = 0.5 * (at(0,0,+1) - at(0,0,-1)) ;                    /* Compute the Hessian. */          Dxx = (at(+1,0,0) + at(-1,0,0) - 2.0 * at(0,0,0)) ;          Dyy = (at(0,+1,0) + at(0,-1,0) - 2.0 * at(0,0,0)) ;          Dss = (at(0,0,+1) + at(0,0,-1) - 2.0 * at(0,0,0)) ;                    Dxy = 0.25 * ( at(+1,+1,0) + at(-1,-1,0) - at(-1,+1,0) - at(+1,-1,0) ) ;          Dxs = 0.25 * ( at(+1,0,+1) + at(-1,0,-1) - at(-1,0,+1) - at(+1,0,-1) ) ;          Dys = 0.25 * ( at(0,+1,+1) + at(0,-1,-1) - at(0,-1,+1) - at(0,+1,-1) ) ;                    /* Solve linear system. */          Aat(0,0) = Dxx ;          Aat(1,1) = Dyy ;          Aat(2,2) = Dss ;          Aat(0,1) = Aat(1,0) = Dxy ;          Aat(0,2) = Aat(2,0) = Dxs ;          Aat(1,2) = Aat(2,1) = Dys ;                    b[0] = - Dx ;          b[1] = - Dy ;          b[2] = - Ds ;                    // Gauss elimination          for(int j = 0 ; j < 3 ; ++j) {            // look for leading pivot            VL::float_t maxa = 0 ;            VL::float_t maxabsa = 0 ;            int   maxi = -1 ;            int i ;            for(i = j ; i < 3 ; ++i) {              VL::float_t a    = Aat(i,j) ;              VL::float_t absa = fabsf( a ) ;              if ( absa > maxabsa ) {                maxa    = a ;                maxabsa = absa ;                maxi    = i ;              }            }            // singular?            if( maxabsa < 1e-10f ) {              b[0] = 0 ;              b[1] = 0 ;              b[2] = 0 ;              break ;            }            i = maxi ;            // swap j-th row with i-th row and            // normalize j-th row            for(int jj = j ; jj < 3 ; ++jj) {              std::swap( Aat(j,jj) , Aat(i,jj) ) ;              Aat(j,jj) /= maxa ;            }            std::swap( b[j], b[i] ) ;            b[j] /= maxa ;            // elimination            for(int ii = j+1 ; ii < 3 ; ++ii) {              VL::float_t x = Aat(ii,j) ;              for(int jj = j ; jj < 3 ; ++jj) {                Aat(ii,jj) -= x * Aat(j,jj) ;                              }              b[ii] -= x * b[j] ;            }          }          // backward substitution          for(int i = 2 ; i > 0 ; --i) {            VL::float_t x = b[i] ;            for(int ii = i-1 ; ii >= 0 ; --ii) {              b[ii] -= x * Aat(ii,i) ;            }          }          /* If the translation of the keypoint is big, move the keypoint           * and re-iterate the computation. Otherwise we are all set.           */          dx= ((b[0] >  0.6 && x < ow-2) ?  1 : 0 )            + ((b[0] < -0.6 && x > 1   ) ? -1 : 0 ) ;                    dy= ((b[1] >  0.6 && y < oh-2) ?  1 : 0 )            + ((b[1] < -0.6 && y > 1   ) ? -1 : 0 ) ;          /*                    std::cout<<x<<","<<y<<"="<<at(0,0,0)                   <<"("                   <<at(0,0,0)+0.5 * (Dx * b[0] + Dy * b[1] + Ds * b[2])<<")"                   <<" "<<std::flush ;           */          if( dx == 0 && dy == 0 ) break ;        }                /* std::cout<<std::endl ; */                // Accept-reject keypoint        {          VL::float_t val = at(0,0,0) + 0.5 * (Dx * b[0] + Dy * b[1] + Ds * b[2]) ;           VL::float_t score = (Dxx+Dyy)*(Dxx+Dyy) / (Dxx*Dyy - Dxy*Dxy) ;           VL::float_t xn = x + b[0] ;          VL::float_t yn = y + b[1] ;          VL::float_t sn = s + b[2] ;                    if(fast_abs(val) > threshold &&             score < (edgeThreshold+1)*(edgeThreshold+1)/edgeThreshold &&              score >= 0 &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -