日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV与图像处理学习六——图像形态学操作:腐蚀、膨胀、开、闭运算、形态学梯度、顶帽和黑帽

發(fā)布時(shí)間:2024/7/23 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV与图像处理学习六——图像形态学操作:腐蚀、膨胀、开、闭运算、形态学梯度、顶帽和黑帽 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

OpenCV與圖像處理學(xué)習(xí)六——圖像形態(tài)學(xué)操作:腐蝕、膨脹、開、閉運(yùn)算、形態(tài)學(xué)梯度、頂帽和黑帽

  • 四、圖像形態(tài)學(xué)操作
    • 4.1 腐蝕和膨脹
      • 4.1.1 圖像腐蝕
      • 4.1.2 圖像膨脹
    • 4.2 開運(yùn)算與閉運(yùn)算
      • 4.2.1 開運(yùn)算
      • 4.2.2 閉運(yùn)算
    • 4.3 形態(tài)學(xué)梯度(Gradient)
    • 4.4頂帽和黑帽

有關(guān)圖像處理前三次的筆記:
OpenCV與圖像處理學(xué)習(xí)三——圖像基本操作(1)
OpenCV與圖像處理學(xué)習(xí)四——圖像基本操作(2)
OpenCV與圖像處理學(xué)習(xí)五——圖像基本操作(3)

這是有關(guān)圖像基本操作的最后一次筆記,有關(guān)圖像形態(tài)學(xué)操作。

四、圖像形態(tài)學(xué)操作

形態(tài)學(xué),是圖像處理中應(yīng)用最為廣泛的技術(shù)之一,主要用于從圖像中提取對(duì)表達(dá)和描繪區(qū)域形狀有意義的圖像分量,使后續(xù)的識(shí)別工作能夠抓住目標(biāo)對(duì)象最為本質(zhì)的形狀特征,如邊界和連通區(qū)域等。

下面會(huì)經(jīng)常用到一個(gè)概念,這里先進(jìn)行說(shuō)明:

結(jié)構(gòu)元素:設(shè)有兩幅圖像B,X,若X是被處理的對(duì)象,而B是用來(lái)處理X的,則B稱為結(jié)構(gòu)元素(structure element),又被形象地稱作刷子。結(jié)構(gòu)元素通常都是一些比較小的圖像。

下面將介紹形態(tài)學(xué)的幾種常用操作:腐蝕、膨脹、開運(yùn)算和閉運(yùn)算等。

4.1 腐蝕和膨脹

圖像的膨脹(Dilation)和腐蝕(Erosion)是兩種基本的形態(tài)學(xué)運(yùn)算,其中膨脹類似于“領(lǐng)域擴(kuò)張”,將圖像中的白色部分進(jìn)行擴(kuò)張,其運(yùn)行結(jié)果圖比原圖的白色區(qū)域更大;而腐蝕類似于“領(lǐng)域被蠶食”,將圖像中白色的部分進(jìn)行縮減細(xì)化,其運(yùn)行結(jié)果圖比原圖的白色區(qū)域更小。

4.1.1 圖像腐蝕

把結(jié)構(gòu)元素B平移a后得到Ba,若Ba包含于X,我們記下這個(gè)a點(diǎn),所有滿足上述條件的a點(diǎn)組成的集合稱作X被B腐蝕(Erosion)的結(jié)果。如下圖所示:

其中X是被處理的對(duì)象,B是結(jié)構(gòu)元素。對(duì)于任意一個(gè)在陰影部分的點(diǎn)a,Ba包含于X,所以X被B腐蝕的結(jié)果就是那個(gè)陰影部分。陰影部分在X的范圍之內(nèi),且比X小,就像X被剝掉了一層似的。


腐蝕后的結(jié)果如下圖黑色部分所示:

相較于原來(lái)的灰色部分,仿佛變瘦了。

OpenCV中的函數(shù)為:

dst = cv2.erode( src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] )

參數(shù)為:

  • src:輸入圖像,可以是灰度圖或彩色圖。
  • kernel:腐蝕操作的結(jié)構(gòu)元素,默認(rèn)為一個(gè)3×3的簡(jiǎn)單矩陣。
  • anchor:錨點(diǎn),默認(rèn)為結(jié)構(gòu)元素的中心。
  • iterations:腐蝕次數(shù),默認(rèn)為1。
  • 下面看個(gè)例子:

    import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('./image/morphology.png') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) kernel = np.ones((3, 3), np.uint8) erosion = cv2.erode(img, kernel, iterations = 1) plt.subplot(121), plt.imshow(img), plt.title('Original') plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(erosion), plt.title('erosion') plt.xticks([]), plt.yticks([]) plt.show()

    結(jié)果如下所示:

    若將結(jié)構(gòu)元素的尺寸擴(kuò)大到7,結(jié)果為:

    ps:在構(gòu)造結(jié)構(gòu)元素的時(shí)候,可以使用numpy,也可以使用OpenCV提供的函數(shù)cv2.getStructuringElement()

    函數(shù):

    retval = cv2.getStructuringElement( shape, ksize[, anchor] )

    參數(shù):

  • shape:結(jié)構(gòu)元素內(nèi)部的結(jié)構(gòu),有三種,分別是矩形、十字形和橢圓形:
  • ksize:結(jié)構(gòu)元素的尺寸。
  • anchor:錨點(diǎn)位置,默認(rèn)為中心位置。
  • 看一下例子:

    import numpy as np import cv2kernel = np.ones((5, 5), np.uint8) print(kernel) [[1 1 1 1 1][1 1 1 1 1][1 1 1 1 1][1 1 1 1 1][1 1 1 1 1]] kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (7,7)) print(kernel) [[0 0 0 1 0 0 0][0 0 0 1 0 0 0][0 0 0 1 0 0 0][1 1 1 1 1 1 1][0 0 0 1 0 0 0][0 0 0 1 0 0 0][0 0 0 1 0 0 0]] kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7)) print(kernel) [[0 0 0 1 0 0 0][0 1 1 1 1 1 0][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][0 1 1 1 1 1 0][0 0 0 1 0 0 0]] kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7)) print(kernel) [[1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1]]

    我們可以用非矩形的結(jié)構(gòu)元素來(lái)進(jìn)行腐蝕操作:

    #!/usr/bin/env python3 import cv2image = cv2.imread("./image/morphology.png") gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) cv2.imshow("Gray Image", gray)kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7)) eroded = cv2.erode(gray.copy(), kernel, 10) # eroded = cv2.erode(gray.copy(), None, 10)cv2.imshow("Eroded Image", eroded) cv2.waitKey(0) cv2.destroyAllWindows()


    也是可以達(dá)到一定效果的,但是比矩形的那種腐蝕程度低一些些,因?yàn)楫吘菇Y(jié)構(gòu)元素里多了一些0。

    4.1.2 圖像膨脹

    膨脹(dilation)可以看做是腐蝕的對(duì)偶運(yùn)算,其定義是:把結(jié)構(gòu)元素B平移后得到Ba,若Ba與X有交集,我們記下這個(gè)a點(diǎn)。所有滿足上述條件的a點(diǎn)組成的集合稱作X被B膨脹后的結(jié)果,如下圖所示:

    其中X是被處理的對(duì)象,B是結(jié)構(gòu)元素,對(duì)于任意一個(gè)在陰影部分的點(diǎn)a,Ba與X有交集,所以X被B膨脹后的結(jié)果就是那個(gè)陰影部分,陰影部分包括X所有范圍,就像是X膨脹了一圈似的。

    膨脹后的圖像,其中綠色是膨脹多出來(lái)的部分:

    在OpenCV中的函數(shù)為:

    dst = cv2.dilate( src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] )

    參數(shù):

  • src:輸入圖像,可以是灰度圖也可以是彩色圖。
  • kernel:膨脹運(yùn)算的結(jié)構(gòu)元素,默認(rèn)為一個(gè)3×3的簡(jiǎn)單矩陣。
  • anchor:同上。
  • iterations:同上。
  • 看個(gè)例子:

    import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('./image/morphology.png') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #kernel = np.ones((3,),np.uint8) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))dilation = cv2.dilate(img,kernel,iterations = 1) plt.subplot(121),plt.imshow(img),plt.title('origin') plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(dilation),plt.title('dilation') plt.xticks([]), plt.yticks([]) plt.show()

    結(jié)果為:

    若將運(yùn)算元素尺寸擴(kuò)大一點(diǎn),擴(kuò)大為11:

    原本斷開的地方或小孔都被填上了。

    4.2 開運(yùn)算與閉運(yùn)算

    4.2.1 開運(yùn)算

    開運(yùn)算 = 先腐蝕運(yùn)算,再膨脹運(yùn)算,看上去把細(xì)微連在一起的兩塊目標(biāo)分開了,開運(yùn)算的效果圖如下所示:

    開運(yùn)算對(duì)一些細(xì)微的小點(diǎn),小塊,細(xì)條等部分是可以消去的,因?yàn)橄雀g消去它們,導(dǎo)致它們消失了無(wú)法再通過(guò)膨脹變回來(lái),而一些比較大的塊通過(guò)腐蝕操作只是會(huì)變瘦一點(diǎn),不會(huì)被完全抹去,所以可以通過(guò)膨脹運(yùn)算變回來(lái),那么總的效果就是開運(yùn)算去除了這些孤立的小點(diǎn),細(xì)長(zhǎng)的小條。

    開運(yùn)算總結(jié):

  • 開運(yùn)算能夠去除孤立的小點(diǎn),毛刺和小條,而總的位置和形狀不變。
  • 開運(yùn)算是一個(gè)基于幾何運(yùn)算的濾波器。
  • 結(jié)構(gòu)元素大小的不同將導(dǎo)致濾波效果的不同。
  • 不同的結(jié)構(gòu)元素的選擇導(dǎo)致了不同的分割,即提取出不同的特征。
  • 開運(yùn)算和閉運(yùn)算都用如下函數(shù)來(lái)表示,這個(gè)函數(shù)是OpenCV中圖像形態(tài)學(xué)變化的通用函數(shù):

    dst = cv2.morphologyEx( src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] )

    參數(shù)如下所示:

  • src:輸入圖像,灰度圖或彩色圖均可。
  • op:形態(tài)學(xué)操作的類型,包括腐蝕、運(yùn)算、開運(yùn)算以及后面要提及的閉運(yùn)算、形態(tài)學(xué)梯度、頂帽、黑帽等類型。
  • kernel:結(jié)構(gòu)元素,可以使用cv2.getStructuringElement函數(shù)來(lái)定義。
  • anchor:錨點(diǎn)位置,一般都用中心位置。
  • iterations:腐蝕或膨脹的次數(shù)。
  • 下面看個(gè)例子:

    import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('./image/open.png') img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #kernel = np.ones((5,5),np.uint8) kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) plt.subplot(121), plt.imshow(img), plt.title('Original') plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(opening), plt.title('opening') plt.xticks([]), plt.yticks([]) plt.show()

    結(jié)果如下所示:

    一些細(xì)小的點(diǎn)被去除了很多,但是開運(yùn)算的結(jié)構(gòu)元素的尺寸很重要,太小可能去除效果不好,太大可能會(huì)得到不想要的結(jié)果,如將3改為9,結(jié)果將變?yōu)?#xff1a;

    所以調(diào)節(jié)這個(gè)參數(shù)還是很關(guān)鍵的。

    4.2.2 閉運(yùn)算

    閉運(yùn)算 = 先膨脹運(yùn)算,再腐蝕運(yùn)算,看上去將兩個(gè)細(xì)微連接的圖塊封閉在一起,閉運(yùn)算的效果圖如下圖所示:

    閉運(yùn)算總結(jié):

  • 閉運(yùn)算能夠填平小孔,彌合小縫隙,而總的位置和形狀不變。
  • 閉運(yùn)算是通過(guò)填充圖像的凹角來(lái)濾波圖像的。
  • 結(jié)構(gòu)元素大小的不同將導(dǎo)致濾波效果的不同。
  • 不同結(jié)構(gòu)元素的選擇導(dǎo)致了不同的分割。
  • 看個(gè)例子:

    import cv2 as cv import numpy as np import matplotlib.pyplot as plt img = cv.imread('./image/close.png') img = cv.cvtColor(img,cv.COLOR_BGR2RGB) # kernel = np.ones((5,5),np.uint8) kernel = np.ones((7, 7), np.uint8) closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel) plt.subplot(121), plt.imshow(img), plt.title('Original') plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(closing), plt.title('closing') plt.xticks([]), plt.yticks([]) plt.show()

    結(jié)果如下所示:

    一些小孔被填滿了。若把尺寸從7改為21,結(jié)果為:

    就有點(diǎn)過(guò)了,把不需要連接和填補(bǔ)的地方也給連接、填補(bǔ)了,所以要合理選擇參數(shù)。

    4.3 形態(tài)學(xué)梯度(Gradient)

  • 基礎(chǔ)梯度:基礎(chǔ)梯度是用膨脹后的圖像減去腐蝕后的圖像得到的差值圖像,也是OpenCV中支持的計(jì)算形態(tài)學(xué)梯度的方法,而此方法得到梯度又稱為基本梯度。
  • 內(nèi)部梯度:是用原圖減去腐蝕之后的圖像得到的差值圖像。
  • 外部梯度:圖形膨脹后再減去原來(lái)圖像得到的差值圖像。
  • 用cv2.morphologyEx函數(shù)可以實(shí)現(xiàn)基礎(chǔ)梯度操作,看下面這個(gè)例子:

    import cv2 as cv import numpy as np import matplotlib.pyplot as plt img = cv.imread('./image/morphology.png') img = cv.cvtColor(img, cv.COLOR_BGR2RGB) kernel = np.ones((3, 3), np.uint8) gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel) plt.subplot(121), plt.imshow(img), plt.title('Original') plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(gradient), plt.title('gradient') plt.xticks([]), plt.yticks([]) plt.show()

    結(jié)果如下所示:

    4.4頂帽和黑帽

    • 頂帽(Top Hat):原圖像與開運(yùn)算圖的差值,突出原圖像中比周圍亮的區(qū)域。
    • 黑帽(Black Hat):閉運(yùn)算圖與原圖的差值,突出原圖中比周圍暗的區(qū)域。

    看兩個(gè)例子:

    頂帽:

    import cv2 as cv import numpy as np import matplotlib.pyplot as plt img = cv.imread('./image/morphology.png') img = cv.cvtColor(img, cv.COLOR_BGR2RGB) kernel = np.ones((9, 9), np.uint8) tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel) plt.subplot(121), plt.imshow(img), plt.title('Original') plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(tophat), plt.title('tophat') plt.xticks([]), plt.yticks([]) plt.show()

    結(jié)果為:

    黑帽:

    import cv2 as cv import numpy as np import matplotlib.pyplot as plt img = cv.imread('./image/morphology.png') img = cv.cvtColor(img, cv.COLOR_BGR2RGB) kernel = np.ones((9, 9), np.uint8) tophat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel) plt.subplot(121), plt.imshow(img), plt.title('Original') plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(tophat), plt.title('blackhat') plt.xticks([]), plt.yticks([]) plt.show()


    圖像處理之圖像基本操作的筆記就暫時(shí)到這里,后面將學(xué)習(xí)傳統(tǒng)方法進(jìn)行圖像分割,包括閾值分割、邊緣檢測(cè)算法、連通域分析以及一些其他區(qū)域生長(zhǎng)算法。

    總結(jié)

    以上是生活随笔為你收集整理的OpenCV与图像处理学习六——图像形态学操作:腐蚀、膨胀、开、闭运算、形态学梯度、顶帽和黑帽的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。