OpenCV3入門(十二)角點檢測

一、角點介紹

角點檢測(Corner Detection)是計算機視覺系統中用來得到圖像特徵的一種方法,普遍應用於運動檢測、圖像匹配、視頻跟蹤、三維建模和目標識別等領域中,也稱爲特徵點檢測。在圖像中角點是一個重要的局部特徵,它決定了圖像中關鍵區域的形狀,體現了圖像中重要的特徵信息。目前,角點檢測方法主要有2大類:html

    1)基於圖像邊緣輪廓特徵的方法。python

    2)基於圖像灰度信息的方法。此方法主要經過計算曲率及梯度進行角點檢測,經過計算邊緣的曲率來判斷角點的存在性。典型表明有Harris算法、Susan算法、Moravec算法等。算法

角點一般被定義爲兩條邊的交點,更嚴格的說,角點的局部鄰域應該具備兩個不一樣區域的不一樣方向的邊界。而實際應用中,大多數所謂的角點檢測方法檢測的是擁有特定特徵的圖像點,而不單單是「角點」。這些特徵點在圖像中有具體的座標,並具備某些數學特徵,如局部最大或最小灰度、某些梯度特徵等。現有的角點檢測算法並非都十分的健壯。不少方法都要求有大量的訓練集和冗餘數據來防止或減小錯誤特徵的出現。另外,角點檢測方法的一個很重要的評價標準是其對多幅圖像中相同或類似特徵的檢測能力,而且可以應對光照變化、圖像旋轉等圖像變化。編程

 二、Harris算法介紹

Harris 是 Harris 和 Stephens 在 1988 年提出,專門針對 Moravec 算子的改進版。Harris 算子,又稱 Plessey算子,它基於與 Moravec 相同的角點定義,即定義在各個方向上灰度值變化的點。mvc

角點能夠以下圖形象的定義,若是在各個方向上移動這個小窗口,窗口內的灰度發生了較大的變化,那麼說明窗口內存在角點;若是在各個方向移動,灰度幾乎不變,說明是平坦區域;若是隻沿着某一個方向移動,灰度幾乎不變,說明是直線(邊緣)。less

設圖像窗口平移[u,v] ,產生的灰度變化爲E[u,v] ,則:函數

 

上式中,窗口函數是一個矩形窗口或高斯窗口,它給在其中的像素加權。學習

咱們必須使邊角檢測的函數最大化,這意味着,咱們必須最大限度地利用第二個參數。測試

根據角點的定義,平坦區域,像素變化小,那麼上式後半部分基本接近爲0;在邊緣區域,會在沿着邊緣方向上差值爲一個穩定值;只有在角點處,不管向那個方向移動,都會發生變化。spa

根據泰勒級數展開:

那麼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爲大數值正數的時候,表示爲角點。以下圖所示:

三、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:

四、參考文獻

一、A COMBINED CORNER AND EDGE DETECTOR,Chris Harris,Mike Stephens,1988

http://www.bmva.org/bmvc/1988/avc-88-023.pdf

二、Harris Corner Detection

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html

三、Harris 角點檢測子

http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/features2d/trackingmotion/harris_detector/harris_detector.html

四、【OpenCV入門教程之十六】OpenCV角點檢測之Harris角點檢測

https://blog.csdn.net/poem_qianmo/article/details/29356187

五、(四)OpenCV中的特徵檢測之Harris Corner檢測

https://blog.csdn.net/u014403318/article/details/80562785

六、OpenCV學習筆記(八)——Harris角度特徵從原理到實現詳解

https://blog.csdn.net/weixin_41695564/article/details/79962401

七、《OpenCV3 編程入門》,電子工業出版社,毛星雨著

八、《學習OpenCV》,清華大學出版社,Gary Bradski, Adrian kaehler著

 

技術博客,轉載請註明。

http://www.javashuo.com/article/p-govtddin-u.html

原文出處:https://www.cnblogs.com/pingwen/p/12423976.html

相關文章
相關標籤/搜索