Python圖像銳化與邊緣檢測(cè)之Scharr,Canny,LOG算子詳解
一.Scharr算子
由于Sobel算子在計(jì)算相對(duì)較小的核的時(shí)候,其近似計(jì)算導(dǎo)數(shù)的精度比較低,比如一個(gè)3×3的Sobel算子,當(dāng)梯度角度接近水平或垂直方向時(shí),其不精確性就越發(fā)明顯。Scharr算子同Sobel算子的速度一樣快,但是準(zhǔn)確率更高,尤其是計(jì)算較小核的情景,所以利用3×3濾波器實(shí)現(xiàn)圖像邊緣提取更推薦使用Scharr算子。
Scharr算子又稱為Scharr濾波器,也是計(jì)算x或y方向上的圖像差分,在OpenCV中主要是配合Sobel算子的運(yùn)算而存在的,其濾波器的濾波系數(shù)如下:

Scharr算子的函數(shù)原型如下所示,和Sobel算子幾乎一致,只是沒(méi)有ksize參數(shù)。
dst = Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]])
- – src表示輸入圖像
- – dst表示輸出的邊緣圖,其大小和通道數(shù)與輸入圖像相同
- – ddepth表示目標(biāo)圖像所需的深度,針對(duì)不同的輸入圖像,輸出目標(biāo)圖像有不同的深度
- – dx表示x方向上的差分階數(shù),取值1或 0
- – dy表示y方向上的差分階數(shù),取值1或0
- – scale表示縮放導(dǎo)數(shù)的比例常數(shù),默認(rèn)情況下沒(méi)有伸縮系數(shù)
- – delta表示將結(jié)果存入目標(biāo)圖像之前,添加到結(jié)果中的可選增量值
- – borderType表示邊框模式,更多詳細(xì)信息查閱BorderTypes
Scharr算子的實(shí)現(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)
#用來(lái)正常顯示中文標(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()
其運(yùn)行結(jié)果如圖1所示:

二.Cann算子
John F.Canny于1986年發(fā)明了一個(gè)多級(jí)邊緣檢測(cè)算法——Canny邊緣檢測(cè)算子,并創(chuàng)立了邊緣檢測(cè)計(jì)算理論(Computational theory of edge detection),該理論有效地解釋了這項(xiàng)技術(shù)的工作理論。
邊緣檢測(cè)通常是在保留原有圖像屬性的情況下,對(duì)圖像數(shù)據(jù)規(guī)模進(jìn)行縮減,提取圖像邊緣輪廓的處理方式。Canny算法是一種被廣泛應(yīng)用于邊緣檢測(cè)的標(biāo)準(zhǔn)算法,其目標(biāo)是找到一個(gè)最優(yōu)的邊緣檢測(cè)解或找尋一幅圖像中灰度強(qiáng)度變化最強(qiáng)的位置。最優(yōu)邊緣檢測(cè)主要通過(guò)低錯(cuò)誤率、高定位性和最小響應(yīng)三個(gè)標(biāo)準(zhǔn)進(jìn)行評(píng)價(jià)。Canny算子的實(shí)現(xiàn)步驟如下:
第一步,使用高斯平滑(如公式2所示)去除噪聲。

第二步,按照Sobel濾波器步驟計(jì)算梯度幅值和方向,尋找圖像的強(qiáng)度梯度。先將卷積模板分別作用x和y方向,再計(jì)算梯度幅值和方向,其公式如下所示。梯度方向一般取0度、45度、90度和135度四個(gè)方向。


第三步,通過(guò)非極大值抑制(Non-maximum Suppression)過(guò)濾掉非邊緣像素,將模糊的邊界變得清晰。該過(guò)程保留了每個(gè)像素點(diǎn)上梯度強(qiáng)度的極大值,過(guò)濾掉其他的值。對(duì)于每個(gè)像素點(diǎn),它進(jìn)行如下操作:
- 將其梯度方向近似為以下值中的一個(gè),包括0、45、90、135、180、225、270和315,即表示上下左右和45度方向;
- 比較該像素點(diǎn)和其梯度正負(fù)方向的像素點(diǎn)的梯度強(qiáng)度,如果該像素點(diǎn)梯度強(qiáng)度最大則保留,否則抑制(刪除,即置為0)。其處理后效果如圖2所示,左邊表示梯度值,右邊表示非極大值抑制處理后的邊緣。

第四步,利用雙閾值方法來(lái)確定潛在的邊界。經(jīng)過(guò)非極大抑制后圖像中仍然有很多噪聲點(diǎn),此時(shí)需要通過(guò)雙閾值技術(shù)處理,即設(shè)定一個(gè)閾值上界和閾值下界。圖像中的像素點(diǎn)如果大于閾值上界則認(rèn)為必然是邊界(稱為強(qiáng)邊界,strong edge),小于閾值下界則認(rèn)為必然不是邊界,兩者之間的則認(rèn)為是候選項(xiàng)(稱為弱邊界,weak edge)。經(jīng)過(guò)雙閾值處理的圖像如圖3所示,左邊為非極大值抑制處理后的邊緣,右邊為雙閾值技術(shù)處理的效果圖。

第五步,利用滯后技術(shù)來(lái)跟蹤邊界。若某一像素位置和強(qiáng)邊界相連的弱邊界認(rèn)為是邊界,其他的弱邊界則被刪除。
在OpenCV中,Canny()函數(shù)原型如下所示:
edges = Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
- – image表示輸入圖像
- – edges表示輸出的邊緣圖,其大小和類型與輸入圖像相同
- – threshold1表示第一個(gè)滯后性閾值
- – threshold2表示第二個(gè)滯后性閾值
- – apertureSize表示應(yīng)用Sobel算子的孔徑大小,其默認(rèn)值為3
- – L2gradient表示一個(gè)計(jì)算圖像梯度幅值的標(biāo)識(shí),默認(rèn)值為false
Canny算子的邊緣提取實(shí)現(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)
#用來(lái)正常顯示中文標(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()
其運(yùn)行結(jié)果如圖4所示:

三.LOG算子
LOG(Laplacian of Gaussian)邊緣檢測(cè)算子是David Courtnay Marr和Ellen Hildreth在1980年共同提出的,也稱為Marr & Hildreth算子,它根據(jù)圖像的信噪比來(lái)求檢測(cè)邊緣的最優(yōu)濾波器。該算法首先對(duì)圖像做高斯濾波,然后再求其拉普拉斯(Laplacian)二階導(dǎo)數(shù),根據(jù)二階導(dǎo)數(shù)的過(guò)零點(diǎn)來(lái)檢測(cè)圖像的邊界,即通過(guò)檢測(cè)濾波結(jié)果的零交叉(Zero crossings)來(lái)獲得圖像或物體的邊緣。
LOG算子綜合考慮了對(duì)噪聲的抑制和對(duì)邊緣的檢測(cè)兩個(gè)方面,并且把Gauss平滑濾波器和Laplacian銳化濾波器結(jié)合了起來(lái),先平滑掉噪聲,再進(jìn)行邊緣檢測(cè),所以效果會(huì)更好。 該算子與視覺(jué)生理中的數(shù)學(xué)模型相似,因此在圖像處理領(lǐng)域中得到了廣泛的應(yīng)用。它具有抗干擾能力強(qiáng),邊界定位精度高,邊緣連續(xù)性好,能有效提取對(duì)比度弱的邊界等特點(diǎn)。
常見(jiàn)的LOG算子是5×5模板,如下所示:

由于LOG算子到中心的距離與位置加權(quán)系數(shù)的關(guān)系曲線像墨西哥草帽的剖面,所以LOG算子也叫墨西哥草帽濾波器,如圖5所示。

LOG算子的邊緣提取實(shí)現(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)
#先通過(guò)高斯濾波降噪
gaussian = cv2.GaussianBlur(grayImage, (3,3), 0)
#再通過(guò)拉普拉斯算子做邊緣檢測(cè)
dst = cv2.Laplacian(gaussian, cv2.CV_16S, ksize = 3)
LOG = cv2.convertScaleAbs(dst)
#用來(lái)正常顯示中文標(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()
其運(yùn)行結(jié)果如圖6所示:

四.總結(jié)
該系列文章主要通過(guò)Roberts算子、Prewitt算子、Sobel算子、Laplacian算子、Scharr算子、Canny算子和LOG算子實(shí)現(xiàn)圖像銳化和邊緣檢測(cè),有效地提取了圖像的輪廓,并進(jìn)行了詳細(xì)地實(shí)驗(yàn)處理。
到此這篇關(guān)于Python圖像銳化與邊緣檢測(cè)之Scharr,Canny,LOG算子詳解的文章就介紹到這了,更多相關(guān)Python Scharr Canny LOG內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python+Selenium實(shí)現(xiàn)網(wǎng)站滑塊拖動(dòng)操作
這篇文章主要為大家詳細(xì)介紹了如何利用Python+Selenium模擬實(shí)現(xiàn)登錄某網(wǎng)站的滑塊拖動(dòng)操作,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-09-09
python進(jìn)階_淺談面向?qū)ο筮M(jìn)階
下面小編就為大家?guī)?lái)一篇python進(jìn)階_淺談面向?qū)ο筮M(jìn)階。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
python中Requests請(qǐng)求的安裝與常見(jiàn)用法
Requests是一常用的http請(qǐng)求庫(kù),它使用python語(yǔ)言編寫,可以方便地發(fā)送http請(qǐng)求,以及方便地處理響應(yīng)結(jié)果,下面這篇文章主要給大家介紹了關(guān)于python中Requests請(qǐng)求的安裝與常見(jiàn)用法的相關(guān)資料,需要的朋友可以參考下2022-07-07
Python UI自動(dòng)化測(cè)試Web frame及多窗口切換
這篇文章主要為大家介紹了Python UI自動(dòng)化測(cè)試Web frame及多窗口切換,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
Python?OpenCV實(shí)現(xiàn)圖形檢測(cè)示例詳解
圖形檢測(cè)在計(jì)算機(jī)視覺(jué)開(kāi)發(fā)中是一項(xiàng)非常重要的操作,算法通過(guò)對(duì)圖像的檢測(cè),分析出圖像中可能存在哪些形狀。本文詳細(xì)介紹了Python+OpenCV如何實(shí)現(xiàn)圖形檢測(cè),感興趣的可以了解一下2022-04-04
python中24小時(shí)制轉(zhuǎn)換為12小時(shí)制的方法
最近需要實(shí)現(xiàn)一個(gè)需求,求用戶輸入24小時(shí)制的時(shí)間,然后顯示12小時(shí)制的時(shí)間。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
python對(duì)Excel按條件進(jìn)行內(nèi)容補(bǔ)充(推薦)
這篇文章主要介紹了python對(duì)Excel按條件進(jìn)行內(nèi)容補(bǔ)充的相關(guān)知識(shí),非常不錯(cuò),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11

