詳解Python中圖像邊緣檢測算法的實現(xiàn)
寫在前面
從本節(jié)開始,計算機視覺教程進入第三章節(jié)——圖像特征提取。在本章,你會見到一張簡簡單單的圖片中蘊含著這么多你沒注意到的細節(jié)特征,而這些特征將會在今后更高級的應用中發(fā)揮著極其重要的作用。本文講解基礎(chǔ)特征之一——圖像邊緣。
本文采用面向?qū)ο笤O(shè)計,定義了一個邊緣檢測類EdgeDetect,使圖像邊緣檢測算法的應用更簡潔,例如
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ò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ù)字圖像的高頻成分,對應圖像梯度的極值。在二維離散數(shù)字圖像上,某個方向上圖像強度函數(shù)微分使用有限差分法來近似,即:

因此圖像邊緣檢測即是對圖像的差分運算。
1.1 Prewitt算子
Prewitt算子本質(zhì)上就是x或y方向上相鄰像素的差分。

那我們常說的圖像梯度是什么意思呢?
其實就是用x與y方向上相鄰像素的差分為方向的向量

在編程實現(xiàn)上,就是構(gòu)造上圖的兩個方向的濾波算子,然后將x xx、y yy兩個方向的邊緣合成就是整張圖各方向的邊緣檢測結(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方向求導,并將其模板化即得Sobel算子。Sobel算子相比于Prewitt算子有更強的抗噪能力,因為其結(jié)合了高斯濾波的效果。

在編程實現(xiàn)上,就是構(gòu)造上圖的兩個方向的濾波算子,然后將x、y兩個方向的邊緣合成就是整張圖各方向的邊緣檢測結(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算子

寫成差分方程形式為

將差分方程進一步寫成卷積核形式如圖(a),可將其擴展為圖(b)使之具有各向同性。微分算子屬于高通濾波,在銳化邊緣的同時也增強了噪點,因此Laplace算子抗噪能力弱,且不能檢測邊緣方向。

在編程實現(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),即先低通濾除噪聲,再高通強化邊緣,LoG算子本質(zhì)上是帶通濾波器。

在編程實現(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算子濾除原圖像噪聲,并得到梯度圖;
- 應用非極大值抑制(Non-Maximum Suppression, NMS)以消除邊緣檢測、目標檢測帶來的雜散響應,即對待測邊緣或目標,應盡可能有唯一的準確響應
- 應用雙閾值(Double-Threshold)檢測來確定真實的和潛在的邊緣。
使用如下雙閾值檢測算法解決因噪聲引起的雜散邊緣響應。

閾值的選擇取決于給定輸入圖像的內(nèi)容。下面對弱邊緣進一步審查,即

通常,由真實邊緣引起的弱邊緣像素將連接到強邊緣像素,而噪聲響應未連接。為了跟蹤邊緣連接,通過查看弱邊緣像素的8個鄰域像素是否存在強邊緣像素,來決定是否濾除該弱邊緣點。
下面是Canny邊緣檢測算法的效果。

到此這篇關(guān)于詳解Python中圖像邊緣檢測算法的實現(xiàn)的文章就介紹到這了,更多相關(guān)Python圖像邊緣檢測算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于python list對象中嵌套元組使用sort時的排序方法
下面小編就為大家分享一篇基于python list對象中嵌套元組使用sort時的排序方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
Python+Selenium實現(xiàn)讀取網(wǎng)易郵箱驗證碼
在自動化工作中,有可能會遇到一些發(fā)送郵箱驗證碼類似的功能。本文將利用Python?Selenium實現(xiàn)自動化讀取網(wǎng)易郵箱驗證碼,感興趣的可以了解一下2022-03-03
keras在構(gòu)建LSTM模型時對變長序列的處理操作
這篇文章主要介紹了keras在構(gòu)建LSTM模型時對變長序列的處理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
Python實現(xiàn)U盤數(shù)據(jù)復制工具
這篇文章主要為大家詳細介紹了如何使用Python實現(xiàn)一個U盤數(shù)據(jù)復制工具,它可以幫助用戶快速、方便地將U盤中的文件復制到計算機中,希望對大家有所幫助2025-01-01

