天天看點

opencv+python 邊緣檢測的基本原理,及Sobel、LoG和Canny算子的程式實作

圖像邊緣檢測的原理:

圖象的邊緣是指圖象局部區域亮度變化顯著的部分,該區域的灰階剖面一般可以看作是一個階躍,既從一個灰階值在很小的緩沖區域内急劇變化到另一個灰階相差較大的灰階值。圖象的邊緣部分集中了圖象的大部分資訊,圖象邊緣的确定與提取對于整個圖象場景的識别與了解是非常重要的,同時也是圖象分割所依賴的重要特征,邊緣檢測主要是圖象的灰階變化的度量、檢測和定位。

opencv+python 邊緣檢測的基本原理,及Sobel、LoG和Canny算子的程式實作

邊緣檢測的基本原理: 邊緣檢測的本質是微分,如上圖所示,當相鄰兩個像素點的灰階值差異越大時,也就是其斜率越陡,也就是微分值越大,進而通過這個來判斷邊緣,實際中常用差分,x方向和y方向。

Sobel算子

opencv+python 邊緣檢測的基本原理,及Sobel、LoG和Canny算子的程式實作

原理:算子使用兩個3X3的矩陣(圖1)算子使用兩個3X3的矩陣(圖1)去和原始圖檔作卷積,分别得到橫向G(x)和縱向G(y)的梯度值,如果梯度值大于某一個門檻值,則認為該點為邊緣點。

LoG算子

opencv+python 邊緣檢測的基本原理,及Sobel、LoG和Canny算子的程式實作

原理:首先對圖像做高斯濾波,然後再求其拉普拉斯(Laplacian)二階導數。即圖像與 Laplacian of the Gaussian function 進行濾波運算。最後,通過檢測濾波結果的零交叉(Zero crossings)可以獲得圖像或物體的邊緣。因而,也被業界簡稱為Laplacian-of-Gaussian (LoG)算子。

Canny算子

算法步驟:

第一步:對原始圖像進行灰階化、對圖像進行高斯濾波

Canny算法通常處理的圖像為灰階圖,是以如果錄影機擷取的是彩色圖像,那首先就得進行灰階化。對一幅彩色圖進行灰階化,就是根據圖像各個通道的采樣值進行權重平均。圖像高斯濾波的實作可以用兩個一維高斯核分别兩次權重實作,也可以通過一個二維高斯核一次卷積實作。

第二步:用一階偏導的有限差分來計算梯度的幅值方向

關于圖像灰階值得梯度可使用一階有限差分來進行近似,這樣就可以得圖像在x和y方向上偏導數的兩個矩陣。

第三步:對梯度幅值進行非極大值抑制

圖像梯度幅值矩陣中的元素值越大,說明圖像中該點的梯度值越大,但這不不能說明該點就是邊緣(這僅僅是屬于圖像增強的過程)。

第四步:用雙門檻值算法檢測和連接配接邊緣

Canny算法中減少假邊緣數量的方法是采用雙門檻值法。選擇兩個門檻值(關于門檻值的選取方法在擴充中進行讨論),根據高門檻值得到一個邊緣圖像,這樣一個圖像含有很少的假邊緣,但是由于門檻值較高,産生的圖像邊緣可能不閉合,為解決這樣一個問題采用了另外一個低門檻值。在高門檻值圖像中把邊緣連結成輪廓,當到達輪廓的端點時,該算法會在斷點的8鄰域點中尋找滿足低門檻值的點,再根據此點收集新的邊緣,直到整個圖像邊緣閉合。

三種邊緣檢測的程式實作:

# -*- coding:utf-8 -*-
#本程式用于邊緣檢測
import cv2  #導入opencv子產品
import numpy as np

print("Hellow word!")     #列印“Hello word!”,驗證子產品導入成功

img = cv2.imread("lena.jpg")  #導入圖檔,圖檔放在程式所在目錄
cv2.namedWindow("imagshow", 2)   #建立一個視窗
cv2.imshow('imagshow', img)    #顯示原始圖檔

#高斯模糊
blurred = cv2.GaussianBlur(img, (3, 3), 0)
#轉換為灰階圖
out_img_GRAY=cv2.cvtColor(blurred,cv2.COLOR_BGR2GRAY)#将圖檔轉換為灰階圖
cv2.namedWindow("img_GRAY", 2)   #建立一個視窗
cv2.imshow('img_GRAY', out_img_GRAY)    #顯示原始圖檔


#使用Canny算子進行邊緣檢測
edge_output = cv2.Canny(out_img_GRAY, 10, 300)
cv2.namedWindow("Canny", 2)   #建立一個視窗
cv2.imshow('Canny', edge_output)    #顯示原始圖檔


#使用sobel算子進行邊緣檢測
sobel = cv2.Sobel(out_img_GRAY,-1,1,0,ksize=3)
cv2.namedWindow("sobel", 2)   #建立一個視窗
cv2.imshow('sobel', sobel)    #顯示原始圖檔


#使用laplacian算子進行邊緣檢測
laplacian = cv2.Laplacian(out_img_GRAY,-1)
cv2.namedWindow("laplacian", 2)   #建立一個視窗
cv2.imshow('laplacian', laplacian)    #顯示原始圖檔

cv2.waitKey()
           

實作效果如圖:

opencv+python 邊緣檢測的基本原理,及Sobel、LoG和Canny算子的程式實作

從左到右分别為:灰階圖、Canny算子、soble算子、laplacian算子

繼續閱讀