harris角點響應函數:harris角點檢測原理

理論

在上一章中,我們看到角是圖像中各個方向上強度變化較大的區域。早在1988年,克里斯·哈里斯和邁克·斯蒂芬斯就在他們的論文《一種結合了角和邊緣的探測器》中試圖找到這些角,所以現在它被稱為“哈里斯角探測器”。他把這個簡單的想法轉化為數學模型。它基本上可以求出(u,v)在所有方向上的位移的強度差。這表示如下:

openCV-特徵點匹配算法介紹二:Harries角點檢測

窗口函數可以是矩形窗口,也可以是高斯窗口(它為下面的像素賦予權重)。

我們需要最大化這個函數E(u,v)來檢測拐角。這意味着,我們要使第二項最大化。將泰勒展開應用於上述方程,並使用一些數學步驟(如需完整推導,請參考您喜歡的任何標準課本),得到最終方程為:

openCV-特徵點匹配算法介紹二:Harries角點檢測

這裡的 Ix 和 Iy 分別是圖像在 x 和 y 上的導數。(可以很容易的通過函數 cv.Sobel()得到)。

接下來是主要部分。在這之後,他們創建了一個分數,基本上是一個方程,它將決定一個窗口是否可以包含一個角。

openCV-特徵點匹配算法介紹二:Harries角點檢測

其中:

  • det(M)=λ1λ2
  • trace(M)=λ1+λ2
  • λ1 和 λ2 是M的特徵值

因此,這些特徵值決定了該區域是角,邊沿還是平台區。

  • 當 |R| 較小時(當 λ1 和 λ2 都小時出現),則該區域就是平台區。
  • 當 R<0 時(一般當 λ1>>λ2 遠大於或相反時出現),則該區域是邊沿。
  • 當 R 較大時(一般 λ1 和 λ2 都較大且 λ1∼λ2趨近),則該區域是角。

可以用下圖 λ1 和 λ2 坐標圖來表示:

openCV-特徵點匹配算法介紹二:Harries角點檢測

因此,Harris角檢測的結果是一個帶評分的灰度圖像。適當的閾值設置會得到圖像中的角。我們將用一個簡單的圖像來做測試。

OpenCV的Harris角點檢測實現

OpenCV 有一個函數 cv.cornerHarris() 就是用於此目的,包括一下參數:

  • img – 輸入圖像,該圖像必須是float32 類型的灰度圖。
  • blockSize – 角點檢測的鄰近域大小
  • ksize – 用於Sobel導數的孔徑參數。
  • k – 方程中Harris 檢測自由參數。

舉例說明該函數的使用:

import numpy as np
import cv2 as cv
filename = 'chessboard.png'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
#result is dilated for marking the corners, not important
dst = cv.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]
cv.imshow('dst',img)
if cv.waitKey(0) & 0xff == 27:
 cv.destroyAllWindows()

以下就是檢測結果:

openCV-特徵點匹配算法介紹二:Harries角點檢測

亞像素精度的角點檢測

有時候,你可能需要找到最精確的角。OpenCV附帶一個函數cv.cornersubpix(),它進一步細化了以亞像素精度檢測到的角。下面是一個例子。像往常一樣,我們需要先找到哈里斯角。然後我們通過這些角的質心(可能在一個角上有一堆像素,我們取它們的質心)來細化它們。Harris角用紅色像素標記,精製角用綠色像素標記。對於這個函數,我們必須定義何時停止迭代的條件。我們在指定的迭代次數或達到一定的精度後停止它,無論先發生什麼。我們還需要定義搜索拐角的鄰域的大小。

import numpy as np
import cv2 as cv
filename = 'chessboard2.jpg'
img = cv.imread(filename)
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# find Harris corners
gray = np.float32(gray)
dst = cv.cornerHarris(gray,2,3,0.04)
dst = cv.dilate(dst,None)
ret, dst = cv.threshold(dst,0.01*dst.max(),255,0)
dst = np.uint8(dst)
# find centroids
ret, labels, stats, centroids = cv.connectedComponentsWithStats(dst)
# define the criteria to stop and refine the corners
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv.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]
cv.imwrite('subpixel5.png',img)

以下是結果,每個角經過縮放後顯示紅綠不同位置標識,該函數明顯提升了精度:

openCV-特徵點匹配算法介紹二:Harries角點檢測

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/220852.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-09 12:18
下一篇 2024-12-09 12:18

相關推薦

發表回復

登錄後才能評論