【python-opencv】17-形態學操作-腐蝕與膨脹


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

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

腐蝕

腐蝕的效果是把圖片"變瘦",其原理是在原圖的小區域內取局部最小值。因為是二值化圖,只有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))  # 十字形結構

膨脹

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

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

開/閉運算

先腐蝕(瘦)后膨脹(胖)叫開運算(因為先腐蝕會分開物體,這樣容易記住),其作用是:分離物體,消除小區域。這類形態學操作用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)  # 開運算

def open_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
    # kernel = np.ones((5,5),np.uint16)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
    dst = cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)
    cv.imshow("open_demo",dst)

 

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

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

def close_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    # kernel = np.ones((5,5),np.uint16)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
    dst = cv.morphologyEx(binary,cv.MORPH_CLOSE,kernel)
    cv.imshow("close_demo",dst)

 

經驗之談很多人對開閉運算的作用不是很清楚,看上圖↑: 如果我們的目標物體外面有很多無關的小區域,就用開運算去除掉; 如果物體內部有很多小黑洞,就用閉運算填充掉。
開操作去掉外部小的干擾,用腐蝕也能做到,二者的區別在於開操作只去掉外部小的干擾而保留了其他部分不變

其他形態學操作

  • 形態學梯度:膨脹圖減去腐蝕圖,dilation - erosion,這樣會得到物體的輪廓:
img = cv2.imread('school.bmp', 0)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

  • 頂帽(tophat)原圖減去開操作后的圖:src - opening
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
  • 黑帽(blackhat):閉運算圖像與原圖像差值:closing - src
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

 

def tophat_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    # kernel = np.ones((5,5),np.uint16)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
    dst = cv.morphologyEx(gray, cv.MORPH_GRADIENT, kernel)
    # dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)
    """給dst圖像添加亮度"""
    # cimage = np.array(gray.shape,np.uint8)
    # cimage = 120
    # dst = cv.add(dst,cimage)
    cv.imshow("MORPH_GRADIENT_demo", dst)

 

Binary二值圖進行腐蝕 膨脹等形態學操作

 

def erode_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
    # kernel = np.ones((5,5),np.uint16)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
    dst = cv.erode(binary,kernel=kernel)
    cv.imshow("erode_demo",dst)

def dilate_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
    ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    # kernel = np.ones((5,5),np.uint16)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
    dst = cv.dilate(binary,kernel=kernel)
    cv.imshow("dilate_demo",dst)

 

 

BGR原圖直接進行腐蝕 膨脹等形態學操作

"""BGR圖像直接進行腐蝕 膨脹"""
src0 = cv.imread('beauty1.jpg')
cv.imshow('input_image',src0)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
dilate_dst = cv.dilate(src0,kernel=kernel)
cv.imshow("dilate_dst",dilate_dst)
erode_dst = cv.erode(src0,kernel=kernel)
cv.imshow("erode_dst",erode_dst)

 

 參考:

https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops

https://www.jianshu.com/p/05ef50ac89ac

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM