分析OpenSurf(1)

panda1234lee發表於2012-11-27

說是surf,其實原演算法是基於Notes on the OpenSURF Library這篇文件。

 

下載地址:http://opensurf1.googlecode.com/files/OpenSURFcpp.zip

 

首先定義 #define PROCEDURE 1

緊接著進入main()主函式:

main.cpp

int main(void) 
{
  if (PROCEDURE == 1) return mainImage();//靜態影象的特徵點監測
  if (PROCEDURE == 2) return mainVideo();//通過攝像頭實時監測,提取特徵點
  if (PROCEDURE == 3) return mainMatch();//影象匹配演算法,在視訊序列裡尋找一個已知物體影象
  if (PROCEDURE == 4) return mainMotionPoints();//視訊中行為監測
  if (PROCEDURE == 5) return mainStaticMatch();//靜態影象間的特徵點匹配
  if (PROCEDURE == 6) return mainKmeans();//靜態影象的k-means聚類
}
 我們以監測靜態影象特徵點(即1)為例瞭解surf演算法如何提取特徵點。
int mainImage(void)
{
  //宣告Ipoints的向量 Declare Ipoints and other stuff
  IpVec ipts;
  
  IplImage *img=cvLoadImage("imgs/sf.jpg");
  
  //檢測與描述影象中的興趣點 Detect and describe interest points in the image
  clock_t start = clock();
  surfDetDes(img, ipts, false, 5, 4, 2, 0.0004f);//SURF描述子特徵提取實現函式 
  clock_t end = clock();
  
  std::cout<< "OpenSURF found: " << ipts.size() << " interest points" << std::endl;
  std::cout<< "OpenSURF took: " << float(end - start) / CLOCKS_PER_SEC  << " seconds" << std::endl;
  
  //繪製檢測到的點 Draw the detected points
  drawIpoints(img, ipts);
    
  //顯示檢測結果 Display the result
  showImage(img);
  
  return 0;
}

EXP:

IpVec的定義在ipoint.h裡,typedef std::vector<Ipoint> IpVec; 也就是說,IpVec是一個vector向量,每個成員是一個Ipoint。而Ipoint是一個類,也在ipoint.h裡,作者將它按照結構體使用,都是public。

clock()的使用是為了測試程式執行的時間,一個記錄起始時間,一個記錄結束時間,最終將兩者之差輸出,即surfDetDes()特徵提取所需要的時間。

drawIpoints()函式是在img基礎上增加特徵點的描述,說白了,就是新增特徵點的函式。

 

那麼,現在進入到surfDetDes()函式內部來探個究竟吧。

//URF描述子特徵提取實現函式

surfDetDes定義在surflib.h裡面:

//!建立興趣點描述特徵向量的庫函式 Library function builds vector of described interest points
inline void surfDetDes(IplImage *img,  /*檢測興趣點的影象 image to find Ipoints in */
                       std::vector<Ipoint> &ipts, /*興趣點向量的引用 reference to vector of Ipoints */
                       bool upright = false, /*是否是旋轉不變模式 run in rotation invariant mode? */
                       int octaves = OCTAVES, /*高斯金字塔的組數 number of octaves to calculate */
                       int intervals = INTERVALS, /*高斯金字塔每組的層數 number of intervals per octave */
                       int init_sample = INIT_SAMPLE, /*初始抽樣步驟 initial sampling step */
                       float thres = THRES /*斑點反應閾值 blob response threshold */)
{
  //建立原影象的積分影象 
  IplImage *int_img = Integral(img);
    
  //建立快速海森矩陣 Create Fast Hessian Object
  FastHessian fh(int_img, ipts, octaves, intervals, init_sample, thres);
   
  //提取興趣點並儲存在向量中 Extract interest points and store in vector ipts
  fh.getIpoints();
    
  //建立Surf描述子物件 Create Surf Descriptor Object
  Surf des(int_img, ipts);
  
  //提取ipts的描述子 Extract the descriptors for the ipts
  des.getDescriptors(upright);
  
  //釋放積分影象 Deallocate the integral image
  cvReleaseImage(&int_img);
}








相關文章