Python圖像銳化與邊緣檢測之Scharr,Canny,LOG算子詳解
一.Scharr算子
由于Sobel算子在計算相對較小的核的時候,其近似計算導(dǎo)數(shù)的精度比較低,比如一個3×3的Sobel算子,當(dāng)梯度角度接近水平或垂直方向時,其不精確性就越發(fā)明顯。Scharr算子同Sobel算子的速度一樣快,但是準(zhǔn)確率更高,尤其是計算較小核的情景,所以利用3×3濾波器實現(xiàn)圖像邊緣提取更推薦使用Scharr算子。
Scharr算子又稱為Scharr濾波器,也是計算x或y方向上的圖像差分,在OpenCV中主要是配合Sobel算子的運算而存在的,其濾波器的濾波系數(shù)如下:
Scharr算子的函數(shù)原型如下所示,和Sobel算子幾乎一致,只是沒有ksize參數(shù)。
dst = Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]])
- – src表示輸入圖像
- – dst表示輸出的邊緣圖,其大小和通道數(shù)與輸入圖像相同
- – ddepth表示目標(biāo)圖像所需的深度,針對不同的輸入圖像,輸出目標(biāo)圖像有不同的深度
- – dx表示x方向上的差分階數(shù),取值1或 0
- – dy表示y方向上的差分階數(shù),取值1或0
- – scale表示縮放導(dǎo)數(shù)的比例常數(shù),默認(rèn)情況下沒有伸縮系數(shù)
- – delta表示將結(jié)果存入目標(biāo)圖像之前,添加到結(jié)果中的可選增量值
- – borderType表示邊框模式,更多詳細(xì)信息查閱BorderTypes
Scharr算子的實現(xiàn)代碼如下所示。
# -*- coding: utf-8 -*- # By:Eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #讀取圖像 img = cv2.imread('luo.png') lenna_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #灰度化處理圖像 grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Scharr算子 x = cv2.Scharr(grayImage, cv2.CV_32F, 1, 0) #X方向 y = cv2.Scharr(grayImage, cv2.CV_32F, 0, 1) #Y方向 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) Scharr = cv2.addWeighted(absX, 0.5, absY, 0.5, 0) #用來正常顯示中文標(biāo)簽 plt.rcParams['font.sans-serif']=['SimHei'] #顯示圖形 titles = ['原始圖像', 'Scharr算子'] images = [lenna_img, Scharr] for i in range(2): plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
其運行結(jié)果如圖1所示:
二.Cann算子
John F.Canny于1986年發(fā)明了一個多級邊緣檢測算法——Canny邊緣檢測算子,并創(chuàng)立了邊緣檢測計算理論(Computational theory of edge detection),該理論有效地解釋了這項技術(shù)的工作理論。
邊緣檢測通常是在保留原有圖像屬性的情況下,對圖像數(shù)據(jù)規(guī)模進(jìn)行縮減,提取圖像邊緣輪廓的處理方式。Canny算法是一種被廣泛應(yīng)用于邊緣檢測的標(biāo)準(zhǔn)算法,其目標(biāo)是找到一個最優(yōu)的邊緣檢測解或找尋一幅圖像中灰度強(qiáng)度變化最強(qiáng)的位置。最優(yōu)邊緣檢測主要通過低錯誤率、高定位性和最小響應(yīng)三個標(biāo)準(zhǔn)進(jìn)行評價。Canny算子的實現(xiàn)步驟如下:
第一步,使用高斯平滑(如公式2所示)去除噪聲。
第二步,按照Sobel濾波器步驟計算梯度幅值和方向,尋找圖像的強(qiáng)度梯度。先將卷積模板分別作用x和y方向,再計算梯度幅值和方向,其公式如下所示。梯度方向一般取0度、45度、90度和135度四個方向。
第三步,通過非極大值抑制(Non-maximum Suppression)過濾掉非邊緣像素,將模糊的邊界變得清晰。該過程保留了每個像素點上梯度強(qiáng)度的極大值,過濾掉其他的值。對于每個像素點,它進(jìn)行如下操作:
- 將其梯度方向近似為以下值中的一個,包括0、45、90、135、180、225、270和315,即表示上下左右和45度方向;
- 比較該像素點和其梯度正負(fù)方向的像素點的梯度強(qiáng)度,如果該像素點梯度強(qiáng)度最大則保留,否則抑制(刪除,即置為0)。其處理后效果如圖2所示,左邊表示梯度值,右邊表示非極大值抑制處理后的邊緣。
第四步,利用雙閾值方法來確定潛在的邊界。經(jīng)過非極大抑制后圖像中仍然有很多噪聲點,此時需要通過雙閾值技術(shù)處理,即設(shè)定一個閾值上界和閾值下界。圖像中的像素點如果大于閾值上界則認(rèn)為必然是邊界(稱為強(qiáng)邊界,strong edge),小于閾值下界則認(rèn)為必然不是邊界,兩者之間的則認(rèn)為是候選項(稱為弱邊界,weak edge)。經(jīng)過雙閾值處理的圖像如圖3所示,左邊為非極大值抑制處理后的邊緣,右邊為雙閾值技術(shù)處理的效果圖。
第五步,利用滯后技術(shù)來跟蹤邊界。若某一像素位置和強(qiáng)邊界相連的弱邊界認(rèn)為是邊界,其他的弱邊界則被刪除。
在OpenCV中,Canny()函數(shù)原型如下所示:
edges = Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
- – image表示輸入圖像
- – edges表示輸出的邊緣圖,其大小和類型與輸入圖像相同
- – threshold1表示第一個滯后性閾值
- – threshold2表示第二個滯后性閾值
- – apertureSize表示應(yīng)用Sobel算子的孔徑大小,其默認(rèn)值為3
- – L2gradient表示一個計算圖像梯度幅值的標(biāo)識,默認(rèn)值為false
Canny算子的邊緣提取實現(xiàn)代碼如下所示:
# -*- coding: utf-8 -*- # By:Eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #讀取圖像 img = cv2.imread('luo.png') lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #灰度化處理圖像 grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #高斯濾波降噪 gaussian = cv2.GaussianBlur(grayImage, (3,3), 0) #Canny算子 Canny = cv2.Canny(gaussian, 50, 150) #用來正常顯示中文標(biāo)簽 plt.rcParams['font.sans-serif']=['SimHei'] #顯示圖形 titles = ['原始圖像', 'Canny算子'] images = [lenna_img, Canny] for i in range(2): plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
其運行結(jié)果如圖4所示:
三.LOG算子
LOG(Laplacian of Gaussian)邊緣檢測算子是David Courtnay Marr和Ellen Hildreth在1980年共同提出的,也稱為Marr & Hildreth算子,它根據(jù)圖像的信噪比來求檢測邊緣的最優(yōu)濾波器。該算法首先對圖像做高斯濾波,然后再求其拉普拉斯(Laplacian)二階導(dǎo)數(shù),根據(jù)二階導(dǎo)數(shù)的過零點來檢測圖像的邊界,即通過檢測濾波結(jié)果的零交叉(Zero crossings)來獲得圖像或物體的邊緣。
LOG算子綜合考慮了對噪聲的抑制和對邊緣的檢測兩個方面,并且把Gauss平滑濾波器和Laplacian銳化濾波器結(jié)合了起來,先平滑掉噪聲,再進(jìn)行邊緣檢測,所以效果會更好。 該算子與視覺生理中的數(shù)學(xué)模型相似,因此在圖像處理領(lǐng)域中得到了廣泛的應(yīng)用。它具有抗干擾能力強(qiáng),邊界定位精度高,邊緣連續(xù)性好,能有效提取對比度弱的邊界等特點。
常見的LOG算子是5×5模板,如下所示:
由于LOG算子到中心的距離與位置加權(quán)系數(shù)的關(guān)系曲線像墨西哥草帽的剖面,所以LOG算子也叫墨西哥草帽濾波器,如圖5所示。
LOG算子的邊緣提取實現(xiàn)代碼如下所示:
# -*- coding: utf-8 -*- # By:Eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #讀取圖像 img = cv2.imread('luo.png') lenna_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #灰度化處理圖像 grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #先通過高斯濾波降噪 gaussian = cv2.GaussianBlur(grayImage, (3,3), 0) #再通過拉普拉斯算子做邊緣檢測 dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize = 3) LOG = cv2.convertScaleAbs(dst) #用來正常顯示中文標(biāo)簽 plt.rcParams['font.sans-serif']=['SimHei'] #顯示圖形 titles = ['原始圖像', 'LOG算子'] images = [lenna_img, LOG] for i in range(2): plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
其運行結(jié)果如圖6所示:
四.總結(jié)
該系列文章主要通過Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子、Canny算子和LOG算子實現(xiàn)圖像銳化和邊緣檢測,有效地提取了圖像的輪廓,并進(jìn)行了詳細(xì)地實驗處理。
到此這篇關(guān)于Python圖像銳化與邊緣檢測之Scharr,Canny,LOG算子詳解的文章就介紹到這了,更多相關(guān)Python Scharr Canny LOG內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
TensorFlow 實戰(zhàn)之實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)的實例講解
下面小編就為大家分享一篇TensorFlow 實戰(zhàn)之實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02keras訓(xùn)練淺層卷積網(wǎng)絡(luò)并保存和加載模型實例
這篇文章主要介紹了keras訓(xùn)練淺層卷積網(wǎng)絡(luò)并保存和加載模型實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Python實現(xiàn)輕松合并doc為txt的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Python編程語言和wxPython模塊,打開指定文件夾中的DOC文檔,并將它們的內(nèi)容合并成一個便捷的TXT文檔,需要的可以參考下2024-03-03Python連接mssql數(shù)據(jù)庫編碼問題解決方法
這篇文章主要介紹了Python連接mssql數(shù)據(jù)庫編碼問題解決方法,本文方法同樣適用mysql、sqllite、mongodb等數(shù)據(jù)庫,需要的朋友可以參考下2015-01-01