特徵檢測(一):OpenCV中的Harris角點檢測技術

本文總結了OpenCV中Harris角點檢測技術,其餘關於Harris角點檢測原理性知識點,將在後續學習過程當中進行補充!html

目標:python

  • 咱們將瞭解Harris Corner Detection背後的概念。
  • 咱們將看到函數:cv2.cornerHarris()cv2.cornerSubPix()

理論:app

    在上一章中,咱們看到角落是圖像中各個方向強度變化很大的區域。早在一九八八年,Chris Harris&Mike Stephens就在其論文A Combined Corner and Edge Detector中發現了這些角落的一個早期嘗試,如今它被稱爲Harris Corner Detector。他把這個簡單的想法變成了一種數學形式。它基本上找到了(U,V)全部方向上位移的強度差別。這表示以下:函數

E(u,v)= \ sum_ {x,y} \ underbrace {w(x,y)} _ \ text {window function} \,[\ underbrace {I(x + u,y + v)} _ \ text {shifted intensity}  -  \ underbrace {I(x,y)} _ \ text {intensity}] ^ 2

窗口函數是一個矩形窗口或高斯窗口,它給下面的像素加權。學習

咱們必須最大化這個E(U,V)角落檢測功能。這意味着,咱們必須最大限度地利用第二個任期。將泰勒展開應用於上述方程式並使用一些數學步驟(請參閱您喜歡的任何標準教科書以得到完整推導),咱們獲得最終方程式爲:優化

E(u,v)\ approx \ begin {bmatrix} u&v \ end {bmatrix} M \ begin {bmatrix} u \ v \ end {bmatrix}

哪裏ui

M = \ sum_ {x,y} w(x,y)\ begin {bmatrix} I_x I_x&I_x I_y \\ I_x I_y&I_y I_y \ end {bmatrix}

這裏,I_XI_Y在x圖像衍生物和y方向分別。(能夠很容易地找到使用cv2.Sobel())。spa

而後是主要部分。以後,他們建立了一個分數,基本上是一個方程,它將肯定一個窗口是否能夠包含角落。htm

R = det(M)-k(trace(M))^ 2

哪裏圖片

  • det(M)= \ lambda_1 \ lambda_2
  • trace(M)= \ lambda_1 + \ lambda_2
  • \ lambda_1而且\ lambda_2是M的特徵值

因此這些特徵值的值決定了一個區域是角落,邊緣仍是平面。

  • | R |小,這發生在\ lambda_1\ lambda_2小,該區域是平坦的。
  • 什麼時候[R <0發生,\ lambda_1 >> \ lambda_2反之亦然,該地區是邊緣。
  • [R大,當其發生\ lambda_1\ lambda_2大和\ lambda_1 \ sim \ lambda_2,該地區是一個角落。

它能夠表示在一個不錯的圖片以下:

圖像點的分類

因此哈里斯角落檢測的結果是一個灰度圖像與這些分數。爲合適的閾值給出圖像中的角落。咱們會用一個簡單的圖像來作到這一點。

Harris角點探測器在OpenCV中

爲此, 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()

哈里斯角落檢測

具備SubPixel準確性的角落

    有時候,您可能須要以最高精度找到角點。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)

結果:

Corner Detection with SubPixel Accuracy

 

參考:

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

轉載請註明出處!!!

相關文章
相關標籤/搜索