計(jì)算機(jī)視覺(開運(yùn)算和閉運(yùn)算)

conv_cover.jpeg

開運(yùn)算和閉運(yùn)算

腐蝕和膨脹是開運(yùn)算和閉運(yùn)算的基礎(chǔ),先腐蝕然后膨脹就是開運(yùn)算,而先膨脹然后腐蝕就是閉運(yùn)算。

開運(yùn)算

先腐蝕后膨脹的過程為開運(yùn)算 I \circ S = (I \ominus S) \oplus S,看上去把細(xì)微連在一起的兩塊目標(biāo)分開了。下面圖中說明已經(jīng)足夠詳細(xì)來說明開運(yùn)算。

erode_dilate.png

對(duì)于開運(yùn)算還有一個(gè)很重要的作用,就是消除暗背景下的較亮區(qū)域,目的是在不改變黑色臺(tái)球面積的情況下,消除球上的白色環(huán)形區(qū)域。

def erode_dilate():
    I = cv2.imread("images/eight_ball.jpeg",0)
    # 結(jié)構(gòu)元半徑
    cv2.imshow("I",I)
    r = 1
    i = 1
    MAX_R,MAX_I = 20,20
    cv2.namedWindow("morphology",1)
    def nothing(*arg):
        pass
    cv2.createTrackbar("r","morphology",r,MAX_R,nothing)
    cv2.createTrackbar("i","morphology",i,MAX_I,nothing)
    while(True):
        # 顯示原圖
        r = cv2.getTrackbarPos('r','morphology')
        i = cv2.getTrackbarPos('i','morphology')
        print(r)
        s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*r + 1,2*r+1))
        d = cv2.morphologyEx(I,cv2.MORPH_OPEN,s,iterations=i)
        cv2.imshow("morphology",d)
        k = cv2.waitKey(5)
        if k==27:
            break
    cv2.destroyAllWindows()

這個(gè)函數(shù)的第一個(gè)參數(shù)表示內(nèi)核的形狀,有三種形狀可以選擇。

  • 矩形:MORPH_RECT;
  • 交叉形:MORPH_CROSS;
  • 橢圓形:MORPH_ELLIPSE;

第二和第三個(gè)參數(shù)分別是內(nèi)核的尺寸以及錨點(diǎn)的位置。一般在調(diào)用erode以及dilate函數(shù)之前,先定義一個(gè)Mat類型的變量來獲得

getStructuringElement 函數(shù)的返回值: 對(duì)于錨點(diǎn)的位置,有默認(rèn)值Point(-1,-1),表示錨點(diǎn)位于中心點(diǎn)。element 形狀唯一依賴錨點(diǎn)位置,其他情況下,錨點(diǎn)只是影響了形態(tài)學(xué)運(yùn)算結(jié)果的偏移。

代碼:

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11))
eight_ball.jpeg
屏幕快照 2019-12-27 下午9.15.36.png
屏幕快照 2019-12-27 下午9.16.14.png

閉運(yùn)算

與開運(yùn)算的操作相反,閉運(yùn)算是對(duì)圖像先膨脹后腐蝕。先膨脹,再腐蝕,可清除小黑點(diǎn)。


dilate_erode.png

I \bullet S = (I \oplus S) \ominus S

目的是去掉所有骰子上的黑色區(qū)域。同樣知道膨脹操作可以消除黑色,但是如果是膨脹會(huì)增大骰子的面積,而閉運(yùn)算恰恰可以避免這一點(diǎn),消除黑色同時(shí)不會(huì)改變骰子的面積。

def erode_dilate():
    I = cv2.imread("images/toss_die.jpeg",0)
    # 結(jié)構(gòu)元半徑
    cv2.imshow("I",I)
    r = 1
    i = 1
    MAX_R,MAX_I = 20,20
    cv2.namedWindow("morphology",1)
    def nothing(*arg):
        pass
    cv2.createTrackbar("r","morphology",r,MAX_R,nothing)
    cv2.createTrackbar("i","morphology",i,MAX_I,nothing)
    while(True):
        # 顯示原圖
        r = cv2.getTrackbarPos('r','morphology')
        i = cv2.getTrackbarPos('i','morphology')
        print(r)
        s = cv2.getStructuringElement(cv2.MORPH_RECT,(2*r + 1,2*r+1))
        d = cv2.morphologyEx(I,cv2.MORPH_CLOSE,s,iterations=i)
        cv2.imshow("morphology",d)
        k = cv2.waitKey(5)
        if k==27:
            break
    cv2.destroyAllWindows()
toss_die.jpeg
屏幕快照 2019-12-27 下午9.28.12.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容