邊緣檢測算法綜合指南
介紹
圖像處理是一個廣泛使用的概念,用于利用圖像中的信息。圖像處理算法需要很長時間來處理數(shù)據(jù),因為圖像很大,并且其中可用的信息量很大。因此,在這些前沿技術中,有必要減少算法所關注的信息量。有時這只能通過傳遞圖像的邊緣來完成。
所以在這篇博客中,讓我們了解 Canny 邊緣檢測器和整體嵌套邊緣檢測器。
什么是邊緣檢測?
圖像中的邊緣是圖像強度的顯著局部變化。顧名思義,邊緣檢測是檢測圖像邊緣的過程。下面的示例描述了海星圖像的邊緣檢測。
圖1.1 邊緣檢測
為什么我們需要邊緣檢測?
深度、表面方向、場景照明變化和材料屬性變化的不連續(xù)性會導致圖像亮度的不連續(xù)性。我們得到表示對象邊界和表面標記的曲線集,以及對應于表面方向不連續(xù)性的曲線。
因此,將邊緣檢測算法應用于圖像可以顯著減少要處理的數(shù)據(jù)量,因此可以過濾掉可能被認為不太相關的信息,同時保留圖像的重要結構屬性。
如圖 1.1 所示,圖像的結構屬性是通過邊緣檢測捕獲的。
了解流行的邊緣檢測算法
在討論了邊緣檢測算法的重要性之后,本節(jié)將重點了解一些流行且廣泛使用的邊緣檢測算法。
邊緣檢測有多種方法。讓我們將這些方法大致分為:
· 傳統(tǒng)方法
· 基于深度學習的方法
現(xiàn)在,讓我們討論最流行的邊緣檢測算法之一——canny 邊緣檢測器,并將其與 Sobel 和 Prewitt 進行比較。
Canny 邊緣檢測器
Canny 邊緣檢測算法是當今圖像處理應用中廣泛使用的邊緣檢測算法。它在多個階段工作,如圖 1.2 所示。Canny 邊緣檢測算法產(chǎn)生比 Sobel 和 Prewitt 過濾器更平滑、更薄、更清晰的圖像。
這里是canny邊緣檢測算法的總結:
對輸入圖像進行平滑處理,應用 Sobel 濾波器檢測圖像的邊緣。然后我們應用非最大抑制,保留梯度方向上的局部最大像素,其余的被抑制。我們應用閾值處理來去除低于某個閾值的像素,并保留高于某個閾值的像素以去除可能由于噪聲而形成的邊緣。
稍后,如果 8 個相鄰像素中的任何一個像素很強,我們就會應用滯后跟蹤來使像素變強。
圖1.2 Canny 邊緣檢測器
現(xiàn)在,我們將詳細討論每個步驟。
Canny邊緣檢測涉及5個步驟,如上圖1.2所示。我們將使用下圖進行說明。
圖像平滑
在這一步中,我們將圖像轉換為灰度,因為邊緣檢測不依賴于顏色。然后我們用高斯濾波器去除圖像中的噪聲,因為邊緣檢測容易產(chǎn)生噪聲。
尋找圖像的強度梯度
然后,我們在水平和垂直方向上應用 Sobel 核,以獲得平滑圖像上水平方向 (G x ) 和垂直方向 (G y ) 的一階導數(shù)。然后我們計算邊緣梯度(G)和角度(θ),如下所示,
我們知道梯度方向垂直于邊緣。我們將角度四舍五入到代表垂直、水平和兩個對角線方向的四個角度之一。
非最大值抑制
現(xiàn)在我們刪除所有可能不構成邊緣的像素。為此,如果每個像素在其鄰域中是局部最大值,則在梯度方向上進行檢查。如果是局部最大值,則考慮用于下一階段,否則,將其變暗,設置為 0。這將在輸出圖像中給出一條細線。
雙閾值
由于噪聲和顏色變化導致的像素會在圖像中持續(xù)存在。因此,為了消除這一點,我們從用戶那里獲得了兩個閾值,lowerVal 和 upperVal。
我們過濾掉具有弱梯度(lowerVal)值的邊緣像素,并保留具有高梯度值(upperVal)的邊緣像素。強度梯度大于upperVal的邊緣肯定是邊緣,低于lowerVal的肯定是非邊緣,所以丟棄。像素值小于 upperVal 且大于 lowerVal 的像素如果連接到“確定邊緣(sure-edge)”,則被視為邊緣的一部分。否則,它們也會被丟棄。
滯后邊緣跟蹤
如果一個像素周圍的 8 個像素中有一個是強像素(像素值 = 255),則將其設為強像素,否則將其設為 0。
這幾乎是關于 Canny 邊緣檢測的。如圖,邊緣是從圖像中檢測到的。
現(xiàn)在,我們將探索基于深度學習的邊緣檢測方法。但是為什么我們首先需要使用基于深度學習的邊緣檢測算法呢?Canny邊緣檢測只關注局部變化,不理解圖像的語義,即圖像內容。因此,提出了基于深度學習的算法來解決這些問題。我們現(xiàn)在將詳細討論它。
但在我們深入研究深度學習的數(shù)學之前,讓我們首先嘗試在 OpenCV 中實現(xiàn) Canny 邊緣檢測器和基于深度學習的模型(HED)。
實現(xiàn) - Canny 邊緣檢測器
讓我們導入必要的模塊
import cv2 from skimage.metrics import mean_squared_error,peak_signal_noise_ratio,structural_similarity
import matplotlib.pyplot as plt
以下代碼在海星圖像上應用 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')
接下來,讓我們在進行數(shù)學運算之前看看 HED 的代碼。
實現(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")
我們讀取由邊緣組成的實際圖像
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]
我們對圖像進行標準化,以使 MSE 值不會上升
#Normalising all the images
test_y = test_y/255
hed = hed/255
canny = canny/255
gray = gray/255
我們現(xiàn)在可視化我們的結果
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')
最后,我們計算指標并比較我們的結果
#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))
為什么要使用深度學習進行邊緣檢測?
在閱讀 HED 之前,可能會出現(xiàn)一個問題,為什么我們需要深度學習算法來完成如此簡單的邊緣檢測任務?
答案是 Canny 邊緣檢測主要關注局部變化而不是圖像的語義,即它較少關注圖像的內容。因此,我們得到不太準確的邊緣。
邊緣檢測的深度學習方法
整體嵌套邊緣檢測( HED)技術是一種基于學習的端到端邊緣檢測系統(tǒng),它使用修剪后的 VGG 類卷積神經(jīng)網(wǎng)絡來執(zhí)行圖像到圖像的預測任務。HED 在神經(jīng)網(wǎng)絡中生成邊輸出。所有側面輸出都融合在一起以形成最終輸出。讓我們更詳細地了解該算法。
圖 1.3 使用 HED 進行邊緣檢測
算法概述
我們采用 VGGNet 架構,但做了以下修改:
(a) 我們將側輸出層連接到每個階段的最后一個卷積層,分別為 conv1 2、conv2 2、conv3 3、conv4 3、conv5 3。
(b) 我們去掉了 VGGNet 的最后階段,包括第 5 個池化層和所有全連接層。此外,網(wǎng)絡內反卷積層結合了雙線性插值的輸出。
圖 1.4:HED
HED 的訓練和測試階段將在本文的最后一節(jié)中介紹。我建議你瀏覽一下,以便更好地理解模型體系結構。
HED:訓練和測試階段
現(xiàn)在,讓我們談談 HED 的訓練和測試階段。正如我在文章開頭提到的,這是一個涉及很多數(shù)學知識的部分,所以這一部分的閱讀是可選的。我強烈建議你閱讀這一部分以真正掌握 HED 的內部運作原理。
訓練階段
讓我們將所有標準網(wǎng)絡層參數(shù)的集合表示為 W,該網(wǎng)絡有 M 個側輸出層。每個側輸出層還與一個分類器相關聯(lián),其中相應的權重表示為 w = (w (1) , . . . , w (m) ))
其中 l side表示側面輸出的圖像級損失函數(shù)。對于典型的自然圖像,邊緣/非邊緣像素分布存在嚴重偏差:90% 是非邊緣的。成本敏感的損失函數(shù)是為有偏采樣引入了額外的權衡參數(shù)。
具體來說,我們定義了上述等式中使用的以下類平衡交叉熵損失函數(shù)
其中:
為了直接利用側輸出預測,我們在網(wǎng)絡中添加了一個“加權融合”層,并(同時)在訓練期間學習融合權重。我們在融合層 l fuse的損失函數(shù)變?yōu)?/p>
其中 Dist 是交叉熵損失。我們給出整個目標函數(shù)為,
測試階段
在測試期間,給定圖像 X,我們從側面輸出層和加權融合層獲得邊緣圖預測。通過聚合這些生成的邊緣圖可以得到最終的統(tǒng)一輸出。
評估指標
現(xiàn)在,我們已經(jīng)了解了不同的邊緣檢測算法——傳統(tǒng)和深度學習方法。但是我們如何評估邊緣檢測算法的性能或比較不同的邊緣檢測算法呢?
這給我們帶來了邊緣檢測中另一個有趣的話題——評估指標。我們現(xiàn)在將討論邊緣檢測的不同評估指標。
均方誤差
MSE 表示影響表示質量的失真噪聲的能力。
公式:
峰值信噪比方程
峰值信噪比 (PSNR) 表示信號的最大可能值(功率)與影響其表示質量的失真噪聲的功率之間的比率。它是由
結構相似性指數(shù)指標
結構相似性指數(shù)指標從圖像的亮度、對比度和結構中提取 3 個關鍵特征。公式:
其中:
μx 是圖像 X 的平均值
μy 是圖像 Y 的平均值
是 X 的方差
是 Y 的方差
是 X 和 Y 的協(xié)方差
和
k1 = 0.01 和 k2 = 0.03
結論
我們已經(jīng)涵蓋了 Canny 邊緣檢測器的所有概念,然后使用 OpenCV 對其進行了編碼。我們討論了 Canny 邊緣檢測涉及的 5 個步驟,為什么 Canny 邊緣檢測器比以前的方法更好。還介紹了HED 方法所涉及的數(shù)學。我們還討論了一些評估指標來評估算法對圖像的執(zhí)行情況。
本文的主要內容是:
· Canny 邊緣檢測器提供比 Sobel 和 Prewitt 濾波器更平滑和更精細的邊緣
· 一種關注圖像的內容的深度學習方法
原文標題 : 邊緣檢測算法綜合指南

請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
推薦專題
- 1 UALink規(guī)范發(fā)布:挑戰(zhàn)英偉達AI統(tǒng)治的開始
- 2 北電數(shù)智主辦酒仙橋論壇,探索AI產(chǎn)業(yè)發(fā)展新路徑
- 3 “AI寒武紀”爆發(fā)至今,五類新物種登上歷史舞臺
- 4 降薪、加班、裁員三重暴擊,“AI四小龍”已折戟兩家
- 5 國產(chǎn)智駕迎戰(zhàn)特斯拉FSD,AI含量差幾何?
- 6 光計算迎來商業(yè)化突破,但落地仍需時間
- 7 東陽光:2024年扭虧、一季度凈利大增,液冷疊加具身智能打開成長空間
- 8 優(yōu)必選:營收大增主靠小件,虧損繼續(xù)又逢關稅,能否乘機器人東風翻身?
- 9 地平線自動駕駛方案解讀
- 10 封殺AI“照騙”,“淘寶們”終于不忍了?