【OpenCV】角點檢測:Harris角點及Shi-Tomasi角點檢測

角點

特徵檢測與匹配是Computer Vision 應用總重要的一部分,這須要尋找圖像之間的特徵創建對應關係。點,也就是圖像中的特殊位置,是很經常使用的一類特徵,點的局部特徵也能夠叫作「關鍵特徵點」(keypoint feature),或「興趣點」(interest point),或「角點」(conrner)。html

關於角點的具體描述能夠有幾種:算法

  • 一階導數(即灰度的梯度)的局部最大所對應的像素點;
  • 兩條及兩條以上邊緣的交點;
  • 圖像中梯度值和梯度方向的變化速率都很高的點;
  • 角點處的一階導數最大,二階導數爲零,指示物體邊緣變化不連續的方向。

Harris角點檢測

當一個窗口在圖像上移動,在平滑區域如圖(a),窗口在各個方向上沒有變化。在邊緣上如圖(b),窗口在邊緣的方向上沒有變化。在角點處如圖(c),窗口在各個方向上具備變化。Harris角點檢測正是利用了這個直觀的物理現象,經過窗口在各個方向上的變化程度,決定是否爲角點。函數

將圖像窗口平移[u,v]產生灰度變化E(u,v)spa

由:, 獲得:.net

對於局部微小的移動量 [u,v],近似表達爲:3d

其中M是 2*2 矩陣,可由圖像的導數求得:rest

E(u,v)的橢圓形式以下圖:code

 

定義角點響應函數 R 爲:orm

Harris角點檢測算法就是對角點響應函數R進行閾值處理:R > threshold,即提取R的局部極大值。htm

【相關代碼】

OpenCV中定義了 cornerHarris 函數:

void cornerHarris( InputArray src, OutputArray dst, int blockSize,  
                                int ksize, double k,  
                                int borderType=BORDER_DEFAULT );  

能夠結合 convertScaleAbs 函數,經過閾值取角點:

void cornerHarris_demo( int, void* )  
{  
  Mat dst, dst_norm;  
  dst = Mat::zeros( src.size(), CV_32FC1 );  
  /// Detector parameters  
  int blockSize = 2;  
  int apertureSize = 3;  
  double k = 0.04;  
  /// Detecting corners  
  cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );  
  /// Normalizing  
  normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );  
  convertScaleAbs( dst_norm, dst_norm_scaled );   
  /// Drawing a circle around corners  
  for( int j = 0; j < dst_norm.rows ; j++ )  
     { for( int i = 0; i < dst_norm.cols; i++ )  
          {  
            if( (int) dst_norm.at<float>(j,i) > thresh )  
              {   
                circle( dst_norm_scaled, Point( i, j ), 5,  Scalar(0), 2, 8, 0 );   
                circle(src,Point( i, j ), 5,  Scalar(255,0,0), -1, 8, 0 );  
              }  
          }   
     }      
  /// Showing the result  
  imshow( corners_window, dst_norm_scaled );  
  imshow( source_window, src );    
}  

Shi-Tomasi 算法

Shi-Tomasi 算法是Harris 算法的改進。Harris 算法最原始的定義是將矩陣 M 的行列式值與 M 的跡相減,再將差值同預先給定的閾值進行比較。後來Shi 和Tomasi 提出改進的方法,若兩個特徵值中較小的一個大於最小閾值,則會獲得強角點。

如上面第二幅圖中,對自相關矩陣 M 進行特徵值分析,產生兩個特徵值和兩個特徵方向向量。由於較大的不肯定度取決於較小的特徵值,也就是,因此經過尋找最小特徵值的最大值來尋找好的特徵點也就解釋的通了。
Shi 和Tomasi 的方法比較充分,而且在不少狀況下能夠獲得比使用Harris 算法更好的結果。

【相關代碼】

因爲這種Shi-Tomasi算子與1994年在文章 Good Features to Track [1]中提出,OpenCV 實現的算法的函數名定義爲 goodFeaturesToTrack:

void goodFeaturesToTrack( InputArray image, OutputArray corners,  
                                     int maxCorners, double qualityLevel, double minDistance,  
                                     InputArray mask=noArray(), int blockSize=3,  
                                     bool useHarrisDetector=false, double k=0.04 );  

自定義使用函數(以方便createTrackbar的響應)以下:

void cornerShiTomasi_demo( int, void* )  
{  
  if( maxCorners < 1 ) { maxCorners = 1; }  
  /// Parameters for Shi-Tomasi algorithm  
  vector<Point2f> corners;  
  double qualityLevel = 0.01;  
  double minDistance = 10;  
  int blockSize = 3;  
  bool useHarrisDetector = false;  
  double k = 0.04;  
  /// Copy the source image  
  Mat cormat;  
  /// Apply corner detection :Determines strong corners on an image.  
  goodFeaturesToTrack( src_gray,   
               corners,  
               maxCorners,  
               qualityLevel,  
               minDistance,  
               Mat(),  
               blockSize,  
               useHarrisDetector,  
               k );  
  /// Draw corners detected  
  for( int i = 0; i < corners.size(); i++ ){   
      circle( dst_norm_scaled,  corners[i], 5,  Scalar(255), 2, 8, 0 );   
      circle( src, corners[i], 4, Scalar(0,255,0), 2, 8, 0 );   
  }  
  
  /// Show what you got  
  imshow( corners_window, dst_norm_scaled );  
  imshow( source_window, src );    
}  

實踐

在主函數中定義兩個進度條方便調整閾值:

namedWindow( source_window, CV_WINDOW_AUTOSIZE );  
createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );  
createTrackbar( "Max  corners:", source_window, &maxCorners, maxTrackbar, cornerShiTomasi_demo );    
  
namedWindow( corners_window, CV_WINDOW_AUTOSIZE );  
namedWindow( source_window, CV_WINDOW_AUTOSIZE );  
imshow( source_window, src );    
  
cornerHarris_demo( 0, 0 );  
cornerShiTomasi_demo( 0, 0 );  

這裏還須要說的是OpenCV 2.4.2中給的角點檢測跟蹤的示例代碼有些問題,是應爲SURF等再也不定義在 feature2d模塊中,而是legacy和nonfree,因此須要加入引用:

#include "opencv2/legacy/legacy.hpp"  
#include "opencv2/nonfree/nonfree.hpp"  

角點檢測結果:

藍色實心點爲Harris檢測結果,綠色空心圈爲goodFeaturetoTrack檢測結果。

M特徵值分解後每一個像素點相減的圖(也就是Harris閾值判斷的圖)以下:

黑色實心點爲Harris閾值檢測結果,白色空心圈爲閾值爲27時Shi-Tomasi檢測結果。

轉載請註明出處:http://blog.csdn.net/xiaowei_cqu/article/details/7805206
源碼及資料下載: http://download.csdn.net/detail/xiaowei_cqu/4466627

參考資料:

[1] Shi and C. Tomasi. Good Features to Track. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pages 593-600, June 1994.

[2] Richard Szeliski. Computer Vision: Algorithms and Applications. Springer, New York, 2010.

[3] 圖像特徵點提取PPT http://wenku.baidu.com/view/f61bc369561252d380eb6ef0.html 

相關文章
相關標籤/搜索