摘要:數(shù)學(xué)形態(tài)學(xué)關(guān)注的是圖像中的形狀,它提供了一些方法用于檢測形狀和改變形狀。所以這個(gè)結(jié)果也會(huì)把形狀以外的噪點(diǎn)排除掉。你還可以查看其它筆記。參考資料圖像的膨脹與腐蝕數(shù)學(xué)形態(tài)學(xué)基本操作及其應(yīng)用計(jì)算機(jī)視覺特征提取與圖像處理第三版
數(shù)學(xué)形態(tài)學(xué)(mathematical morphology)關(guān)注的是圖像中的形狀,它提供了一些方法用于檢測形狀和改變形狀。起初是基于二值圖像提出的,后來擴(kuò)展到灰度圖像。二值圖像就是:每個(gè)像素的值只能是0或1,1代表描繪圖像的點(diǎn),0代表背景。
基本的形態(tài)學(xué)運(yùn)算包括:腐蝕(erosion)、膨脹(dilation)、開(opening)、閉(closing),對于這些運(yùn)算,都需要用到被稱為結(jié)構(gòu)元素(Structuring element)的模板,一般為方形,以小矩陣的形式表示,但它的元素的值只能是0或1,它代表的是一個(gè)集合,這個(gè)集合罩在原圖像上,可以跟原圖像的形狀進(jìn)行集合運(yùn)算。
腐蝕(erosion)要講清楚去處過程不容易,直接上圖看效果:
圖中(a)為原圖像,(b)為腐蝕運(yùn)算后結(jié)果,可以看出除了字母筆刷變細(xì)了之外,黑色背景的噪點(diǎn)也都不見了,(c)是膨脹運(yùn)算結(jié)果,字母筆刷比原圖像粗。
ok,現(xiàn)在看腐蝕是怎么實(shí)現(xiàn)的,還是先看圖:
如圖所示,(a)是3×3結(jié)構(gòu)元素,相當(dāng)于:
array([[ 1., 1., 1.], [ 1., 1., 1.], [ 1., 1., 1.]])
圖中標(biāo)識出了它的中心點(diǎn)。
結(jié)構(gòu)元素的設(shè)置也可以是其它大小,也不一定全是1(黑點(diǎn)),比如是一個(gè)3×3十字形:
[[0,1,0], [1,1,1], [0,1,0]]
(b)為待處理的原圖像,我們把其中由所有黑點(diǎn)組成的集合設(shè)為X
(c)為腐蝕后的結(jié)果,黑色點(diǎn)就是經(jīng)過腐蝕之后保留下來的點(diǎn),灰色的點(diǎn)表示被排除出去的點(diǎn),我們看到的效果是X變小了一圈,這也之所以叫腐蝕的原因吧。
可以這樣來形象理解腐蝕運(yùn)算過程:將結(jié)構(gòu)元素平移到原圖像上某個(gè)位置,如果結(jié)構(gòu)元素中所有的黑點(diǎn)(值為1)都落在X里,就把結(jié)構(gòu)元素中心點(diǎn)對應(yīng)的原圖像的像素點(diǎn)保留下來,否則就排除出去,如(c)所示,假設(shè)結(jié)構(gòu)元素蓋在這個(gè)位置,這時(shí)結(jié)構(gòu)元素下半部還有幾個(gè)點(diǎn)沒落在原圖X中,所以將中心點(diǎn)對應(yīng)的像素點(diǎn)排除出去,從黑色標(biāo)記為灰色。將結(jié)構(gòu)元素在原圖像上進(jìn)行平移,直到原圖像的每一個(gè)像素都被處理過。
所以這個(gè)結(jié)果也會(huì)把形狀以外的噪點(diǎn)排除掉。
腐蝕函數(shù)說明
scipy.ndimage.morphology.binary_erosion(input, structure=None, iterations=1,...) input: 原圖像二值圖 structure: 即結(jié)構(gòu)元素,默認(rèn)為3×3十字形 iterations: 表示要連續(xù)應(yīng)用腐蝕多少次 返回腐蝕后二值圖結(jié)果,ndarray類型
示例:
>>> a = np.zeros((7,7), dtype=np.int) >>> a[1:6, 2:5] = 1 >>> a #原圖像二值圖,注意中間由1組成的矩形形狀 array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0]]) >>> ndimage.binary_erosion(a).astype(a.dtype) #可以看出矩形形狀被"腐蝕"了一圈 array([[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]])膨脹(dilation)
類似地:
如圖(c)就是膨脹的結(jié)果,運(yùn)算過程跟腐蝕類似,只不過對像素的排除判斷不一樣,膨脹的判斷方式是:只要結(jié)構(gòu)元素中有一個(gè)黑點(diǎn)(值為1)落在X集合里,就把結(jié)構(gòu)元素中心點(diǎn)對應(yīng)的原圖像的像素點(diǎn)保留下來,否則就排除出去。
膨脹函數(shù)scipy.ndimage.morphology.binary_dilation與腐蝕類似,使用示例:
>>> a = np.zeros((5, 5)) >>> a[2, 2] = 1 >>> a array([ [ 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0.], [ 0., 0., 1., 0., 0.], [ 0., 0., 0., 0., 0.], [ 0., 0., 0., 0., 0.]]) >>> ndimage.binary_dilation(a).astype(a. dtype) #binary_dilation第二個(gè)參數(shù)可指定結(jié)構(gòu)元素,默認(rèn)為3×3十字形 array([ [ 0., 0., 0., 0., 0.], [ 0., 0., 1., 0., 0.], [ 0., 1., 1., 1., 0.], [ 0., 0., 1., 0., 0.], [ 0., 0., 0., 0., 0.]])
我們從以上的效果圖可以看到,腐蝕和膨脹可以改變形狀,同時(shí)也可以去背景噪點(diǎn)。
另外,把形狀的膨脹結(jié)果減去它的腐蝕結(jié)果,可以得到形狀的粗略邊緣以及角點(diǎn)。
先對原圖像進(jìn)行腐蝕,再膨脹,就是開運(yùn)算。有什么用呢?簡單點(diǎn)說它可以去除與結(jié)構(gòu)元素大小相當(dāng)?shù)目锥春退槠H绻惶巿D像中有多個(gè)形狀,開運(yùn)算可以把那些只有一點(diǎn)點(diǎn)粘連的形狀分開。因?yàn)槟屈c(diǎn)粘連的地方被去除了。
簡單示例:
>>> a = np.zeros((5,5), dtype=np.int) >>> a[1:4, 1:4] = 1; a[4, 4] = 1 >>> a #原圖像,注意右下角有個(gè)1,表示零散的碎片 array([[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 1]]) >>> ndimage.binary_opening(a, structure=np.ones((3,3))).astype(np.int) array([[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]]) #基于3×3全1的結(jié)構(gòu)元素應(yīng)用開運(yùn)算,把原圖像角落的1去掉 >>> ndimage.binary_opening(a).astype(np.int) array([[0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 1, 1, 1, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]]) #還可以用于平滑邊角,也就是四角處縮小變平滑了,如果形狀與形狀有邊角的粘連,就可以分開閉(closing)
與開運(yùn)算相反,先對原圖進(jìn)行膨脹,再腐蝕,就是閉運(yùn)算。閉運(yùn)算可以填充圖像中的孔洞,連接一些缺口和碎片,變成塊狀。舉個(gè)應(yīng)用場景——車牌定位,如下圖:
右圖是使用通過簡單的算法得到車的粗略邊角,車牌位置像是一堆散點(diǎn),如果對這個(gè)邊角圖運(yùn)用閉運(yùn)算可以得到這樣的效果:
車牌的位置變成一個(gè)接近車牌形狀的矩形,為下一步檢測提供了便利。
閉運(yùn)算函數(shù)ndimage.binary_closing的用法:
>>> a = np.zeros((5,5), dtype=np.int) >>> a[1:-1, 1:-1] = 1; a[2,2] = 0 >>> a #原圖像,注意中間有個(gè)0,表示形狀里面有個(gè)空洞 array([[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 0, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]]) >>> ndimage.binary_closing(a).astype(np.int) array([[0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]]) #應(yīng)用閉運(yùn)算之后,空洞被填充了
開閉運(yùn)算原理看似簡單,但很強(qiáng)大,只要結(jié)構(gòu)元素選取得當(dāng),可以做很多事情。
對象計(jì)數(shù)(Counting Objects)這里說的對象是指圖像中與周圍沒有連通的多帶帶的形狀,我們的目標(biāo)是要計(jì)算這些對象的個(gè)數(shù),計(jì)算對象個(gè)數(shù)可以使用函數(shù):
label, num_features = scipy.ndimage.measurements.label(input, structure=None, output=None) 參數(shù) input: 數(shù)組類型,其中元素非0值表示對象組成的點(diǎn),0表示圖像背景 structure: 結(jié)構(gòu)元素,用于檢測對象的連通特征,默認(rèn)是3×3十字形 返回值 label: 返回與input一樣的大小,但是把對象標(biāo)記出來 num_features:對象的個(gè)數(shù)
用法簡單示例:
>>> a = np.array([[0,0,1,1,0,0], ... [0,0,0,1,0,0], ... [1,1,0,0,1,0], ... [0,0,0,1,0,0]]) >>> labeled_array, num_features = measurements.label(a) #使用默認(rèn)3×3十字形結(jié)構(gòu)元素 >>> print(num_features) 4 >>> print(labeled_array) #打印被識別出來的對象的位置,分別用1,2,3...遞增的下標(biāo)標(biāo)記出來,所以labeled_array可以當(dāng)成灰度圖打印出來,被標(biāo)識的對象的灰度從黑到白變化 array([[0, 0, 1, 1, 0, 0], [0, 0, 0, 1, 0, 0], [2, 2, 0, 0, 3, 0], [0, 0, 0, 4, 0, 0]])
從上面例子看出,使用默認(rèn)3×3十字形結(jié)構(gòu)元素,檢測時(shí),只有水平和垂直連通才認(rèn)為像素屬于同一個(gè)對象,對角連通不算,如果要把對角連通當(dāng)作是同一個(gè)對象來計(jì)算,可以指定結(jié)構(gòu)元素為:
[[1,1,1], [1,1,1], [1,1,1]]
有時(shí)候,因受噪聲影響,對象之間有一點(diǎn)邊角的粘連,人眼可以很容易分辨出是兩個(gè)對象,但要讓label函數(shù)理解這一點(diǎn),可以使用前面提到的開運(yùn)算先對把對象稍微分開,再把結(jié)果傳給label函數(shù)進(jìn)行計(jì)數(shù),下面給出一個(gè)具體的圖像進(jìn)行示例:
from PIL import Image import numpy as np from scipy.ndimage import measurements,morphology import matplotlib.pyplot as plt im = np.array(Image.open("house.png").convert("L")) im = 1 * (im < 128) #把灰度圖像轉(zhuǎn)為二值圖,即灰度少于128的當(dāng)成圖像黑點(diǎn),否則當(dāng)作背景 label_from_origin, num_from_origin = measurements.label(im) im_open = morphology.binary_opening(im, np.ones((9, 5)), iterations=2) #運(yùn)用了一個(gè)9×5全1的結(jié)構(gòu)元素,并連續(xù)應(yīng)用兩次開運(yùn)算 label_from_open, num_from_open = measurements.label(im_open) #以下是畫圖 index = 221 plt.subplot(index) plt.imshow(im) plt.title("original") plt.axis("off") plt.subplot(index + 1) plt.imshow(label_from_origin) plt.title("%d objects" % num_from_origin) plt.axis("off") plt.subplot(index + 2) plt.imshow(im_open) plt.title("apply opening") plt.axis("off") plt.subplot(index + 3) plt.imshow(label_from_open) plt.title("%d objects" % num_from_open) plt.axis("off") #plt.gray() #為了更好的看出對象的分離,故意不用灰度顯示 plt.show()
效果圖如下,第二組(即第二行)是應(yīng)用開運(yùn)算之后的圖像及計(jì)算結(jié)果,跟第一組相比,對象計(jì)數(shù)增加了,我在第二組圖中圈出了應(yīng)用開運(yùn)算之后的主要變化之處:
上面介紹的用于二值圖的一些函數(shù),也有其對應(yīng)的用于灰度圖像的函數(shù),包括:
grey_erosion()
grey_dilation()
grey_opening()
grey_closing()
下一節(jié)學(xué)習(xí)圖像去噪。
你還可以查看其它筆記。
圖像的膨脹與腐蝕
數(shù)學(xué)形態(tài)學(xué)基本操作及其應(yīng)用
《計(jì)算機(jī)視覺特征提取與圖像處理(第三版)》
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/44194.html
摘要:學(xué)習(xí)筆記七數(shù)學(xué)形態(tài)學(xué)關(guān)注的是圖像中的形狀,它提供了一些方法用于檢測形狀和改變形狀。學(xué)習(xí)筆記十一尺度不變特征變換,簡稱是圖像局部特征提取的現(xiàn)代方法基于區(qū)域圖像塊的分析。本文的目的是簡明扼要地說明的編碼機(jī)制,并給出一些建議。 showImg(https://segmentfault.com/img/bVRJbz?w=900&h=385); 前言 開始之前,我們先來看這樣一個(gè)提問: pyth...
摘要:接下來的學(xué)習(xí)筆記本人都將使用來代替。庫中提供的很多圖像操作都是分別作用于某個(gè)通道的數(shù)據(jù)。是最流行的開源色彩管理庫之一。目前只支持在增加和。模塊支持從圖像對象創(chuàng)建或的對象,方便被使用和顯示。模塊對圖像或指定區(qū)域的每個(gè)通道進(jìn)行統(tǒng)計(jì),包括等。 介紹 《Programming Computer Vision with Python》是一本介紹計(jì)算機(jī)視覺底層基本理論和算法的入門書,通過這本收可以...
摘要:下面是二維空間的高斯分布函數(shù)公式這個(gè)公式被稱作高斯核。高斯模糊使用高斯平均算子來實(shí)現(xiàn)的圖像模糊叫高斯模糊,也叫高斯平滑被認(rèn)為是一種最優(yōu)的圖像平滑處理。 SciPy庫 SciPy庫,與之前我們使用的NumPy和Matplotlib,都是scipy.org提供的用于科學(xué)計(jì)算方面的核心庫。相對NumPy,SciPy庫提供了面向更高層應(yīng)用的算法和函數(shù)(其實(shí)也是基于NumPy實(shí)現(xiàn)的),并以子模塊...
摘要:簡稱庫是從擴(kuò)展下來的,提供了更豐富的圖像處理函數(shù),去噪函數(shù)除了還有算法,比如邊緣檢測還有以前簡單提過的算子濾波器。下面我用看具體的例子,將和高斯平滑進(jìn)行對比效果對比如下明顯感覺使用的效果要比高斯平滑好很多。 圖像去噪(Image Denoising)的過程就是將噪點(diǎn)從圖像中去除的同時(shí)盡可能的保留原圖像的細(xì)節(jié)和結(jié)構(gòu)。這里講的去噪跟前面筆記提過的去噪不一樣,這里是指高級去噪技術(shù),前面提過的...
閱讀 2797·2023-04-25 23:08
閱讀 1583·2021-11-23 09:51
閱讀 1564·2021-10-27 14:18
閱讀 3115·2019-08-29 13:25
閱讀 2831·2019-08-29 13:14
閱讀 2895·2019-08-26 18:36
閱讀 2193·2019-08-26 12:11
閱讀 811·2019-08-26 11:29