天天看點

opencv中的形态學操作形态學操作

形态學操作

1 連通性

在圖像中,最小的機關是像素,每個像素周圍有8各鄰接像素,常見的鄰接關系有3種:4鄰接、8鄰接和D鄰接。分别如下圖所示:

opencv中的形态學操作形态學操作
  • 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腐蝕後:

opencv中的形态學操作形态學操作

​ 腐蝕的作用是消除物體邊界點,使目标縮小,可以消除小于結構元素的噪聲點。

​ API:

cv.erode(img,kernel,iterations)

​ 參數:

​ * img:要處理的圖像

​ * kernel:核結構(上圖結構B)

​ * iterations:腐蝕的次數,預設是1

​ 2.膨脹

​ 具體操作是∶用一個結構元素掃描圖像中的每一個像羹,用結構元素中的每一個像素與其覆寫的像素做 “與"操作,如果都為0,則該像素為0,否則為1。如下圖所示,結構A被結構B腐蝕後:

opencv中的形态學操作形态學操作

​ 膨脹的作用是将與物體接觸的所有背景點合并到物體中,使目标增大,可填補目标中的孔洞。

​ 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.禮帽運算

​ 原圖像與**“開運算“的結果圖**之差,如下式計算:

opencv中的形态學操作形态學操作

​ 因為開運算帶來的結果是放大了裂縫或者局部低亮度的區域,是以,從原圖中減去開運算後的圖,得到的效果圖突出了比原圖輪廓周圍的區域更明亮的區域,且這一操作和選擇的核的大小相關。

​ 禮帽運算用來分離比鄰近點亮一些的斑塊。當一幅圖像具有大幅的背景的時候,而微小物品比較有規律的情況下,可以使用頂帽運算進行背景提取。

2.黑帽運算

​ “閉運算“的結果圖與原圖像之差,如下式計算:

opencv中的形态學操作形态學操作

​ 黑帽運算後的效果圖突出了比原圖輪廓周圍的區域更暗的區域,且這一操作和選擇的核的大小相關。

​ 黑帽運算用來分離比鄰近點暗一些的斑塊。

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站黑馬程式員視訊,點選跳轉

繼續閱讀