OpenCV 圖像特徵提取
Harris 角點檢測
1、什麼是角點
同角點並列的還有邊界點、平面點。看下面的圖可以看出來三者之間的位置關係。
從上面的圖片我們可以看出來:
簡化一點就是下面三種情況:
2、如何區分角點、邊界和平面
我們使用肉眼觀察很方便,但是輸入到計算機裏面就需要相應的算法進行識別。
-
平面: 之所以叫平面,是因爲在圖像窗口任意移動過程中,像素值不會發生明顯的變化,趨於平滑。
-
邊界: 當圖像窗口在邊界範圍移動時,像素值會沿一個方向基本不變,在垂直的方向發生巨大變化。可以看中間的圖片,當沿 y 軸運動時,像素值不會發生大的變化。當沿 x 軸移動時會發生像素值會發生巨大變化。
-
角點: 不同於平面和邊界,圖像窗口處於角點位置時,沿任意方向都會發生巨大變化。
利用上面的規則我們就可以區分角點、邊界和平面。
3、角點公式推導
我們在實際中主要是觀察移動前後像素值的變化情況。
1、 當圖像在 (x,y) 處平移 (Δx,Δy) 後的自相似性:
c(x,y;Δx,Δy)=u,v∈W(x,y)∑w(u,v)(I(u,v)−I(u+Δx,v+Δy))2
其中 w(x,y) 是以點 (x,y) 爲中心的窗口,這裏既可以取常數,或者是高斯加權的函數(推薦)。
2、 對上面的部分式子進行化簡,泰勒展開:
I(u+Δx,v+Δy)=I(u,v)+Ix(u,v)Δx+Iy(u,v)Δy+O(Δx2,Δy2)≈I(u,v)+Ix(u,v)Δx+Iy(u,v)Δy
其中 Ix,Iy 分別是 x,y 的偏導數。
3、 進一步化簡關於 c 的方程,近似可得:
c(x,y;Δx,Δy)≈w∑(Ix(u,v)Δx+Iy(u,v)Δy)2=[Δx,Δy]M(x,y)[ΔxΔy]
我們發現上賣弄的式子是一個平方項,我們可以使用二次型對結果進行化簡,提取二次型矩陣。
4、二次型矩陣
M(x,y)=w∑[Ix(x,y)2Ix(x,y)Iy(x,y)Ix(x,y)Iy(x,y)Iy(x,y)2]=[∑wIx(x,y)2∑wIx(x,y)Iy(x,y)∑wIx(x,y)Iy(x,y)∑wIy(x,y)2]=[ABBC]
化簡可得:
c(x,y;Δx,Δy)≈AΔx2+2CΔxΔy+BΔy2
⎩⎪⎨⎪⎧A=Ix2B=IxIyC=Iy2
5、 形狀估計
我們可以看得出來二次項函數是一個橢圓函數,類似於:a2x2+b2y2=c,只不過是一個不過圓心的橢圓函數。
而且橢圓的大小隨着Δx,Δy的變化而變化。類似於一個錐體。
我們最後希望檢測角點,我們上面提到,它的變化越大,說明是角點的可能性越大。也就是說在單位Δx,Δy變化中,角點所在位置一般就是$A, B, C $較大值的點。實際中我們並不好利用三個值來進行判斷是否是邊界,平面還是角點。所以我們根據性質來減少自變量。
6、 減少自變量
根據我們之前學的高數,裏面有一個定理:
實對稱矩陣一定可以對角化
我們的 M 矩陣是一個實對稱矩陣( MT=M ),那麼它一定可以對角化,並且一定存在一組特徵值( λ1,λ2 ),那麼就將矩陣對角化。這樣自變量由三個變成了兩個,我們就方便來區分三者。
從上圖我們可以分析出來:
- 平面:λ1,λ2均小,也就說梯度不怎麼變化
- 邊界:λ1≫λ2,λ1≪λ2,也就是說梯度只沿一個方向變化快,垂直方向變化慢。
- 角點:λ1,λ2 均大,也就是沿任意方向變化均快。
7、 角點響應值
上面我們只是分析了依靠λ1,λ2來區分三者,那麼需要更加準確的表達式來進行判別。
R=detM−α(traceM)2
其中detM=λ1λ2:行列式的值traceM=λ1+λ2:跡
4、OpenCV相關函數
cv2.cornerHarris(img, blockSize, ksize, k)
- img:輸入圖像。類型爲float32
- blockSize:角點檢測中指定的區域大小
- ksize:Soble求導中使用窗口的大小
- k:取值爲[0.04-0.06]
5、角點檢測程序實現
程序實現:
def cv_show(src):
cv2.imshow('',src)
cv2.waitKey(0)
cv2.destroyAllWindows()
img_copy = img.copy()
img = cv2.imread('Pic/check.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
img[dst>0.0005*dst.max()]=[0,0,255]
res = np.hstack((img_copy, img))
cv_show(res)
結果如下:
最後
更多精彩內容,大家可以轉到我的主頁:曲怪曲怪的主頁
或者關注我的微信公衆號:TeaUrn