1、角點介紹
角點檢測(Corner Detection)是計算機視覺系統中用來獲得圖像特征的一種方法,廣泛應用於運動檢測、圖像匹配、視頻跟蹤、三維建模和目標識別等領域中,也稱為特征點檢測。在圖像中角點是一個重要的局部特征,它決定了圖像中關鍵區域的形狀,體現了圖像中重要的特征信息。目前,角點檢測方法主要有2大類:
1)基於圖像邊緣輪廓特征的方法。
2)基於圖像灰度信息的方法。此方法主要通過計算曲率及梯度進行角點檢測,通過計算邊緣的曲率來判斷角點的存在性。典型代表有Harris算法、Susan算法、Moravec算法等。
角點通常被定義為兩條邊的交點,更嚴格的說,角點的局部鄰域應該具有兩個不同區域的不同方向的邊界。而實際應用中,大多數所謂的角點檢測方法檢測的是擁有特定特征的圖像點,而不僅僅是“角點”。這些特征點在圖像中有具體的坐標,並具有某些數學特征,如局部最大或最小灰度、某些梯度特征等。現有的角點檢測算法並不是都十分的健壯。很多方法都要求有大量的訓練集和冗余數據來防止或減少錯誤特征的出現。另外,角點檢測方法的一個很重要的評價標准是其對多幅圖像中相同或相似特征的檢測能力,並且能夠應對光照變化、圖像旋轉等圖像變化。
2、Harris算法介紹
Harris 是 Harris 和 Stephens 在 1988 年提出,專門針對 Moravec 算子的改進版。Harris 算子,又稱 Plessey算子,它基於與 Moravec 相同的角點定義,即定義在各個方向上灰度值變化的點。
角點可以如下圖形象的定義,如果在各個方向上移動這個小窗口,窗口內的灰度發生了較大的變化,那么說明窗口內存在角點;如果在各個方向移動,灰度幾乎不變,說明是平坦區域;如果只沿着某一個方向移動,灰度幾乎不變,說明是直線(邊緣)。
設圖像窗口平移[u,v] ,產生的灰度變化為E[u,v] ,則:
上式中,窗口函數是一個矩形窗口或高斯窗口,它給在其中的像素加權。
我們必須使邊角檢測的函數最大化,這意味着,我們必須最大限度地利用第二個參數。
根據角點的定義,平坦區域,像素變化小,那么上式后半部分基本接近為0;在邊緣區域,會在沿着邊緣方向上差值為一個穩定值;只有在角點處,無論向那個方向移動,都會發生變化。
根據泰勒級數展開:
那么f(x+u, y+v)可以簡化為:
f(x+u, y+v) ≈ f(x,y) + ufx(x,y) + vfy(x,y)
Harris算式的可以寫成矩陣模式。
Harris算式可以近似得到下面的表達:
其中M為:
其中,表示 Ix 方向的梯度,表示Iy 方向的梯度,為高斯函數。矩陣的特征值是自相關函數的一階曲率。特征值的大小與特征點的性質息息相關。即當兩個特征值都比較小時,則此點可能位於平坦區,不為角點或邊界點; 當兩個特征值一個較大、而另一個卻相對較小時,則此點位於邊界上,屬於邊界點; 當兩個特征值均相對較大時,則此點沿任意方向的曲率都較大,為需要提取的角點。
M為梯度的協方差矩陣,在實際應用中為了能夠應用更好的編程,定義了角點響應函數R,通過判定R大小來判斷像素是否為角點。R取決於M的特征值,對於角點|R|很大,平坦的區域|R|很小,邊緣的R為負值。Harris角點檢測算法就是對角點響應函數R進行閾值處理:R > threshold,即提取R的局部極大值。
其中,det(M) = λ1* λ1, trace(M) =λ1+ λ1 。k是經驗參數,一般取值為0.04~0.06。
當R為大數值正數的時候,表示為角點。如下圖所示:
3、Harris實驗
OpenCV函數原型:
C++:void cornerHarris( InputArray src, //輸入8bit單通道灰度Mat矩陣 OutputArray dst, //保存角點檢測結果,32位單通道,大小與src相同 int blockSize, //滑塊窗口的尺寸、鄰域的大小 int ksize, //Sobel邊緣檢測濾波器大小 double k, //Harris中間參數,經驗值0.04~0.06 int borderType=BORDER_DEFAULT //插值類型 );
測試實例:
int threshod_val = 30; int max_threshod_val = 150; Mat src_img; void call_back(int, void*) { Mat normImage, scaledImage; Mat Img_scr1 = src_img.clone(); Mat Img_dst = Mat::zeros(src_img.size(), CV_32FC1); cornerHarris(src_img, Img_dst, 2, 3, 0.04, BORDER_DEFAULT); //進行角點檢測 normalize(Img_dst, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat()); // 歸一化 convertScaleAbs(normImage, scaledImage);//將歸一化后的圖線性變換成8位無符號整型 for (int i = 0; i < normImage.rows; i++) { for (int j = 0; j < normImage.cols; j++) { if ((int)normImage.at<float>(i, j) > threshod_val + 100) { circle(Img_scr1, Point(j, i), 3, Scalar(0, 0, 255), 2, 8, 0); circle(scaledImage, Point(j, i), 3, Scalar(0, 0, 255), 2, 8, 0); } } } imshow("corner", Img_scr1); imshow("scaledImage", scaledImage); } int main() { src_img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\checkerboard.png"); imshow("原圖", src_img); cvtColor(src_img, src_img, COLOR_BGR2GRAY); namedWindow("corner"); createTrackbar("thresh", "corner", &threshod_val, max_threshod_val, call_back); call_back(threshod_val, 0); waitKey(0); }
輸出結果如下圖:
測試2:
4、參考文獻
1、A COMBINED CORNER AND EDGE DETECTOR,Chris Harris,Mike Stephens,1988
http://www.bmva.org/bmvc/1988/avc-88-023.pdf
2、Harris Corner Detection
3、Harris 角點檢測子
4、【OpenCV入門教程之十六】OpenCV角點檢測之Harris角點檢測
https://blog.csdn.net/poem_qianmo/article/details/29356187
5、(四)OpenCV中的特征檢測之Harris Corner檢測
https://blog.csdn.net/u014403318/article/details/80562785
6、OpenCV學習筆記(八)——Harris角度特征從原理到實現詳解
https://blog.csdn.net/weixin_41695564/article/details/79962401
7、《OpenCV3 編程入門》,電子工業出版社,毛星雨著
8、《學習OpenCV》,清華大學出版社,Gary Bradski, Adrian kaehler著
技術博客,轉載請注明。