影像形態學主要從影像內提取分量資訊,該分量資訊通常對表達影像的特征具有重要意義,例如,在車牌號碼識別中,能夠使用形態學計算其重要特征資訊,在進行識別時,只需對這些特征資訊運算即可,影像形態學在目標視覺檢測、醫學影像處理、資訊壓縮提取等領域都有重要的應用,接下來,這篇隨筆介紹使用OpenCV進行影像處理的第七章 影像形態學操作,
7 影像形態學操作
形態學操作主要包括:腐蝕、膨脹、開運算、閉運算、形態學梯度運算、頂帽運算(禮帽運算)、黑帽運算等操作,其中,腐蝕和膨脹是形態學中最基本的運算,其他方法都是基于這兩種運算組合而成的,
7.1 腐蝕
腐蝕是最基本的形態學操作之一,能夠消除影像中的邊界,使影像沿邊界向內收縮,
腐蝕時,有一個結構元逐個像素掃描原影像,根據結構元中心與原影像的關系來進行腐蝕,該結構元也被成為核,
核能夠自定義生成,也可以使用函式cv2.getStructuringElement()構造不同結構的核,該核函式的shape引數有多種,能夠生成不同的核,但相比于自定義核就稍有局限,所以本章內容全部默認基于自定義核,當然朋友們也可以嘗試使用cv2.getStructuringElement()核函式來構造特定結構的核,
在OpenCV中,使用cv2.erode()函式進行腐蝕操作,舉例程式如下:
1 #使用函式cv.erode()完成影像腐蝕 2 import cv2 3 import numpy as np 4 o=cv2.imread('E:\python_opencv/fushi.jpg',cv2.IMREAD_UNCHANGED) 5 kernel=np.ones((5,5),np.uint8) #核大小為5×5 6 erosion=cv2.erode(o,kernel) #使用kernel對原影像腐蝕 7 cv2.imshow('orriginal',o) 8 cv2.imshow('erosion',erosion) 9 cv2.waitKey() 10 cv2.destroyAllWindows()
在上面程式中,讀取圖片后先生成kernel結構元,是一個5×5大小且元素均為1的矩陣,再使用cv2.erode()函式進行腐蝕操作,運行結果如圖所示:


左圖是原始影像,右圖是腐蝕影像,可以看到,腐蝕操作能將圖片中的毛刺等腐蝕消掉,下面我們調節cv2.erode()函式的迭代次數,觀察不同kernel核對影像的腐蝕效果,程式如下所示:
1 #調節函式cv2.erode()的引數,觀察不同引數控制下的影像腐蝕效果 2 import cv2 3 import numpy as np 4 o=cv2.imread('E:\python_opencv/fushi.jpg',cv2.IMREAD_UNCHANGED) 5 kernel=np.ones((9,9),np.uint8) #核大小為9×9 6 #引數iteration等于5,是對cv2.erode()的迭代次數進行控制,讓其迭代5次 7 erosion=cv2.erode(o,kernel,iterations=5) 8 cv2.imshow('orriginal',o) 9 cv2.imshow('erosion',erosion) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為迭代5次后的腐蝕處理結果,影像已明顯向內收縮,


在這段代碼中,使用了更大的核、更多的迭代次數,所以影像被腐蝕的更嚴重了,
7.2 膨脹
膨脹操作是腐蝕的逆運算,能對影像從邊界處向外擴張,如果圖片中的兩個目標相距較近,膨脹后兩個目標可能會連通,膨脹操作經常應用在影像分割后的填充任務中,
影像膨脹也是使用一個kernel核,逐一對原影像素進行掃描,判斷它們的位置關系來實作的,
在OpenCV中,使用cv2.dilate()函式進行膨脹操作,舉例程式如下:
1 #使用函式cv2.dilate()完成影像膨脹操作 2 import cv2 3 import numpy as np 4 o=cv2.imread('E:\python_opencv/pengzhang.jpg',cv2.IMREAD_UNCHANGED) 5 kernel=np.ones((9,9),np.uint8) #核大小為9×9 6 dilation=cv2.dilate(o,kernel) #使用kernel對原影像膨脹 7 cv2.imshow('orriginal',o) 8 cv2.imshow('dilation',dilation) 9 cv2.waitKey() 10 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為影像膨脹處理結果,影像已由邊界處向外擴張,


下面我們調節cv2.dilate()函式的迭代次數,觀察不同kernel核對影像的腐蝕效果,代碼如下:
1 #調節函式cv2.dilate()的引數,觀察不同引數控制下的影像膨脹效果 2 import cv2 3 import numpy as np 4 o=cv2.imread('E:\python_opencv/pengzhang.jpg',cv2.IMREAD_UNCHANGED) 5 kernel=np.ones((5,5),np.uint8) #核大小為5×5 6 #引數iteration等于9,是對cv2.dilate()的迭代次數進行控制,迭代9次 7 dilation=cv2.dilate(o,kernel,iterations=9) 8 cv2.imshow('orriginal',o) 9 cv2.imshow('dilation',dilation) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為迭代9次后的膨脹處理結果,影像已明顯由邊界處向外擴張,


7.3 開運算
開運算是先將影像腐蝕,再對腐蝕后的結果進行膨脹,開運算常應用于影像去噪等,
OpenCV提供了形態學函式cv2.morphologyEx()來實作各種形態學運算,內部op引數如下:

所以,使用函式cv2.morphologyEx()實作開運算舉例代碼如下:
1 #使用函式cv2.morphologyEx()實作開運算 2 import cv2 3 import numpy as np 4 img=cv2.imread('E:\python_opencv/kaiyunsuan.jpg') 5 kernel=np.ones((20,20),np.uint8) 6 #cv2.morphologyEx()函式的op引數設定為cv2.MORPH_OPEN 7 rst=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel) 8 cv2.imshow('img',img) 9 cv2.imshow('rst',rst) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為開運算處理結果,影像兩個目標已斷開連接,

7.4 閉運算
閉運算是先將影像膨脹,再對膨脹后的結果進行腐蝕,閉運算常應用于去除影像上的小黑點、或者連接圖中多個相距較近的目標等,
使用函式cv2.morphologyEx()實作閉運算,舉例代碼如下:
1 #使用函式cv2.morphologyEx()實作閉運算 2 import cv2 3 import numpy as np 4 img=cv2.imread('E:\python_opencv/biyunsuan.jpg') 5 kernel=np.ones((10,10),np.uint8) 6 #cv2.morphologyEx()函式的op引數設定為cv2.MORPH_CLOSE 7 rst=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel,iterations=3) 8 cv2.imshow('img',img) 9 cv2.imshow('rst',rst) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為閉運算處理結果,影像兩個目標經過運算后連接在一起,


7.5 形態學梯度運算
形態學梯度運算是用影像的膨脹影像減去腐蝕影像的操作,形態學梯度運算經常用于獲取前景影像的邊緣資訊,
使用函式cv2.morphologyEx()實作形態學梯度運算,舉例代碼如下:
1 #使用函式cv2.morphologyEx()實作形態學梯度運算 2 import cv2 3 import numpy as np 4 img=cv2.imread('E:\python_opencv/biyunsuan.jpg',cv2.IMREAD_UNCHANGED) 5 kernel=np.ones((5,5),np.uint8) 6 #cv2.morphologyEx()函式的op引數設定為cv2.MORPH_GRADIENT 7 rst=cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel) 8 cv2.imshow('img',img) 9 cv2.imshow('rst',rst) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為形態學梯度運算處理結果,獲得了前景影像的邊緣輪廓,


7.6 禮帽運算
禮帽運算是用原始影像減去其開運算影像的操作,禮帽運算經常用于獲取影像的噪聲資訊和比原影像更亮的區域邊緣資訊,
使用函式cv2.morphologyEx()實作禮帽運算,舉例代碼如下:
1 #使用函式cv2.morphologyEx()實作禮帽運算 2 import cv2 3 import numpy as np 4 img=cv2.imread('E:\python_opencv/lena.jpg',cv2.IMREAD_UNCHANGED) 5 kernel=np.ones((5,5),np.uint8) 6 #cv2.morphologyEx()函式的op引數設定為cv2.MORPH_TOPHAT 7 rst=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel) 8 cv2.imshow('img',img) 9 cv2.imshow('rst',rst) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為禮帽運算處理結果,


7.7 黑帽運算
黑帽運算是用閉運算影像減去原始影像的操作,黑帽運算能夠獲取影像內部的小黑點或小孔,得到比原影像更暗的邊緣資訊,
使用函式cv2.morphologyEx()實作黑帽運算,舉例代碼如下:
1 #使用函式cv2.morphologyEx()實作黑帽運算 2 import cv2 3 import numpy as np 4 img=cv2.imread('E:\python_opencv/lena.jpg',cv2.IMREAD_UNCHANGED) 5 kernel=np.ones((5,5),np.uint8) 6 #cv2.morphologyEx()函式的op引數設定為cv2.MORPH_BLACKHAT 7 rst=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel) 8 cv2.imshow('img',img) 9 cv2.imshow('rst',rst) 10 cv2.waitKey() 11 cv2.destroyAllWindows()
運行結果如下圖,左為原影像,右為黑帽運算處理結果,


可以看到,黑帽運算得到了比禮帽運算更暗的邊緣資訊,
這次內容就分享到這里了,下次繼續更新第8章 影像梯度與Canny邊緣檢測,希望與各位老師和小伙伴們交流學習~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/275351.html
標籤:其他
