python-opencv图像处理之哈里斯角检测
- 理解什么是特征,為什么拐角重要等等
- 我們將了解"Harris Corner Detection”背后的概念。
- 我們將看到以下函數:cv.cornerHarris(),cv.cornerSubPix()
1.我們不妨先看一下下面這張圖片:
圖像非常簡單。在圖像的頂部,給出了六個小圖像塊。你的問題是在原始圖像中找到這些補丁的確切位置。你可以找到多少正確的結果?
A和B是平坦的表面,它們散布在很多區域上。很難找到這些補丁的確切位置。
C和D更簡單。它們是建筑物的邊緣。你可以找到一個大概的位置,但是準確的位置仍然很困難。這是因為沿著邊緣的每個地方的圖案都是相同的。但是,在邊緣,情況有所不同。因此,與平坦區域相比,邊緣是更好的特征,但不夠好(在拼圖游戲中比較邊緣的連續性很好)。
最后,E和F是建筑物的某些角落。而且很容易找到它們。因為在拐角處,無論將此修補程序移動到何處,它的外觀都將有所不同。因此,它們可以被視為很好的特征。
我們在圖像中找到了特征。找到它之后,你應該能夠在其他圖像中找到相同的圖像。怎么做?我們圍繞該特征采取一個區域,我們用自己的語言解釋它,例如“上部是藍天,下部是建筑物的區域,在建筑物上有玻璃等”,而你在另一個建筑物中搜索相同的區域圖片。基本上,你是在描述特征。同樣,計算機還應該描述特征周圍的區域,以便可以在其他圖像中找到它。所謂的描述稱為特征描述。獲得特征及其描述后,你可以在所有圖像中找到相同的功能并將它們對齊,縫合在一起或進行所需的操作。
2.我們看到角是圖像中各個方向上強度變化很大的區域。Chris Harris和Mike Stephens在1988年的論文《組合式拐角和邊緣檢測器》中做了一次嘗試找到這些拐角的嘗試,所以現在將其稱為哈里斯拐角檢測器。他把這個簡單的想法變成了數學形式。它基本上找到了(u,v)(u,v)(u,v)在所有方向上位移的強度差異。表示如下:
E(u,v)=∑x,yw(x,y)?window?function[I(x+u,y+v)?shifted?intensity?I(x,y)?intensity]2E(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}]^2E(u,v)=x,y∑?w(x,y)?window?function[I(x+u,y+v)?shifted?intensity?intensityI(x,y)??]2
窗口函數要么是一個矩形窗口,要么是高斯窗口,它在下面賦予了值。
我們必須最大化這個函數E(u,v)E(u,v)E(u,v)用于角檢測。這意味著,我們必須最大化第二個項。將泰勒擴展應用于上述方程,并使用一些數學步驟(請參考任何你喜歡的標準文本書),我們得到最后的等式:
E(u,v)≈[uv]M[uv]E(u,v) \approx \begin{bmatrix} u & v \end{bmatrix} M \begin{bmatrix} u \ v \end{bmatrix}E(u,v)≈[u?v?]M[u?v?]
其中
M=∑x,yw(x,y)[IxIxIxIyIxIyIyIy]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}M=x,y∑?w(x,y)[Ix?Ix??Ix?Iy??Ix?Iy??Iy?Iy??]
在此,IxI_xIx?和IyI_yIy?分別是在x和y方向上的圖像導數。(可以使用cv.Sobel()輕松找到)。
然后是主要部分。之后,他們創建了一個分數,基本上是一個等式,它將確定一個窗口是否可以包含一個角。
R=det(M)?k(trace(M))2R = det(M) - k(trace(M))^2R=det(M)?k(trace(M))2
其中
det(M)=λ1λ2det(M)=\lambda_1\lambda_2det(M)=λ1?λ2?
trace(M)=λ1+λ2trace(M)=\lambda_1+\lambda_2trace(M)=λ1?+λ2?
λ1\lambda_1λ1? and λ2\lambda_2λ2? 是 MMM 的特征值
因此,這些特征值的值決定了區域是拐角,邊緣還是平坦。
當∣R∣|R|∣R∣較小,這在λ1\lambda_1λ1?和λ2\lambda_2λ2?較小時發生,該區域平坦。
當R<0R<0R<0時(當λ1>>λ2\lambda_1 >>\lambda_2λ1?>>λ2?時發生,反之亦然),該區域為邊。
當RRR很大時,這發生在λ1\lambda_1λ1?和λ2\lambda_2λ2?大且λ1\lambda_1λ1?~λ2\lambda_2λ2?時,該區域是角。
可以用如下圖來表示:
因此,Harris Corner Detection的結果是具有這些分數的灰度圖像。合適的閾值可為您提供圖像的各個角落。我們將以一個簡單的圖像來完成它。
OpenCV中的哈里斯角檢測
為此,OpenCV具有函數cv.cornerHarris()。其參數為: - img - 輸入圖像,應為灰度和float32類型。 - blockSize - 是拐角檢測考慮的鄰域大小 - ksize - 使用的Sobel導數的光圈參數。 - k - 等式中的哈里斯檢測器自由參數。
請參閱以下示例:
`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用于標記角點,并不重要 dst = cv.dilate(dst,None) #最佳值的閾值,它可能因圖像而異。 img[dst>0.01*dst.max()]=[0,0,255] cv.imshow('dst',img) if cv.waitKey(0) & 0xff == 27:cv.destroyAllWindows()`總結
以上是生活随笔為你收集整理的python-opencv图像处理之哈里斯角检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】matlab 生成调用c/c++
- 下一篇: 【转】C++读写.mat文件的方法