訂閱
糾錯
加入自媒體

OpenCV 指南2:如何在圖像中進行邊緣檢測?

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

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

我們思考的問題是:

如何在圖像中進行邊緣檢測?

如何在圖像中進行輪廓檢測?

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

如何處理顏色通道?

如何模糊圖像?

如何使用位運算符?

如何在圖像的每個像素點繪制顏色的直方圖?

1)如何在圖像中進行邊緣檢測?

1.1. Canny:對于這里的邊緣檢測,我們將使用 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)在我們將嘗試通過使其模糊來找到原始圖像的邊緣。博客中進一步介紹了如何使圖像模糊。

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

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

其中 ksize:用于計算二階導(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)
上述代碼的輸出:拉普拉斯邊緣檢測:

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

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

Sobel 邊緣檢測的代碼:#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 腐蝕它對于去除小的白噪聲很有用。用于分離兩個連接的對象等。怎么運作:內(nèi)核(奇數(shù)大小的矩陣(3,5,7)與圖像卷積。僅當(dāng)內(nèi)核下的所有像素都為 1 時,原始圖像中的像素(1 或 0)才會被視為 1,否則它會被腐蝕(使其為零)。因此,根據(jù)內(nèi)核的大小,將丟棄邊界附近的所有像素。因此,前景對象的厚度或大小會減少,或者只是圖像中的白色區(qū)域會減少。1.4.2 膨脹:在去除噪聲等情況下,腐蝕之后是膨脹。因為,腐蝕去除了白噪聲,但它也縮小了我們的對象。所以我們膨脹它。由于噪音消失了,它們不會回來,但我們的對象區(qū)域會增加。它也可用于連接對象的損壞部分。這個怎么運作:內(nèi)核(奇數(shù)大小的矩陣(3,5,7)與圖像卷積如果內(nèi)核下至少有一個像素為“1”,則原始圖像中的像素元素為“1”。它增加了圖像中的白色區(qū)域或前景對象的大小增加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 : 它會增加邊緣的厚度

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

2)如何在圖像中進行輪廓檢測?

有時,如果我們對圖像執(zhí)行邊緣檢測和輪廓檢測,則兩者的輸出可能看起來相似。但與邊緣檢測相比,輪廓檢測通常會更詳細(xì)。cv.findContours 函數(shù)中的一些重要參數(shù)是:Image :輸入圖像應(yīng)該是二進制作為源,一個8位的單通道圖像。非零像素被視為 1。零像素保持 0,因此圖像被視為二進制。輪廓檢索模式:1)cv.RETR_TREE →它將給出圖像中的分層輪廓。cv.RETR_EXTERNAL →它將給出圖像中唯一的外部輪廓。cv.RETR_LIST →它將給出圖像中存在的所有輪廓。輪廓逼近方法:1)CHAIN_APPROX_NONE →它將給出圖像中存在的所有計數(shù)器。2)CHAIN_APPROX_SIMPLE →它將給出圖像中的重要輪廓,例如,如果我們有線,它只會給出圖像中的起點和終點,而在 CHAIN_APPROX_NONE 的情況下,我們得到所有點,F(xiàn)在讓我們來看看它實際上是如何工作的。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ù)量比原始圖像少。現(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  下一頁>  
聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

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

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