訂閱
糾錯(cuò)
加入自媒體

OpenCV 指南2:如何在圖像中進(jìn)行邊緣檢測(cè)?

在上篇文章中,我們已經(jīng)學(xué)習(xí)了 OpenCV 的基礎(chǔ)知識(shí)。我們已經(jīng)看到了如何執(zhí)行圖像和視頻調(diào)整大小、裁剪等,這是 OpenCV 教程的第二部分。

本文,我們主要關(guān)注 OpenCV 的高級(jí)部分,它將涵蓋以下提到的問題。但是,如果你是 OpenCV 的新手或覺得這很難理解,那么請(qǐng)?jiān)L問OpenCV 基礎(chǔ)指南第1部分并復(fù)習(xí)基礎(chǔ)知識(shí),然后再回到此文。

我們思考的問題是:

如何在圖像中進(jìn)行邊緣檢測(cè)?

如何在圖像中進(jìn)行輪廓檢測(cè)?

如何在圖像中執(zhí)行顏色空間?

如何處理顏色通道?

如何模糊圖像?

如何使用位運(yùn)算符?

如何在圖像的每個(gè)像素點(diǎn)繪制顏色的直方圖?

1)如何在圖像中進(jìn)行邊緣檢測(cè)?

1.1. Canny:對(duì)于這里的邊緣檢測(cè),我們將使用 cv.Canny 方法。輸入圖像為原始圖像,thereshold-1 即像素值低于150 被視為非邊緣,threshold-2 即像素值高于175 被視為有效邊緣。如果該值在 150 和 175 之間,那么如果邊緣像素與有效邊緣相連,則僅將其視為有效邊緣。original_img=cv.imread("/content/drive/MyDrive/Colab Notebooks/Opencv/NCS/hana-lshin-qUhu8zjm38w-unsplash(1).jpg")
cv2_imshow(original_img)
print("  Edge detection in the Original images  ")
#We will find the edges in the image as below
Edge_Org=cv.Canny(original_img,150,175)
cv2_imshow(Edge_Org)
上述代碼的輸出:原圖:

原始圖像的邊緣:

現(xiàn)在我們將嘗試通過使其模糊來找到原始圖像的邊緣。博客中進(jìn)一步介紹了如何使圖像模糊。

通過比較原始圖像和模糊圖像之間的邊緣檢測(cè)。我們知道圖像中的邊緣檢測(cè)隨著圖像模糊程度的增加而減少。1.2. 拉普拉斯算子在拉普拉斯邊緣檢測(cè)方法中,我們將計(jì)算源圖像的 (x,y) 像素的第二個(gè)梯度。當(dāng) ksize>1 時(shí),查看下面提到的源圖像的拉普拉斯公式:

當(dāng) ksize=1 時(shí),拉普拉斯算子是通過使用以下 3×3 孔徑過濾圖像來計(jì)算:

其中 ksize:用于計(jì)算二階導(dǎo)數(shù)濾波器的孔徑大小。大小必須是正數(shù)和奇數(shù)。lap=cv.Laplacian(original_img,cv.CV_64F)
lap=np.uint8(np.a(chǎn)bsolute(lap))
cv2_imshow(lap)
上述代碼的輸出:拉普拉斯邊緣檢測(cè):

1.3.Sobel邊緣檢測(cè)在計(jì)算拉普拉斯算子時(shí),我們計(jì)算了稱為 Sobel 的二階導(dǎo)數(shù)。因此,在 sobel 檢測(cè)中,我們將計(jì)算 sobelx(也稱為水平 Sobel 導(dǎo)數(shù))和 sobely(也稱為垂直 Sobel 導(dǎo)數(shù))。我們可以通過輸入圖像與大小為 3*3 的內(nèi)核進(jìn)行卷積,來計(jì)算 Sobelx 和 sobely(但我們可以根據(jù)需要更改內(nèi)核大小)。拉普拉斯公式中的 Sobelx 和 sobely:

提到的卷積的 3*3 矩陣是:

Sobel 邊緣檢測(cè)的代碼:#Sobel
Sobelx=cv.Sobel(Gray_1,cv.CV_64F,1,0)
Sobely=cv.Sobel(Gray_1,cv.CV_64F,0,1)
Cpmbine_Sobel=cv.bitwise_or(Sobelx,Sobely)
print(" SobelX Edge Detection")
cv2_imshow(Sobelx)
print(" Sobely Edge Detection")
cv2_imshow(Sobely)
print(" ombine Sobel Edge Detection")
cv2_imshow(Cpmbine_Sobel)
上述代碼的輸出:Sobelx:

Sobely:

結(jié)合Sobel:

1.4. 腐蝕和膨脹

1.4.1 腐蝕它對(duì)于去除小的白噪聲很有用。用于分離兩個(gè)連接的對(duì)象等。怎么運(yùn)作:內(nèi)核(奇數(shù)大小的矩陣(3,5,7)與圖像卷積。僅當(dāng)內(nèi)核下的所有像素都為 1 時(shí),原始圖像中的像素(1 或 0)才會(huì)被視為 1,否則它會(huì)被腐蝕(使其為零)。因此,根據(jù)內(nèi)核的大小,將丟棄邊界附近的所有像素。因此,前景對(duì)象的厚度或大小會(huì)減少,或者只是圖像中的白色區(qū)域會(huì)減少。1.4.2 膨脹:在去除噪聲等情況下,腐蝕之后是膨脹。因?yàn)?腐蝕去除了白噪聲,但它也縮小了我們的對(duì)象。所以我們膨脹它。由于噪音消失了,它們不會(huì)回來,但我們的對(duì)象區(qū)域會(huì)增加。它也可用于連接對(duì)象的損壞部分。這個(gè)怎么運(yùn)作:內(nèi)核(奇數(shù)大小的矩陣(3,5,7)與圖像卷積如果內(nèi)核下至少有一個(gè)像素為“1”,則原始圖像中的像素元素為“1”。它增加了圖像中的白色區(qū)域或前景對(duì)象的大小增加Dilate 和 Erode 的代碼演練:#Dilating the image i.e., It will incrases the thickness of the edges
Dilat_img=cv.dilate(Edge_blur,(7,7),iterations=3)
cv2_imshow(Dilat_img)
#We can restore to the original edges by using the erode
print(" ")
Erode_img=cv.erode(Dilat_img,(7,7),iterations=3)
cv2_imshow(Erode_img)
上述代碼的輸出:將圖像輸入到 cv.dilate():

Dilate : 它會(huì)增加邊緣的厚度

腐蝕:這里的輸入圖像是 cv.dilate 輸出。所以腐蝕輸出將恢復(fù) Dilate 的輸入圖像。

2)如何在圖像中進(jìn)行輪廓檢測(cè)?

有時(shí),如果我們對(duì)圖像執(zhí)行邊緣檢測(cè)和輪廓檢測(cè),則兩者的輸出可能看起來相似。但與邊緣檢測(cè)相比,輪廓檢測(cè)通常會(huì)更詳細(xì)。cv.findContours 函數(shù)中的一些重要參數(shù)是:Image :輸入圖像應(yīng)該是二進(jìn)制作為源,一個(gè)8位的單通道圖像。非零像素被視為 1。零像素保持 0,因此圖像被視為二進(jìn)制。輪廓檢索模式:1)cv.RETR_TREE →它將給出圖像中的分層輪廓。cv.RETR_EXTERNAL →它將給出圖像中唯一的外部輪廓。cv.RETR_LIST →它將給出圖像中存在的所有輪廓。輪廓逼近方法:1)CHAIN_APPROX_NONE →它將給出圖像中存在的所有計(jì)數(shù)器。2)CHAIN_APPROX_SIMPLE →它將給出圖像中的重要輪廓,例如,如果我們有線,它只會(huì)給出圖像中的起點(diǎn)和終點(diǎn),而在 CHAIN_APPROX_NONE 的情況下,我們得到所有點(diǎn),F(xiàn)在讓我們來看看它實(shí)際上是如何工作的。Org_img=cv.imread("/content/drive/MyDrive/Colab Notebooks/Opencv/NCS/olena-sergienko-UQLGR8otAEs-unsplash(1).jpg")
Canny_img=cv.Canny(Org_img,100,150)
cv2_imshow(Canny_img)
contours,hierarchies= cv.findContours(Canny_img,cv.RETR_LIST,cv.CHAIN_APPROX_NONE)
print(" Number of the contours in the image: ",len(contours))
上圖的輸出:

現(xiàn)在我們將模糊圖像并查看輪廓的數(shù)量blur_img=cv.GaussianBlur(Org_img,(5,5),cv.BORDER_DEFAULT)
#if image has the pixel <150 then it will consider as the 0(black) and if >175 then it is consider as the 255(white)
blur_Canny=cv.Canny(blur_img,150,175)
cv2_imshow(blur_Canny)
# As we have the blur image edges as a Input to the findContours so the number of the contours is also decreases.
contours,hierarchies= cv.findContours(blur_Canny,cv.RETR_LIST,cv.CHAIN_APPROX_NONE)
print(" Number of the contours in the image: ",len(contours))
上述代碼的輸出:

通過觀察圖像和它的總輪廓,我們知道模糊圖像中的輪廓數(shù)量比原始圖像少,F(xiàn)在我們將嘗試在空白圖像上繪制圖像的輪廓cv2_imshow(Canny_img)
contours,hierarchies= cv.findContours(Canny_img,cv.RETR_LIST,cv.CHAIN_APPROX_SIMPLE)
print(len(contours))
print(len(hierarchies))
Blank_contours=np.zeros((600,600,3),dtype='uint8')
print(" Plotting the Countours on the blank")
cv.drawContours(Blank_contours,contours,-1,(0,0,255),1)
cv2_imshow(Blank_contours)
上述代碼的輸出:

在空白圖像上繪制輪廓:

1  2  3  下一頁(yè)>  
聲明: 本文由入駐維科號(hào)的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場(chǎng)。如有侵權(quán)或其他問題,請(qǐng)聯(lián)系舉報(bào)。

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字

您提交的評(píng)論過于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無(wú)評(píng)論

暫無(wú)評(píng)論

    人工智能 獵頭職位 更多
    掃碼關(guān)注公眾號(hào)
    OFweek人工智能網(wǎng)
    獲取更多精彩內(nèi)容
    文章糾錯(cuò)
    x
    *文字標(biāo)題:
    *糾錯(cuò)內(nèi)容:
    聯(lián)系郵箱:
    *驗(yàn) 證 碼:

    粵公網(wǎng)安備 44030502002758號(hào)