詳解Python中圖像邊緣檢測算法的實(shí)現(xiàn)
寫在前面
從本節(jié)開始,計(jì)算機(jī)視覺教程進(jìn)入第三章節(jié)——圖像特征提取。在本章,你會(huì)見到一張簡簡單單的圖片中蘊(yùn)含著這么多你沒注意到的細(xì)節(jié)特征,而這些特征將會(huì)在今后更高級的應(yīng)用中發(fā)揮著極其重要的作用。本文講解基礎(chǔ)特征之一——圖像邊緣。
本文采用面向?qū)ο笤O(shè)計(jì),定義了一個(gè)邊緣檢測類EdgeDetect,使圖像邊緣檢測算法的應(yīng)用更簡潔,例如
import cv2 import numpy as np import matplotlib.pyplot as plt Detector = EdgeDetect('1.jpg') Prewitt = Detector.prewitt() plt.imshow(Prewitt , 'gray') plt.show()
這個(gè)類的構(gòu)造函數(shù)為
class EdgeDetect: def __init__(self, img) -> None: self.src = cv2.imread(img) self.gray = cv2.cvtColor(self.src, cv2.COLOR_BGR2GRAY)
讀取的是圖像的基本信息。
1.一階微分算子
圖像邊緣是數(shù)字圖像的高頻成分,對應(yīng)圖像梯度的極值。在二維離散數(shù)字圖像上,某個(gè)方向上圖像強(qiáng)度函數(shù)微分使用有限差分法來近似,即:
因此圖像邊緣檢測即是對圖像的差分運(yùn)算。
1.1 Prewitt算子
Prewitt算子本質(zhì)上就是x或y方向上相鄰像素的差分。
那我們常說的圖像梯度是什么意思呢?
其實(shí)就是用x與y方向上相鄰像素的差分為方向的向量
在編程實(shí)現(xiàn)上,就是構(gòu)造上圖的兩個(gè)方向的濾波算子,然后將x xx、y yy兩個(gè)方向的邊緣合成就是整張圖各方向的邊緣檢測結(jié)果
def prewitt(self): # Prewitt 算子 kernelX = np.array([[1,1,1],[0,0,0],[-1,-1,-1]], dtype=int) kernelY = np.array([[-1,0,1],[-1,0,1],[-1,0,1]], dtype=int) # 對圖像濾波 x = cv2.filter2D(self.gray, cv2.CV_16S, kernelX) y = cv2.filter2D(self.gray, cv2.CV_16S, kernelY) # 轉(zhuǎn) uint8 ,圖像融合 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) return cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
1.2 Sobel算子
對高斯核函數(shù)x、y方向求導(dǎo),并將其模板化即得Sobel算子。Sobel算子相比于Prewitt算子有更強(qiáng)的抗噪能力,因?yàn)槠浣Y(jié)合了高斯濾波的效果。
在編程實(shí)現(xiàn)上,就是構(gòu)造上圖的兩個(gè)方向的濾波算子,然后將x、y兩個(gè)方向的邊緣合成就是整張圖各方向的邊緣檢測結(jié)果
def sobel(self): # Sobel 算子 kernelX = np.array([[1, 2, 1],[0, 0, 0],[-1, -2, -1]],dtype=int) kernelY = np.array([[-1, -2, -1],[0, 0, 0],[1, 2, 1]],dtype=int) # 對圖像濾波 x = cv2.filter2D(self.gray, cv2.CV_16S, kernelX) y = cv2.filter2D(self.gray, cv2.CV_16S, kernelY) # 轉(zhuǎn) uint8 ,圖像融合 absX = cv2.convertScaleAbs(x) absY = cv2.convertScaleAbs(y) return cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
2.二階微分算子
2.1 Laplace算子
將Laplace算子
寫成差分方程形式為
將差分方程進(jìn)一步寫成卷積核形式如圖(a),可將其擴(kuò)展為圖(b)使之具有各向同性。微分算子屬于高通濾波,在銳化邊緣的同時(shí)也增強(qiáng)了噪點(diǎn),因此Laplace算子抗噪能力弱,且不能檢測邊緣方向。
在編程實(shí)現(xiàn)上,就是構(gòu)造上圖的濾波算子
# Laplace 算子 def laplace(self): kernel = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]], dtype=int) img = cv2.filter2D(self.gray, cv2.CV_16S, kernel) return cv2.convertScaleAbs(img)
2.2 LoG算子
為克服Laplace算子抗噪能力弱這一問題,引入高斯-拉普拉斯算子(LoG, Laplace of Gaussian),即先低通濾除噪聲,再高通強(qiáng)化邊緣,LoG算子本質(zhì)上是帶通濾波器。
在編程實(shí)現(xiàn)上,就是構(gòu)造上圖的濾波算子
# LoG算子 def LoG(self): kernel = np.array([[0, 0, 1, 0, 0], [0, 1, 2, 1, 0], [1, 2, -16, 2, 1], [0, 1, 2, 1, 0], [0, 0, 1, 0, 0]], dtype=int) img = cv2.filter2D(self.gray, cv2.CV_16S, kernel) return cv2.convertScaleAbs(img)
3.Canny邊緣檢測
Canny邊緣檢測算法可以分為以下步驟。
- 使用Sobel算子濾除原圖像噪聲,并得到梯度圖;
- 應(yīng)用非極大值抑制(Non-Maximum Suppression, NMS)以消除邊緣檢測、目標(biāo)檢測帶來的雜散響應(yīng),即對待測邊緣或目標(biāo),應(yīng)盡可能有唯一的準(zhǔn)確響應(yīng)
- 應(yīng)用雙閾值(Double-Threshold)檢測來確定真實(shí)的和潛在的邊緣。
使用如下雙閾值檢測算法解決因噪聲引起的雜散邊緣響應(yīng)。
閾值的選擇取決于給定輸入圖像的內(nèi)容。下面對弱邊緣進(jìn)一步審查,即
通常,由真實(shí)邊緣引起的弱邊緣像素將連接到強(qiáng)邊緣像素,而噪聲響應(yīng)未連接。為了跟蹤邊緣連接,通過查看弱邊緣像素的8個(gè)鄰域像素是否存在強(qiáng)邊緣像素,來決定是否濾除該弱邊緣點(diǎn)。
下面是Canny邊緣檢測算法的效果。
到此這篇關(guān)于詳解Python中圖像邊緣檢測算法的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python圖像邊緣檢測算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python numpy數(shù)組轉(zhuǎn)置與軸變換
這篇文章主要介紹了Python numpy數(shù)組轉(zhuǎn)置與軸變換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11celery實(shí)現(xiàn)動(dòng)態(tài)設(shè)置定時(shí)任務(wù)
這篇文章主要為大家詳細(xì)介紹了celery實(shí)現(xiàn)動(dòng)態(tài)設(shè)置定時(shí)任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03python使用pil庫實(shí)現(xiàn)圖片合成實(shí)例代碼
這篇文章主要介紹了python PIL實(shí)現(xiàn)圖片合成實(shí)例代碼,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01Python3讀取和寫入excel表格數(shù)據(jù)的示例代碼
這篇文章主要介紹了Python3讀取和寫入excel表格數(shù)據(jù)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Python基于smtplib模塊發(fā)送郵件代碼實(shí)例
這篇文章主要介紹了Python基于smtplib模塊發(fā)送郵件代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05python中tf.boolean_mask()函數(shù)的使用方法詳解
這篇文章主要介紹了python中tf.boolean_mask()函數(shù)的使用方法詳解,?tf.boolean_mask()?函數(shù)的作用是通過布爾值對指定的列的元素進(jìn)行過濾,需要的朋友可以參考下2023-11-11python數(shù)據(jù)預(yù)處理 :樣本分布不均的解決(過采樣和欠采樣)
今天小編就為大家分享一篇python數(shù)據(jù)預(yù)處理 :樣本分布不均的解決(過采樣和欠采樣),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02Python json格式化打印實(shí)現(xiàn)過程解析
這篇文章主要介紹了Python json格式化打印實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07