数字图像处理——第九章 形态学图像处理
數字圖像處理——第9章 形態學圖像處理
文章目錄
- 數字圖像處理——第9章 形態學圖像處理
- 1 基礎知識
- 1.1 形態學圖像
- 1.2 二值圖像
- 2 腐蝕和膨脹
- 2.1 腐蝕
- 2.2 膨脹
- 3 開操作與閉操作
- 3.1 開操作
- 3.2 閉操作
- 3.3 實驗對比
- 4 一些基本的形態學算法
- 4.1 邊界提取
- 4.2 空洞填充
- 4.3 凸殼
1 基礎知識
1.1 形態學圖像
形態學通常指的是生物學的某個分支,常用來處理動物和植物的形狀和結構。現在,我們也將這個詞用于圖像處理中。形態學圖像處理就是使用數學形態學的基本運算,由計算機對圖像進行分析,以達到所需結果的一種技術。通俗理解,形態學操作其實就是改變物體的形態。
1.2 二值圖像
為啥會形態學會提到二值圖像,因為形態學操作一般作用于二值圖像。所以繼續復習下二值圖像。二值圖像(Binary Image)是指將圖像上的每一個像素只有兩種可能的取值或灰度等級狀態。具體來說,二值圖像是指在圖像中,灰度等級只有兩種,也就是說,圖像中的任何像素點的灰度值均為0或者255,分別代表黑色和白色。舉個例子,首先我們需要讀取一張灰度圖,然后將設定一個全1的矩陣,然后設定閾值,即二值化的閾值,例如177,則原圖像素值大于177的置為1,小于177則置為0。
代碼如下:
import cv2
import numpy as np
import matplotlib.pyplot as pltimg = cv2.imread(' ',0)
param = 177
img_2 = np.ones(img.shape[0:2])
img_2[img<177] = 0
plt.figure(dpi = 150)
plt.subplot(121)
plt.title("Gray Scale Image")
plt.imshow(img, cmap = 'gray')
plt.subplot(122)
plt.title("Binary Image")
plt.imshow(img_2, cmap = 'gray')
plt.tight_layout()
plt.show()
2 腐蝕和膨脹
現有一個結構元素的概念
- 設有兩幅圖象B,X。若X是被處理的對象,而B是用來處理X的,則稱B為結構元素(structure element),又被形象地稱做刷子。結構元素通常都是一些比較小的圖象。
2.1 腐蝕
把結構元素B平移a后得到Ba,若Ba包含于X,我們記下這個a點,所有滿足上述條件的a點組成的集合稱做X被B腐蝕(Erosion)的結果。如下圖所示:
其中X是被處理的對象,B是結構元素。對于任意一個在陰影部分的點a,Ba 包含于X,所以X被B腐蝕的結果就是那個陰影部分。陰影部分在X的范圍之內,可以看出比之前的X要小了,被撕了一層似的,是將圖像中的目標進行細化的操作。opencv中已有現成的腐蝕庫供調用,實驗效果如下:
實驗分析:腐蝕之后的圖像通俗理解會變細,且隨著濾波器的大小改變。當濾波器的尺寸越大,則腐蝕效果越強,圖像就變得越細;弱濾波器的大小較小,則腐蝕效果較弱。腐蝕將圖像中的高亮區域或白色部分進行縮減細化,其運行結果圖比原圖的高亮區域更小。
代碼如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt# 將圖片轉成二值圖像
def img2binary_img(img):param = 177binary_img = np.ones(img.shape[0:2])binary_img[img<177] = 0return binary_img
# 執行腐蝕操作
def img_erode(binary, kernel_size):#可以修改卷積核大小來增加腐蝕效果,越大腐蝕越強kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(kernel_size,kernel_size))dst = cv2.erode(binary,kernel)return dst
img = cv2.imread(' ',0)
binary_img = img2binary_img(img)
erode_img_5 = img_erode(binary_img, 5)
erode_img_7 = img_erode(binary_img, 7)
erode_img_9 = img_erode(binary_img, 9)plt.figure(dpi = 120)
plt.subplot(221)
plt.title("Binary Image")
plt.imshow(binary_img, cmap = 'gray')
plt.subplot(222)
plt.title("Erode Image(kernel_size = 5)")
plt.imshow(erode_img_5, cmap = 'gray')
plt.subplot(223)
plt.title("Erode Image(kernel_size = 7)")
plt.imshow(erode_img_7, cmap = 'gray')
plt.subplot(224)
plt.title("Erode Image(kernel_size = 9)")
plt.imshow(erode_img_9, cmap = 'gray')
plt.tight_layout()
plt.show()
2.2 膨脹
膨脹(dilation)可以看做是腐蝕的對偶運算,其定義是:把結構元素B平移a后得到Ba,若Ba擊中X,我們記下這個a點。所有滿足上述條件的a點組成的集合稱做X被B膨脹的結果。如下圖所示。
其中X是被處理的對象,B是結構元素,不難知道,對于任意一個在陰影部分的點a,Ba擊中X,所以X被B膨脹的結果就是那個陰影部分。陰影部分包括X的所有范圍,就象X膨脹了一圈似的。同樣用python-opencv處理。
代碼如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt# 將圖片轉成二值圖像
def img2binary_img(img):param = 177binary_img = np.ones(img.shape[0:2])binary_img[img<177] = 0return binary_img
# 執行膨脹操作
def img_dilate(binary, kernel_size):#可以修改卷積核大小來增加膨脹效果,越大膨脹越強kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(kernel_size,kernel_size))dst = cv2.dilate(binary,kernel)return dst
img = cv2.imread(' ',0)
binary_img = img2binary_img(img)
erode_img_5 = img_dilate(binary_img, 5)
erode_img_7 = img_dilate(binary_img, 7)
erode_img_9 = img_dilate(binary_img, 9)plt.figure(dpi = 120)
plt.subplot(221)
plt.title("Binary Image")
plt.imshow(binary_img, cmap = 'gray')
plt.subplot(222)
plt.title("Dilate Image(kernel_size = 5)")
plt.imshow(erode_img_5, cmap = 'gray')
plt.subplot(223)
plt.title("Dilate Image(kernel_size = 7)")
plt.imshow(erode_img_7, cmap = 'gray')
plt.subplot(224)
plt.title("Dilate Image(kernel_size = 9)")
plt.imshow(erode_img_9, cmap = 'gray')
plt.tight_layout()
plt.show()
實驗分析:圖像膨脹是腐蝕操作的逆操作,類似于“領域擴張”,將圖像中的高亮區域或白色部分進行擴張,其運行結果圖比原圖的高亮區域更大,線條變粗了,主要用于去噪。同時圖像被腐蝕后,去除了噪聲,但是會壓縮圖像。且對腐蝕過的圖像,進行膨脹處理,可以去除噪聲,并且保持原有形狀。
3 開操作與閉操作
開操作閉操作簡稱開閉運算,即開操作=開運算;閉操作=閉運算。說白了就是打腐蝕和膨脹的組合拳。 **為什么有了膨脹、腐蝕還要開運算閉運算呢?**其實開閉運算最重要的一點就是,可以保持物體原有大小。然后一個是消除物體外部噪聲(開運算)的另一個是增強物體之間連接點(閉運算)的。
3.1 開操作
開運算 = 先腐蝕運算,再膨脹運算
開運算如下圖所示:
3.2 閉操作
閉運算 = 先膨脹運算,再腐蝕運算
閉運算如下圖所示:
3.3 實驗對比
可用opencv中cv2.morphologyEx函數實現開閉運算,cv2.morphologyEx(src, op, kernel) 可進行各類形態學的變化。參數說明:
- src傳入的圖片
- op進行變化的方式
- kernel表示方框的大小
op = cv2.MORPH_OPEN 進行開運算,指的是先進行腐蝕操作,再進行膨脹操作
op = cv2.MORPH_CLOSE 進行閉運算, 指的是先進行膨脹操作,再進行腐蝕操作
實驗效果如下:
實驗總結(開運算):
(1)開運算能夠除去孤立的小點,毛刺和小橋,而總的位置和形狀不便。
(2)開運算是一個基于幾何運算的濾波器。
(3)結構元素大小的不同將導致濾波效果的不同。
(4)不同的結構元素的選擇導致了不同的分割,即提取出不同的特征。
代碼如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 將圖片轉成二值圖像
def img2binary_img(img):param = 177binary_img = np.ones(img.shape[0:2])binary_img[img<177] = 0return binary_img
img = cv2.imread(' ',0)
binary_img = img2binary_img(img)
kernel = np.ones((5,5),np.uint8)
open_img = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel)
close_img = cv2.morphologyEx(binary_img, cv2.MORPH_CLOSE, kernel)
plt.figure(dpi = 190)
plt.subplot(131)
plt.title("Binary Image")
plt.imshow(binary_img, cmap = 'gray')
plt.subplot(132)
plt.title("Opened Image")
plt.imshow(open_img, cmap = 'gray')
plt.subplot(133)
plt.title("Closed Image")
plt.imshow(close_img, cmap = 'gray')
plt.tight_layout()
plt.show()
實驗總結(閉運算):
(1)閉運算能夠填平小湖(即小孔),彌合小裂縫,而總的位置和形狀不變。
(2)閉運算是通過填充圖像的凹角來濾波圖像的。
(3)結構元素大小的不同將導致濾波效果的不同。
(4)不同結構元素的選擇導致了不同的分割。
4 一些基本的形態學算法
當處理二值圖像時,形態學的主要應用是提取表示和描述形狀的有用成分。特別是用形態學方法提取某一區域邊界線,連接成分,骨骼,凸殼的算法是十分有效的。此外,區域填充,細化,加粗,裁剪等處理方法也經常與上述算法相結合在預處理和后處理中使用。
4.1 邊界提取
這類似于邊緣檢測,之前學過的Canny邊緣檢測算法,使用opencv函數cv2.Canny可輕松實現邊緣提取:
代碼如下:
import cv2
img = cv2.imread(" ",0)
blurred = cv2.GaussianBlur(img,(11,11),0)
gaussImg = cv2.Canny(blurred, 10, 70)plt.figure(dpi = 130)
plt.subplot(121)
plt.title("Origin Image")
plt.imshow(img, cmap = 'gray')
plt.subplot(122)
plt.title("Canny Image")
plt.imshow(gaussImg, cmap = 'gray')
plt.tight_layout()
plt.show()
4.2 空洞填充
使用空洞填充,可以對圖像進行填充。使用函數為泛洪函數。原型為:cv2.floodFill(img, mask, seed, newvalue(BGR), (loDiff1, loDiff2, loDiff3), (upDiff1, upDiff2, upDiff3), flag)
- img:為待使用泛洪算法的圖像
- mask:為掩碼層,使用掩碼可以規定是在哪個區域使用該算法,如果是對于完整圖像都要使用,則掩碼層大小為原圖行數+2,列數+2.是一個二維的0矩陣,邊緣一圈會在使用算法是置為1。而只有對于掩碼層上對應為0的位置才能泛洪,所以掩碼層初始化為0矩陣。【dtype:np.uint8】
- seed:為泛洪算法的種子點,也是根據該點的像素判斷決定和其相近顏色的像素點,是否被泛洪處理。
- newvalue:是對于泛洪區域新賦的值(B,G,R)
- (loDiff1,loDiff2,loDiff3):是相對于seed種子點像素可以往下的像素值,即seed(B0,G0,R0),泛洪區域下界為(B0-loDiff1,G0-loDiff2,R0-loDiff3)
- (upDiff1,upDiff2,upDiff3):是相對于seed種子點像素可以往上的像素值,即seed(B0,G0,R0),泛洪區域上界為(B0+upDiff1,G0+upDiff2,R0+upDiff3)
- flag:為泛洪算法的處理模式。
如下圖所示使用泛洪函數簡單對彩色圖像進行填充:
代碼如下:
import cv2
import matplotlib.pyplot as pltimg = cv2.imread(' ')
im_floodfill = img.copy()
h, w = img.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
cv2.floodFill(im_floodfill, mask, (220, 250), (0, 255, 255), (100, 100, 100), (50, 50 ,50), cv2.FLOODFILL_FIXED_RANGE)
plt.figure(dpi = 190)
plt.subplot(131)
plt.title("Origin Image")
plt.imshow(img)
plt.subplot(132)
plt.title("FillHole Image")
plt.imshow(im_floodfill)
plt.tight_layout()
plt.show()
4.3 凸殼
凸殼在平面中是一種形狀,類比三個點的三角形,四個點的常見四邊形,橡皮筋的比喻很容易讓人認為凸殼是皮筋,實際是皮筋圍起來的區域。而且,凸殼通常被稱為最小凸多邊形(MCP,the minimum convex polygon)。二值圖像的凸殼指的是包圍輸入二值圖像白色區域的最小的凸多邊形的像素集合。可使用skimage庫實現。實現效果如下圖所示,有點外接多邊形的意思。
總結
以上是生活随笔為你收集整理的数字图像处理——第九章 形态学图像处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数字图像处理——第七章 小波和多分辨处理
- 下一篇: 数字图像处理——第十章 图像分割