1. 程式人生 > >二十 形態學操作

二十 形態學操作

windows 改變 nes 特點 .com div pre code element

介紹

形態學操作其實就是改變物體的形狀,比如腐蝕就是”變瘦”,膨脹就是”變胖”,看下圖就明白了

形態學操作一般作用於二值化圖,來連接相鄰的元素或分離成獨立的元素。腐蝕和膨脹是針對圖片中的白色部分!

主要是應用在二值圖像分析中,灰度圖像亦可。

可以看做膨脹是將白色區域擴大,腐蝕是將黑色區域擴大

一、膨脹與腐蝕

相關函數

def getStructuringElement(shape, ksize, anchor=None): # real signature unknown; restored from __doc__

第一個參數shape:表示內核的形狀,有三種形狀可以選擇

矩形:MORPH_RECT; 交叉形:MORPH_CORSS; 橢圓形:MORPH_ELLIPSE;

第二個參數ksize:是內核的尺寸(n,n)

第三個參數anchor:錨點的位置

getStructuringElement函數會返回指定形狀和尺寸的結構元素。

1、腐蝕erode

腐蝕的效果是把圖片”變瘦”,其原理是在原圖的小區域內取局部最小值。因為是二值化圖,只有0和255,所以小區域內有一個是0該像素點就為0,這樣原圖中邊緣地方就會變成0,達到了瘦身目的。

OpenCV中用cv2.erode()函數進行腐蝕,只需要指定核的大小就行:

img = cv2.imread(j.bmp, 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel)  #
腐蝕

這個核也叫結構元素,因為形態學操作其實也是應用卷積來實現的。結構元素可以是矩形/橢圓/十字形,可以用cv2.getStructuringElement()來生成不同形狀的結構元素,比如:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 矩形結構
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))  # 橢圓結構
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))  # 十字形結構

代碼實現

 1 import cv2 as cv
 2 import numpy as np
 3 
 4 def erode_image(image):
 5     print(image.shape)
 6     gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
 7     ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU) #大律法獲取二值圖像
 8     cv.imshow(binary,binary)
 9     kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,3))  #可以修改卷積核大小來增加腐蝕效果,越大腐蝕越強
10     dst = cv.erode(binary,kernel)
11     cv.imshow(erode_demo,dst)
12 
13 img = cv.imread(1.jpg)
14 cv.imshow(input image,img)
15 erode_image(img)
16 cv.waitKeyEx(0)
17 cv.destroyAllWindows()

技術分享圖片技術分享圖片技術分享圖片

2、膨脹dilate

膨脹與腐蝕相反,取的是局部最大值,效果是把圖片”變胖”:

dilation = cv2.dilate(img, kernel)  # 膨脹

代碼實現

 1 import cv2 as cv
 2 import numpy as np
 3 
 4 #膨脹就是白色部分變多
 5 def dilate_image(image):
 6     print(image.shape)
 7     gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
 8     ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU) #大律法獲取二值圖像
 9     cv.imshow(binary,binary)
10     kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,3))  #可以修改卷積核大小來增加腐蝕效果,越大膨脹越強
11     dst = cv.dilate(binary,kernel)
12     cv.imshow(dilate_demo,dst)
13 
14 img = cv.imread(1.jpg)
15 cv.imshow(input image,img)
16 dilate_image(img)
17 cv.waitKeyEx(0)
18 cv.destroyAllWindows()

技術分享圖片技術分享圖片技術分享圖片

3、可以不進行灰度處理,對彩色圖片進行處理

(1)膨脹

kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
dst = cv.dilate(src,kernel)
cv.imshow("result",dst)

技術分享圖片

(2)腐蝕

kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
dst = cv.erode(src,kernel)
cv.imshow("result",dst)

技術分享圖片

二、開閉運算

1、開

先腐蝕後膨脹叫開運算(因為先腐蝕會分開物體,這樣容易記住),其作用是:分離物體,消除小區域。

特點:消除噪點,去除小的幹擾塊,而不影響原來的圖像

這類形態學操作用cv2.morphologyEx()函數實現:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 定義結構元素
img = cv2.imread(j_noise_out.bmp, 0)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)  # 開運算

代碼實現

 1 import cv2 as cv
 2 import numpy as np
 3 
 4 def camp(val1,val2):
 5     pv = val1 + val2
 6     if pv > 255:
 7         return 255
 8     elif pv < 0:
 9         return 0
10     else:
11         return pv
12 
13 def open_demo(image):
14     gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)     #(h,w) = (576,1024)
15     print(gray.shape)
16     for i in range(1000):
17         h = np.random.random_integers(0,gray.shape[0]-1)    #因為返回的是閉區間內的隨機整數,h是從0開始的,所以要減1
18         w = np.random.random_integers(0,gray.shape[1]-1)
19         value = np.random.random_integers(0,255)        #隨機添加的像素值
20         gray[h,w] = camp(gray[h,w],value)
21     ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
22     cv.imshow(binary,binary)
23     kernel = cv.getStructuringElement(cv.MORPH_RECT,(3,3))
24     open = cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)     #開操作,先腐蝕後膨脹,會消除一些為1的白色噪點
25     cv.imshow(open_demo,binary)
26 
27 img = cv.imread(1.jpg)
28 cv.imshow(input image,img)
29 open_demo(img)
30 cv.waitKey(0)
31 cv.destroyAllWindows()

技術分享圖片技術分享圖片

技術分享圖片

2、閉

閉運算則相反:先膨脹後腐蝕(先膨脹會使白色的部分擴張,以至於消除/“閉合”物體裏面的小黑洞,所以叫閉運算)

img = cv2.imread(j_noise_in.bmp, 0)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)  # 閉運算

代碼實現

技術分享圖片

如果我們的目標物體外面有很多無關的小區域,就用開運算去除掉;如果物體內部有很多小黑洞,就用閉運算填充掉

二十 形態學操作