??????????OpenCV實戰(zhàn)系列總目錄
打印一個圖片可以做出一個函數(shù):
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
1、Canny邊緣檢測流程
Canny是一個科學(xué)家在1986年寫了一篇論文,所以用自己的名字來命名這個檢測算法,Canny邊緣檢測算法這里寫了5步流程,會用到之前《openCV實戰(zhàn)-系列教程》的內(nèi)容。?
- 使用高斯濾波器,以平滑圖像,濾除噪聲。
- 計算圖像中每個像素點的梯度強度和方向。
- 應(yīng)用非極大值(Non-Maximum Suppression)抑制,以消除邊緣檢測帶來的雜散響應(yīng)。
- 應(yīng)用雙閾值(Double-Threshold)檢測來確定真實的和潛在的邊緣。
- 通過抑制孤立的弱邊緣最終完成邊緣檢測。
濾波:Canny檢測算法使用的濾波器是高斯濾波器,通過濾波器可以對圖像進(jìn)行平滑處理。所以第一步需要過濾噪聲,當(dāng)進(jìn)行檢測的時候,肯定需要計算梯度,當(dāng)遇到噪音點也會發(fā)生梯度的變化,所以為了更好的做到邊緣檢測,第一步需要去噪。
梯度:之前我們計算梯度的時候,只需要計算大小就行了,但是現(xiàn)在需要計算一下方向,所以梯度計算包括強度和方向。
非極大值抑制:計算的梯度大小有不同,比如在一個3*3的卷積核中,有些梯度比較小,相對大的就會保留下來,小的梯度就不會保留,只留下最明顯的。 比如在人臉檢測中,需要把人臉部分打出一個框的標(biāo)識,計算的時候會計算出多個框,每個框都有一個概率值,最后只保留概率最大的那個框,而其他的框就會被抑制掉。
雙閾值:計算邊界的時候,會計算出多個候選值,在候選值中會再進(jìn)行計算,只保留最接近真實的那個候選值邊界。
完成邊緣檢測:將前面的結(jié)果都組合起來,完成邊緣檢測。
2、高斯濾波器
在前面的內(nèi)容中已經(jīng)講解過,中間點比較大,越邊緣的點越小,圖中的H對高斯濾波器的濾波核進(jìn)行歸一化處理,然后再將濾波核H框住的區(qū)域A對應(yīng)位置相乘再求和得到一個結(jié)果e。
3、梯度方向
Canny計算梯度使用的是Sobel算子(前面已經(jīng)講過這個內(nèi)容),?Sobel算子中需要分別計算水平和豎直兩個方向的Gx和Gy(Gx和Gy的計算如上圖),將這個結(jié)果融合到一起G計算方法如上圖
梯度方向就是θ值,通過Gx和Gy計算得到,計算方法如上圖。
4、非極大值抑制
4.1 方法A
如圖所示,C點是目標(biāo)像素點,需要判斷C是不是一個極大值點,然后紅色方框是它的周圍的8個像素,藍(lán)色線是C點的梯度方向,梯度方向和邊界方向應(yīng)該是垂直的關(guān)系。
如圖所示,g1、g2、g3、g4、c都是一個像素點,而Q、Z是梯度方向與方框的交點,Q和Z不是一個像素是一個亞像素,使用線性插值法計算這個亞像素。?
首先g1、g2、g3、g4的梯度(梯度幅值,上一節(jié)講到的梯度計算)都能夠計算出來, Q就是g1和g2之間的,用M(dtmp1)表示Q點梯度(梯度幅值),它的計算方法在上圖的公式已經(jīng)給出,w和(1-w)都是代表的是一個權(quán)重,是Q點到g1、g2點的距離比上g1到g2的距離。得到權(quán)重乘上g1和g2的梯度就得到了Q點的梯度。
通過比較C、Q、Z的梯度值,如果C比Q、Z都要大,則說明C點是一個極大值,就可以將C點保留下來。
4.2 方法B
由于方法A太復(fù)雜了,將它簡化成方法B,將一個像素周圍的8個像素分解成8個方向。在方法1中如果過了g1和g4就不需要做插值了。方法B就是判斷當(dāng)前的方向和這8個方向那個最近就是哪個方向。然后這個方向上除了目標(biāo)像素值之外還有兩個點,如圖所示假如分別是A、B、C,如果目標(biāo)點A比B、C的梯度都要小那么A點就是極大值點。
5、雙閾值檢測?
?
maxVal即max value,意思是如果算出來的梯度值比maxVal(假如是100)大,那就是邊界。
所以A點是邊界,如果紅色線下方還有一個D點,那么就舍棄這個點,這個點的梯度值比minVal小。
如果是在minval和maxval之間,就要分開討論了,比如C點和邊界點A連接在了一起,那么C點就可以判斷為一個邊界點,否則比如B點就不是了
6、邊緣檢測效果實現(xiàn)
這里的80和150就是minVal和maxVal
img=cv2.imread("lena.jpg",cv2.IMREAD_GRAYSCALE)
v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)
res = np.hstack((v1,v2))
cv_show(res,'res')
打印結(jié)果:
?所以minVal和maxVal的設(shè)定是比較重要的,第5節(jié)中如果對minval進(jìn)行調(diào)整,那么提到的D點就有可能判定為邊界點,因此會提取出更多的細(xì)節(jié)。
再導(dǎo)入一張圖片,將兩個參數(shù)設(shè)置的更大一些來對比:
img=cv2.imread("car.png",cv2.IMREAD_GRAYSCALE)
v1=cv2.Canny(img,120,250)
v2=cv2.Canny(img,50,100)
res = np.hstack((v1,v2))
cv_show(res,'res')
打印結(jié)果:文章來源:http://www.zghlxwxcb.cn/news/detail-678828.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-678828.html
到了這里,關(guān)于openCV實戰(zhàn)-系列教程5:邊緣檢測(Canny邊緣檢測/高斯濾波器/Sobel算子/非極大值抑制/線性插值法/梯度方向/雙閾值檢測 )、原理解析、源碼解讀 ?????OpenCV實戰(zhàn)系列總目錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!