邊緣檢測算法綜合指南
介紹
圖像處理是一個廣泛使用的概念,用于利用圖像中的信息。圖像處理算法需要很長時間來處理數(shù)據(jù),因?yàn)閳D像很大,并且其中可用的信息量很大。因此,在這些前沿技術(shù)中,有必要減少算法所關(guān)注的信息量。有時這只能通過傳遞圖像的邊緣來完成。
所以在這篇博客中,讓我們了解 Canny 邊緣檢測器和整體嵌套邊緣檢測器。
什么是邊緣檢測?
圖像中的邊緣是圖像強(qiáng)度的顯著局部變化。顧名思義,邊緣檢測是檢測圖像邊緣的過程。下面的示例描述了海星圖像的邊緣檢測。
圖1.1 邊緣檢測
為什么我們需要邊緣檢測?
深度、表面方向、場景照明變化和材料屬性變化的不連續(xù)性會導(dǎo)致圖像亮度的不連續(xù)性。我們得到表示對象邊界和表面標(biāo)記的曲線集,以及對應(yīng)于表面方向不連續(xù)性的曲線。
因此,將邊緣檢測算法應(yīng)用于圖像可以顯著減少要處理的數(shù)據(jù)量,因此可以過濾掉可能被認(rèn)為不太相關(guān)的信息,同時保留圖像的重要結(jié)構(gòu)屬性。
如圖 1.1 所示,圖像的結(jié)構(gòu)屬性是通過邊緣檢測捕獲的。
了解流行的邊緣檢測算法
在討論了邊緣檢測算法的重要性之后,本節(jié)將重點(diǎn)了解一些流行且廣泛使用的邊緣檢測算法。
邊緣檢測有多種方法。讓我們將這些方法大致分為:
· 傳統(tǒng)方法
· 基于深度學(xué)習(xí)的方法
現(xiàn)在,讓我們討論最流行的邊緣檢測算法之一——canny 邊緣檢測器,并將其與 Sobel 和 Prewitt 進(jìn)行比較。
Canny 邊緣檢測器
Canny 邊緣檢測算法是當(dāng)今圖像處理應(yīng)用中廣泛使用的邊緣檢測算法。它在多個階段工作,如圖 1.2 所示。Canny 邊緣檢測算法產(chǎn)生比 Sobel 和 Prewitt 過濾器更平滑、更薄、更清晰的圖像。
這里是canny邊緣檢測算法的總結(jié):
對輸入圖像進(jìn)行平滑處理,應(yīng)用 Sobel 濾波器檢測圖像的邊緣。然后我們應(yīng)用非最大抑制,保留梯度方向上的局部最大像素,其余的被抑制。我們應(yīng)用閾值處理來去除低于某個閾值的像素,并保留高于某個閾值的像素以去除可能由于噪聲而形成的邊緣。
稍后,如果 8 個相鄰像素中的任何一個像素很強(qiáng),我們就會應(yīng)用滯后跟蹤來使像素變強(qiáng)。
圖1.2 Canny 邊緣檢測器
現(xiàn)在,我們將詳細(xì)討論每個步驟。
Canny邊緣檢測涉及5個步驟,如上圖1.2所示。我們將使用下圖進(jìn)行說明。
圖像平滑
在這一步中,我們將圖像轉(zhuǎn)換為灰度,因?yàn)檫吘墮z測不依賴于顏色。然后我們用高斯濾波器去除圖像中的噪聲,因?yàn)檫吘墮z測容易產(chǎn)生噪聲。
尋找圖像的強(qiáng)度梯度
然后,我們在水平和垂直方向上應(yīng)用 Sobel 核,以獲得平滑圖像上水平方向 (G x ) 和垂直方向 (G y ) 的一階導(dǎo)數(shù)。然后我們計(jì)算邊緣梯度(G)和角度(θ),如下所示,
我們知道梯度方向垂直于邊緣。我們將角度四舍五入到代表垂直、水平和兩個對角線方向的四個角度之一。
非最大值抑制
現(xiàn)在我們刪除所有可能不構(gòu)成邊緣的像素。為此,如果每個像素在其鄰域中是局部最大值,則在梯度方向上進(jìn)行檢查。如果是局部最大值,則考慮用于下一階段,否則,將其變暗,設(shè)置為 0。這將在輸出圖像中給出一條細(xì)線。
雙閾值
由于噪聲和顏色變化導(dǎo)致的像素會在圖像中持續(xù)存在。因此,為了消除這一點(diǎn),我們從用戶那里獲得了兩個閾值,lowerVal 和 upperVal。
我們過濾掉具有弱梯度(lowerVal)值的邊緣像素,并保留具有高梯度值(upperVal)的邊緣像素。強(qiáng)度梯度大于upperVal的邊緣肯定是邊緣,低于lowerVal的肯定是非邊緣,所以丟棄。像素值小于 upperVal 且大于 lowerVal 的像素如果連接到“確定邊緣(sure-edge)”,則被視為邊緣的一部分。否則,它們也會被丟棄。
滯后邊緣跟蹤
如果一個像素周圍的 8 個像素中有一個是強(qiáng)像素(像素值 = 255),則將其設(shè)為強(qiáng)像素,否則將其設(shè)為 0。
這幾乎是關(guān)于 Canny 邊緣檢測的。如圖,邊緣是從圖像中檢測到的。
現(xiàn)在,我們將探索基于深度學(xué)習(xí)的邊緣檢測方法。但是為什么我們首先需要使用基于深度學(xué)習(xí)的邊緣檢測算法呢?Canny邊緣檢測只關(guān)注局部變化,不理解圖像的語義,即圖像內(nèi)容。因此,提出了基于深度學(xué)習(xí)的算法來解決這些問題。我們現(xiàn)在將詳細(xì)討論它。
但在我們深入研究深度學(xué)習(xí)的數(shù)學(xué)之前,讓我們首先嘗試在 OpenCV 中實(shí)現(xiàn) Canny 邊緣檢測器和基于深度學(xué)習(xí)的模型(HED)。
實(shí)現(xiàn) - Canny 邊緣檢測器
讓我們導(dǎo)入必要的模塊
import cv2 from skimage.metrics import mean_squared_error,peak_signal_noise_ratio,structural_similarity
import matplotlib.pyplot as plt
以下代碼在海星圖像上應(yīng)用 Canny 邊緣檢測器
img_path = 'starfish.png'
#Reading the image
image = cv2.imread(img_path)
(H, W) = image.shape[:2]
# convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# blur the image
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# Perform the canny operator
canny = cv2.Canny(blurred, 30, 150)
讓我們看看 Canny 邊緣檢測器的輸出
fig,ax = plt.subplots(1,2,figsize=(18, 18))
ax[0].imshow(gray,cmap='gray')
ax[1].imshow(canny,cmap='gray')
ax[0].a(chǎn)xis('off')
ax[1].a(chǎn)xis('off')
接下來,讓我們在進(jìn)行數(shù)學(xué)運(yùn)算之前看看 HED 的代碼。
實(shí)現(xiàn) - HED
#This class helps in cropping the specified coordinated in the function
class CropLayer(object):
def __init__(self, params, blobs):
# initialize our starting and ending (x, y)-coordinates of
self.startX = 0
self.startY = 0
self.endX = 0
self.endY = 0
def getMemoryShapes(self, inputs):
(inputShape, targetShape) = (inputs[0], inputs[1])
(batchSize, numChannels) = (inputShape[0], inputShape[1])
(H, W) = (targetShape[2], targetShape[3])
# compute the starting and ending crop coordinates
self.startX = int((inputShape[3] - targetShape[3]) / 2)
self.startY = int((inputShape[2] - targetShape[2]) / 2)
self.endX = self.startX + W
self.endY = self.startY + H
# return the shape of the volume (we'll perform the actual
# crop during the forward pass
return [[batchSize, numChannels, H, W]]
def forward(self, inputs):
return [inputs[0][:, :, self.startY:self.endY,self.startX:self.endX]]
你可以從此 repo 下載 deploy.prototxt 和 caffemodel:https://github.com/ashukid/hed-edge-detector
#The caffemodel contains the model of the architecture and the deploy.prototxt contains the weights
protoPath = 'deploy.prototxt.txt'
modelPath = 'hed_pretrained_bsds.caffemodel'
net = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
# register our new layer with the model
cv2.dnn_registerLayer("Crop", CropLayer)
現(xiàn)在我們讀取我們的圖像并將其傳遞給算法。
#Input image is converted to a blog
blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size=(W, H),mean=(104.00698793, 116.66876762, 122.67891434),swapRB=False, crop=False)
#We pass the blob into the network and make a forward pass
net.setInput(blob)
hed = net.forward()
hed = cv2.resize(hed[0, 0], (W, H))
hed = (255 * hed).a(chǎn)stype("uint8")
我們讀取由邊緣組成的實(shí)際圖像
test_y_path = 'edge.png'
test_y = cv2.imread(test_y_path)
#The test image has its third dimesion as 3
#So we are extractin only one dimension
test_y = test_y[:,:,0]
我們對圖像進(jìn)行標(biāo)準(zhǔn)化,以使 MSE 值不會上升
#Normalising all the images
test_y = test_y/255
hed = hed/255
canny = canny/255
gray = gray/255
我們現(xiàn)在可視化我們的結(jié)果
fig,ax = plt.subplots(1,2,figsize=(18, 18))
ax[0].imshow(gray,cmap='gray')
ax[1].imshow(hed,cmap='gray')
ax[0].a(chǎn)xis('off')
ax[1].a(chǎn)xis('off')
最后,我們計(jì)算指標(biāo)并比較我們的結(jié)果
#Calculating metrics between actual test image and the output we got through Canny edge detection
print(mean_squared_error(test_y,canny),peak_signal_noise_ratio(test_y,canny),structural_similarity(test_y,canny))
#Calculating metrics between actual test image and the output we got through HED
print(mean_squared_error(test_y,hed),peak_signal_noise_ratio(test_y,hed),structural_similarity(test_y,hed))
為什么要使用深度學(xué)習(xí)進(jìn)行邊緣檢測?
在閱讀 HED 之前,可能會出現(xiàn)一個問題,為什么我們需要深度學(xué)習(xí)算法來完成如此簡單的邊緣檢測任務(wù)?
答案是 Canny 邊緣檢測主要關(guān)注局部變化而不是圖像的語義,即它較少關(guān)注圖像的內(nèi)容。因此,我們得到不太準(zhǔn)確的邊緣。
邊緣檢測的深度學(xué)習(xí)方法
整體嵌套邊緣檢測( HED)技術(shù)是一種基于學(xué)習(xí)的端到端邊緣檢測系統(tǒng),它使用修剪后的 VGG 類卷積神經(jīng)網(wǎng)絡(luò)來執(zhí)行圖像到圖像的預(yù)測任務(wù)。HED 在神經(jīng)網(wǎng)絡(luò)中生成邊輸出。所有側(cè)面輸出都融合在一起以形成最終輸出。讓我們更詳細(xì)地了解該算法。
圖 1.3 使用 HED 進(jìn)行邊緣檢測
算法概述
我們采用 VGGNet 架構(gòu),但做了以下修改:
(a) 我們將側(cè)輸出層連接到每個階段的最后一個卷積層,分別為 conv1 2、conv2 2、conv3 3、conv4 3、conv5 3。
(b) 我們?nèi)サ袅?VGGNet 的最后階段,包括第 5 個池化層和所有全連接層。此外,網(wǎng)絡(luò)內(nèi)反卷積層結(jié)合了雙線性插值的輸出。
圖 1.4:HED
HED 的訓(xùn)練和測試階段將在本文的最后一節(jié)中介紹。我建議你瀏覽一下,以便更好地理解模型體系結(jié)構(gòu)。
HED:訓(xùn)練和測試階段
現(xiàn)在,讓我們談?wù)?HED 的訓(xùn)練和測試階段。正如我在文章開頭提到的,這是一個涉及很多數(shù)學(xué)知識的部分,所以這一部分的閱讀是可選的。我強(qiáng)烈建議你閱讀這一部分以真正掌握 HED 的內(nèi)部運(yùn)作原理。
訓(xùn)練階段
讓我們將所有標(biāo)準(zhǔn)網(wǎng)絡(luò)層參數(shù)的集合表示為 W,該網(wǎng)絡(luò)有 M 個側(cè)輸出層。每個側(cè)輸出層還與一個分類器相關(guān)聯(lián),其中相應(yīng)的權(quán)重表示為 w = (w (1) , . . . , w (m) ))
其中 l side表示側(cè)面輸出的圖像級損失函數(shù)。對于典型的自然圖像,邊緣/非邊緣像素分布存在嚴(yán)重偏差:90% 是非邊緣的。成本敏感的損失函數(shù)是為有偏采樣引入了額外的權(quán)衡參數(shù)。
具體來說,我們定義了上述等式中使用的以下類平衡交叉熵?fù)p失函數(shù)
其中:
為了直接利用側(cè)輸出預(yù)測,我們在網(wǎng)絡(luò)中添加了一個“加權(quán)融合”層,并(同時)在訓(xùn)練期間學(xué)習(xí)融合權(quán)重。我們在融合層 l fuse的損失函數(shù)變?yōu)?/p>
其中 Dist 是交叉熵?fù)p失。我們給出整個目標(biāo)函數(shù)為,
測試階段
在測試期間,給定圖像 X,我們從側(cè)面輸出層和加權(quán)融合層獲得邊緣圖預(yù)測。通過聚合這些生成的邊緣圖可以得到最終的統(tǒng)一輸出。
評估指標(biāo)
現(xiàn)在,我們已經(jīng)了解了不同的邊緣檢測算法——傳統(tǒng)和深度學(xué)習(xí)方法。但是我們?nèi)绾卧u估邊緣檢測算法的性能或比較不同的邊緣檢測算法呢?
這給我們帶來了邊緣檢測中另一個有趣的話題——評估指標(biāo)。我們現(xiàn)在將討論邊緣檢測的不同評估指標(biāo)。
均方誤差
MSE 表示影響表示質(zhì)量的失真噪聲的能力。
公式:
峰值信噪比方程
峰值信噪比 (PSNR) 表示信號的最大可能值(功率)與影響其表示質(zhì)量的失真噪聲的功率之間的比率。它是由
結(jié)構(gòu)相似性指數(shù)指標(biāo)
結(jié)構(gòu)相似性指數(shù)指標(biāo)從圖像的亮度、對比度和結(jié)構(gòu)中提取 3 個關(guān)鍵特征。公式:
其中:
μx 是圖像 X 的平均值
μy 是圖像 Y 的平均值
是 X 的方差
是 Y 的方差
是 X 和 Y 的協(xié)方差
和
k1 = 0.01 和 k2 = 0.03
結(jié)論
我們已經(jīng)涵蓋了 Canny 邊緣檢測器的所有概念,然后使用 OpenCV 對其進(jìn)行了編碼。我們討論了 Canny 邊緣檢測涉及的 5 個步驟,為什么 Canny 邊緣檢測器比以前的方法更好。還介紹了HED 方法所涉及的數(shù)學(xué)。我們還討論了一些評估指標(biāo)來評估算法對圖像的執(zhí)行情況。
本文的主要內(nèi)容是:
· Canny 邊緣檢測器提供比 Sobel 和 Prewitt 濾波器更平滑和更精細(xì)的邊緣
· 一種關(guān)注圖像的內(nèi)容的深度學(xué)習(xí)方法
原文標(biāo)題 : 邊緣檢測算法綜合指南
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-11.13立即報(bào)名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月28日立即報(bào)名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會議
-
12月19日立即報(bào)名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會
-
即日-12.26火熱報(bào)名中>> OFweek2024中國智造CIO在線峰會
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書》
-
精彩回顧立即查看>> 【限時免費(fèi)下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
推薦專題
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市