在這篇文章中,我們將學(xué)習(xí)如何在OpenCV中使用基于深度學(xué)習(xí)的邊緣檢測,它比目前流行的canny邊緣檢測器更精確。邊緣檢測在許多用例中是有用的,如視覺顯著性檢測,目標(biāo)檢測,跟蹤和運(yùn)動(dòng)分析,結(jié)構(gòu)從運(yùn)動(dòng),3D重建,自動(dòng)駕駛,圖像到文本分析等等。
01 什么是邊緣檢測?
邊緣檢測是計(jì)算機(jī)視覺中一個(gè)非常古老的問題,它涉及到檢測圖像中的邊緣來確定目標(biāo)的邊界,從而分離感興趣的目標(biāo)。最流行的邊緣檢測技術(shù)之一是Canny邊緣檢測,它已經(jīng)成為大多數(shù)計(jì)算機(jī)視覺研究人員和實(shí)踐者的首選方法。讓我們快速看一下Canny邊緣檢測。
02 Canny邊緣檢測算法
1983年,John Canny在麻省理工學(xué)院發(fā)明了Canny邊緣檢測。它將邊緣檢測視為一個(gè)信號處理問題。其核心思想是,如果你觀察圖像中每個(gè)像素的強(qiáng)度變化,它在邊緣的時(shí)候非常高。
在下面這張簡單的圖片中,強(qiáng)度變化只發(fā)生在邊界上。所以,你可以很容易地通過觀察像素強(qiáng)度的變化來識別邊緣。
現(xiàn)在,看下這張圖片。強(qiáng)度不是恒定的,但強(qiáng)度的變化率在邊緣處最高。(微積分復(fù)習(xí):變化率可以用一階導(dǎo)數(shù)(梯度)來計(jì)算。)
Canny邊緣檢測器通過4步來識別邊緣:
去噪:因?yàn)檫@種方法依賴于強(qiáng)度的突然變化,如果圖像有很多隨機(jī)噪聲,那么會(huì)將噪聲作為邊緣。所以,使用5×5的高斯濾波器平滑你的圖像是一個(gè)非常好的主意。
梯度計(jì)算:下一步,我們計(jì)算圖像中每個(gè)像素的強(qiáng)度的梯度(強(qiáng)度變化率)。我們也計(jì)算梯度的方向。
梯度方向垂直于邊緣,它被映射到四個(gè)方向中的一個(gè)(水平、垂直和兩個(gè)對角線方向)
非極大值抑制:現(xiàn)在,我們想刪除不是邊緣的像素(設(shè)置它們的值為0)。你可能會(huì)說,我們可以簡單地選取梯度值最高的像素,這些就是我們的邊。然而,在真實(shí)的圖像中,梯度不是簡單地在只一個(gè)像素處達(dá)到峰值,而是在臨近邊緣的像素處都非常高。因此我們在梯度方向上取3×3附近的局部最大值。
遲滯閾值化:在下一步中,我們需要決定一個(gè)梯度的閾值,低于這個(gè)閾值所有的像素都將被抑制(設(shè)置為0)。而Canny邊緣檢測器則采用遲滯閾值法。遲滯閾值法是一種非常簡單而有效的方法。我們使用兩個(gè)閾值來代替只用一個(gè)閾值:
高閾值 = 選擇一個(gè)非常高的值,這樣任何梯度值高于這個(gè)值的像素都肯定是一個(gè)邊緣。
低閾值 = 選擇一個(gè)非常低的值,任何梯度值低于該值的像素絕對不是邊緣。
在這兩個(gè)閾值之間有梯度的像素會(huì)被檢查,如果它們和邊緣相連,就會(huì)留下,否則就會(huì)去掉。
遲滯閾值化
03
Canny 邊緣檢測的問題:
由于Canny邊緣檢測器只關(guān)注局部變化,沒有語義(理解圖像的內(nèi)容)理解,精度有限(很多時(shí)候是這樣)。
Canny邊緣檢測器在這種情況下會(huì)失敗,因?yàn)闆]有理解圖像的上下文
語義理解對于邊緣檢測是至關(guān)重要的,這就是為什么使用機(jī)器學(xué)習(xí)或深度學(xué)習(xí)的基于學(xué)習(xí)的檢測器比canny邊緣檢測器產(chǎn)生更好的結(jié)果。
04 OpenCV中基于深度學(xué)習(xí)的邊緣檢測
OpenCV在其全新的DNN模塊中集成了基于深度學(xué)習(xí)的邊緣檢測技術(shù)。你需要OpenCV 3.4.3或更高版本。這種技術(shù)被稱為整體嵌套邊緣檢測或HED,是一種基于學(xué)習(xí)的端到端邊緣檢測系統(tǒng),使用修剪過的類似vgg的卷積神經(jīng)網(wǎng)絡(luò)進(jìn)行圖像到圖像的預(yù)測任務(wù)。
HED利用了中間層的輸出。之前的層的輸出稱為side output,將所有5個(gè)卷積層的輸出進(jìn)行融合,生成最終的預(yù)測。由于在每一層生成的特征圖大小不同,它可以有效地以不同的尺度查看圖像。
網(wǎng)絡(luò)結(jié)構(gòu):整體嵌套邊緣檢測
HED方法不僅比其他基于深度學(xué)習(xí)的方法更準(zhǔn)確,而且速度也比其他方法快得多。這就是為什么OpenCV決定將其集成到新的DNN模塊中。以下是這篇論文的結(jié)果:
05 在OpenCV中訓(xùn)練深度學(xué)習(xí)邊緣檢測的代碼
OpenCV使用的預(yù)訓(xùn)練模型已經(jīng)在Caffe框架中訓(xùn)練過了,可以這樣加載:
shdownload_pretrained.sh
網(wǎng)絡(luò)中有一個(gè)crop層,默認(rèn)是沒有實(shí)現(xiàn)的,所以我們需要自己實(shí)現(xiàn)一下。
現(xiàn)在,我們可以重載這個(gè)類,只需用一行代碼注冊該層。
cv.dnn_registerLayer('Crop',CropLayer)
現(xiàn)在,我們準(zhǔn)備構(gòu)建網(wǎng)絡(luò)圖并加載權(quán)重,這可以通過OpenCV的dnn.readNe函數(shù)。
net=cv.dnn.readNet(args.prototxt,args.caffemodel)
現(xiàn)在,下一步是批量加載圖像,并通過網(wǎng)絡(luò)運(yùn)行它們。為此,我們使用cv2.dnn.blobFromImage方法。該方法從輸入圖像中創(chuàng)建四維blob。
blob=cv.dnn.blobFromImage(image,scalefactor,size,mean,swapRB,crop)
其中:
image:是我們想要發(fā)送給神經(jīng)網(wǎng)絡(luò)進(jìn)行推理的輸入圖像。
scalefactor:圖像縮放常數(shù),很多時(shí)候我們需要把uint8的圖像除以255,這樣所有的像素都在0到1之間。默認(rèn)值是1.0,不縮放。
size:輸出圖像的空間大小。它將等于后續(xù)神經(jīng)網(wǎng)絡(luò)作為blobFromImage輸出所需的輸入大小。
swapRB:布爾值,表示我們是否想在3通道圖像中交換第一個(gè)和最后一個(gè)通道。OpenCV默認(rèn)圖像為BGR格式,但如果我們想將此順序轉(zhuǎn)換為RGB,我們可以將此標(biāo)志設(shè)置為True,這也是默認(rèn)值。
mean:為了進(jìn)行歸一化,有時(shí)我們計(jì)算訓(xùn)練數(shù)據(jù)集上的平均像素值,并在訓(xùn)練過程中從每幅圖像中減去它。如果我們在訓(xùn)練中做均值減法,那么我們必須在推理中應(yīng)用它。這個(gè)平均值是一個(gè)對應(yīng)于R, G, B通道的元組。例如Imagenet數(shù)據(jù)集的均值是R=103.93, G=116.77, B=123.68。如果我們使用swapRB=False,那么這個(gè)順序?qū)⑹?B, G, R)。
crop:布爾標(biāo)志,表示我們是否想居中裁剪圖像。如果設(shè)置為True,則從中心裁剪輸入圖像時(shí),較小的尺寸等于相應(yīng)的尺寸,而其他尺寸等于或大于該尺寸。然而,如果我們將其設(shè)置為False,它將保留長寬比,只是將其調(diào)整為固定尺寸大小。
在我們這個(gè)場景下:
inp=cv.dnn.blobFromImage(frame,scalefactor=1.0,size=(args.width,args.height),
mean=(104.00698793,116.66876762,122.67891434),swapRB=False,
crop=False)
現(xiàn)在,我們只需要調(diào)用一下前向方法。
結(jié)果:
審核編輯:劉清
-
邊緣檢測
+關(guān)注
關(guān)注
0文章
92瀏覽量
18250 -
OpenCV
+關(guān)注
關(guān)注
31文章
635瀏覽量
41582 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5516瀏覽量
121584 -
高斯濾波器
+關(guān)注
關(guān)注
0文章
9瀏覽量
1753 -
dnn
+關(guān)注
關(guān)注
0文章
60瀏覽量
9093
原文標(biāo)題:干貨丨在OpenCV中基于深度學(xué)習(xí)的邊緣檢測
文章出處:【微信號:gh_c87a2bc99401,微信公眾號:INDEMIND】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
如何在深度學(xué)習(xí)中使用紋理分析
AI模型部署邊緣設(shè)備的奇妙之旅:如何在邊緣端部署OpenCV
Rayeager PX2開發(fā)板測試opencv邊緣檢測效果
【DragonBoard 410c試用體驗(yàn)】之OpenCV中canny算子邊緣檢測
如何在您選擇的邊緣計(jì)算框架中使用EdgeScale
![如<b class='flag-5'>何在</b>您選擇的<b class='flag-5'>邊緣</b>計(jì)算框架<b class='flag-5'>中使</b>用EdgeScale](https://file.elecfans.com/web1/M00/7F/0B/pIYBAFwbSSKAVDxnAAAmV8uSVBg461.jpg)
如何在OpenCV中使用基于深度學(xué)習(xí)的邊緣檢測
![如<b class='flag-5'>何在</b><b class='flag-5'>OpenCV</b><b class='flag-5'>中使</b>用基于<b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b>的<b class='flag-5'>邊緣</b><b class='flag-5'>檢測</b>](https://file.elecfans.com/web1/M00/EB/18/o4YBAGB7mSuAZaPlAAAHdZNBrxc729.png)
OpenCV使用深度學(xué)習(xí)做邊緣檢測的流程
![<b class='flag-5'>OpenCV</b>使用<b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b>做<b class='flag-5'>邊緣</b><b class='flag-5'>檢測</b>的流程](https://file.elecfans.com/web1/M00/EE/69/pIYBAGCWAuGAbNpUAAAHxLM9J0w141.png)
如何在OpenCV中實(shí)現(xiàn)CUDA加速
如何在OpenCV中使用基于深度學(xué)習(xí)的邊緣檢測?
![如<b class='flag-5'>何在</b><b class='flag-5'>OpenCV</b><b class='flag-5'>中使</b>用基于<b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b>的<b class='flag-5'>邊緣</b><b class='flag-5'>檢測</b>?](https://file1.elecfans.com/web2/M00/82/E0/wKgZomRliXCAE1W-AAAHxLM9J0w793.png)
如何在深度學(xué)習(xí)結(jié)構(gòu)中使用紋理特征
![如<b class='flag-5'>何在</b><b class='flag-5'>深度</b><b class='flag-5'>學(xué)習(xí)</b>結(jié)構(gòu)<b class='flag-5'>中使</b>用紋理特征](https://file.elecfans.com/web2/M00/4E/DC/poYBAGLCjeiALm_WAAAYmfR7Qec474.png)
OpenCV庫在圖像處理和深度學(xué)習(xí)中的應(yīng)用
如何在汽車CAN應(yīng)用中使用負(fù)邊緣觸發(fā)觸發(fā)器節(jié)省電力
![如<b class='flag-5'>何在</b>汽車CAN應(yīng)用<b class='flag-5'>中使</b>用負(fù)<b class='flag-5'>邊緣</b>觸發(fā)觸發(fā)器節(jié)省電力](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論