本文總結了OpenCV中Harris角點檢測技術,其餘關於Harris角點檢測原理性知識點,將在後續學習過程當中進行補充!html
目標:python
理論:app
在上一章中,咱們看到角落是圖像中各個方向強度變化很大的區域。早在一九八八年,Chris Harris&Mike Stephens就在其論文A Combined Corner and Edge Detector中發現了這些角落的一個早期嘗試,如今它被稱爲Harris Corner Detector。他把這個簡單的想法變成了一種數學形式。它基本上找到了全部方向上位移的強度差別。這表示以下:函數
窗口函數是一個矩形窗口或高斯窗口,它給下面的像素加權。學習
咱們必須最大化這個角落檢測功能。這意味着,咱們必須最大限度地利用第二個任期。將泰勒展開應用於上述方程式並使用一些數學步驟(請參閱您喜歡的任何標準教科書以得到完整推導),咱們獲得最終方程式爲:優化
哪裏ui
這裏,和在x圖像衍生物和y方向分別。(能夠很容易地找到使用cv2.Sobel())。spa
而後是主要部分。以後,他們建立了一個分數,基本上是一個方程,它將肯定一個窗口是否能夠包含角落。htm
哪裏圖片
因此這些特徵值的值決定了一個區域是角落,邊緣仍是平面。
- 當小,這發生在與小,該區域是平坦的。
- 什麼時候發生,反之亦然,該地區是邊緣。
- 當大,當其發生和大和,該地區是一個角落。
它能夠表示在一個不錯的圖片以下:
因此哈里斯角落檢測的結果是一個灰度圖像與這些分數。爲合適的閾值給出圖像中的角落。咱們會用一個簡單的圖像來作到這一點。
爲此, OpenCV具備函數cv2.cornerHarris()。它的論據是:
- img - 輸入圖像,應該是灰度和float32類型。
- 塊大小 - 這是考慮角落檢測的鄰域大小
- ksize - 使用Sobel衍生物的孔徑參數。
- 方程中的k - 哈里斯檢測器自由參數。
import cv2 import numpy as np filename = 'chessboard.jpg' img = cv2.imread(filename) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) #result is dilated for marking the corners, not important dst = cv2.dilate(dst,None) # Threshold for an optimal value, it may vary depending on the image. img[dst>0.01*dst.max()]=[0,0,255] cv2.imshow('dst',img) if cv2.waitKey(0) & 0xff == 27: cv2.destroyAllWindows()
有時候,您可能須要以最高精度找到角點。OpenCV帶有一個函數cv2.cornerSubPix(),它進一步細化了以亞像素精度檢測到的角點。下面是一個例子。像往常同樣,咱們須要先找到哈里斯的角落。而後咱們經過這些角的質心(可能有一些像素位於角落,咱們取其質心)來優化它們。哈里斯的角落標記爲紅色像素,精緻的角落標記爲綠色像素。對於這個函數,咱們必須定義什麼時候中止迭代的標準。咱們中止指定次數的迭代或達到必定的準確度,以先發生者爲準。咱們還須要定義要搜索拐角的鄰域的大小。
import cv2 import numpy as np filename = 'chessboard2.jpg' img = cv2.imread(filename) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # find Harris corners gray = np.float32(gray) dst = cv2.cornerHarris(gray,2,3,0.04) dst = cv2.dilate(dst,None) ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0) dst = np.uint8(dst) # find centroids ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst) # define the criteria to stop and refine the corners criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001) corners = cv2.cornerSubPix(gray,np.float32(centroids),(5,5),(-1,-1),criteria) # Now draw them res = np.hstack((centroids,corners)) res = np.int0(res) img[res[:,1],res[:,0]]=[0,0,255] img[res[:,3],res[:,2]] = [0,255,0] cv2.imwrite('subpixel5.png',img)
結果:
參考:
http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_feature2d/py_features_harris/py_features_harris.html
轉載請註明出處!!!