形态學操作
1 連通性
在圖像中,最小的機關是像素,每個像素周圍有8各鄰接像素,常見的鄰接關系有3種:4鄰接、8鄰接和D鄰接。分别如下圖所示:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnLiJjM3QzMiFTYkFGZiNWZ4QWMzQjYkhTYhRzN4UTZyEzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
- 4鄰接:像素p(x,y)的4鄰域是:(x+1,y)、(x-1,y)、(x,y+1)、(x,y-1),用N4(P)表示像素p的4鄰接
- D鄰接:像素p(x,y)的D鄰域是:對角上的點:(x+1,y+1)、(x-1,y-1)、(x-1,y+1)、(x+1,y-1),用ND(P)表示像素p的D鄰接
- 8鄰接:像素p(x,y)的8鄰域是:4鄰域的點+D鄰域的點,用N8(p)表示p的8鄰域
連通性是描述區域和邊界的重要概念,兩個像素連通的兩個必要條件是:
1.兩個像素的位置是否相鄰
2.兩個像素的灰階值是否滿足特定的相似性準則(或者是否相等)
根據聯通性的定義,有4連通、8連通和m連通三種
- 4連通:對于具有值V的像素p和q,如果q在集合N4§中,則稱這兩個像素是4連通。
- 8連通∶對于具有值V的像素p和q,如果q在集合N8§中,則稱這兩個像素是8連通。
2形态學操作
形态學轉換是基于圖像形狀的一些簡單操作。它通常在二進制圖像上執行。腐蝕和膨脹是兩個基本的形态學運算符。然後它的變體形式如開運算,閉運算,禮帽黑帽等。
2.1腐蝕和膨脹
腐蝕和膨脹是最基本的形态學操作,腐蝕和膨脹都是針對白色部分(高亮部分)而言的。
膨脹就是使圖像中高亮部分擴張,效果圖擁有比原圖更大的高亮區域﹔腐蝕是原圖中的高亮區域被蠶食,效果圖擁有比原圖更小的高亮區域。膨脹是求局部最大值的操作,腐蝕是求局部最小值的操作。
1.腐蝕
具體操作是:用一個結構元素掃描圖像中的每一個像素,用結構元素中的每一個像素與其覆寫的像做“與"操 作,如果都為1,則該像素為1,否則為0。如下圖所示,結構A被結構B腐蝕後:
腐蝕的作用是消除物體邊界點,使目标縮小,可以消除小于結構元素的噪聲點。
API:
cv.erode(img,kernel,iterations)
參數:
* img:要處理的圖像
* kernel:核結構(上圖結構B)
* iterations:腐蝕的次數,預設是1
2.膨脹
具體操作是∶用一個結構元素掃描圖像中的每一個像羹,用結構元素中的每一個像素與其覆寫的像素做 “與"操作,如果都為0,則該像素為0,否則為1。如下圖所示,結構A被結構B腐蝕後:
膨脹的作用是将與物體接觸的所有背景點合并到物體中,使目标增大,可填補目标中的孔洞。
API:
cv.dilate(img,kernel,iterations)
參數:
* img:要處理的圖像
* kernel:核結構
* iterations:腐蝕的次數,預設是1
3.示例
使用一個5*5的卷積核實作腐蝕核膨脹的運算:
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread("../image/yy.jpg")
# 建立核結構
kernel = np.ones((5,5),np.uint8)
# 進行圖像的腐蝕和膨脹
erosion = cv.erode(img,kernel) #腐蝕
dilate = cv.dilate(img,kernel) #膨脹
plt.imshow(img[:,:,::-1])
plt.show() # 原圖
plt.imshow(erosion[:,:,::-1])
plt.show() # 腐蝕後結果
plt.imshow(dilate[:,:,::-1])
plt.show() # 膨脹後結果
2.2開閉運算
開運算和閉運算是将腐蝕和膨脹按照一定的次序進行處理。但這兩者并不是可逆的,即先開後閉并不能得到原來的圖像。
1.開運算
開運算是先腐蝕後膨脹,其作用是︰分離物體,消除小區域。特點︰消除噪點,去除小的幹擾塊,而不影響原來的圖像。
2.閉運算
閉運算與開運算相反,是先膨脹後腐蝕,作用是消除/"閉合"物體裡面的孔洞,特點︰可以填充閉合區域。
3.API
cv.morphologyEx(img,op,kernel)
參數:
* img:要處理的圖像
* op:處理方式:若進行開運算,則設為cv.MORPH_OPEN,若進行閉運算,則設為cv.MORPH_CLOSE
* Kernel:核結構(用來參照的,上述結構B)
4.示例
使用10*10的核結構對卷積進行開閉運算的實作。
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread("../image/yy.jpg")
# 建立核結構
kernel = np.ones((10,10),np.uint8)
#圖像的開閉運算
cvOPen = cv.morphologyEx(img,cv.MORPH_OPEN,kernel) #開運算
cvClose = cv.morphologyEx(img,cv.MORPH_CLOSE,kernel) #閉運算
#圖像展示
fig,axes=plt.subplots(nrows=1,ncols=3,figsize=(10,8))
axes[0].imshow(img[:,:,::-1]), axes[0].set_title("原圖")
axes[1].imshow(cvOPen[:,:,::-1]), axes[1].set_title("開運算結果")
axes[2].imshow(cvClose[:,:,::-1]), axes[2].set_title("閉運算結果")
plt.show()
2.3 禮帽和黑帽
1.禮帽運算
原圖像與**“開運算“的結果圖**之差,如下式計算:
因為開運算帶來的結果是放大了裂縫或者局部低亮度的區域,是以,從原圖中減去開運算後的圖,得到的效果圖突出了比原圖輪廓周圍的區域更明亮的區域,且這一操作和選擇的核的大小相關。
禮帽運算用來分離比鄰近點亮一些的斑塊。當一幅圖像具有大幅的背景的時候,而微小物品比較有規律的情況下,可以使用頂帽運算進行背景提取。
2.黑帽運算
“閉運算“的結果圖與原圖像之差,如下式計算:
黑帽運算後的效果圖突出了比原圖輪廓周圍的區域更暗的區域,且這一操作和選擇的核的大小相關。
黑帽運算用來分離比鄰近點暗一些的斑塊。
3.API
cv.morphologyEx(img,op,kernel)
參數:
- img:要處理的圖像
- op:處理方式:若進行開運算
- 閉運算:cv.MORPH_CLOSE
- 開運算:cv.MORPH_OPEN
- 禮帽運算:cv.MORPH_TOPHAT
- 黑帽運算:cv.MORPH_BLACKHAT
- Kernel:核結構(用來參照的,上上述結構B)
2.4 總結
1.鄰接關系:4鄰接,8鄰接和D鄰接
連通性:4連通,8連通和m連通
2.形态學操作
-
腐蝕和膨脹∶
腐蝕:求局部最大值
膨脹:求局部最小值
-
開閉運算:
開:先腐蝕後膨脹
閉:先膨脹後腐蝕
-
禮帽和黑帽:
禮帽:原圖像與開運算之差
黑帽:閉運算與原圖像之差
注:以上資料來自b站黑馬程式員視訊,點選跳轉