OpenCV與EmguCV中的形態(tài)學濾波
來源:程序員人生 發(fā)布時間:2016-07-26 13:22:11 閱讀次數(shù):8634次
形態(tài)學(morphology)1詞通常表示生物學的1個分支,該分支主要研究動植物的形態(tài)和結(jié)構(gòu)。而我們圖象處理中指的形態(tài)學,常常表示的是數(shù)學形態(tài)學。下面1起來了解數(shù)學形態(tài)學的概念。
數(shù)學形態(tài)學是由1組形態(tài)學的代數(shù)運算子組成的,它的基本運算有4個: 膨脹、腐蝕、開啟和閉合, 它們在2值圖象和灰度圖象中各有特點。
簡單來說,形態(tài)學操作就是基于形狀的1系列圖象處理操作。
OpenCV為進行圖象的形態(tài)學變換提供了快捷、方便的函數(shù)。基本的形態(tài)學操作有2種,他們是:膨脹與腐蝕(Dilation與Erosion)。
膨脹與腐蝕能實現(xiàn)多種多樣的功能:消除噪聲、分割(isolate)出獨立的圖象元素和在圖象中連接(join)相鄰的元素。形態(tài)學也常被用于尋覓圖象中的明顯的極大值區(qū)域或極小值區(qū)域和求出圖象的梯度。
①膨脹 dilate
OpenCV中的函數(shù)原型以下:
void dilate( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(⑴,⑴), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );
- 第1個參數(shù),InputArray類型的src,輸入圖象,即源圖象,填Mat類的對象便可。圖象通道的數(shù)量可以是任意的,但圖象深度應(yīng)為CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之1。
- 第2個參數(shù),OutputArray類型的dst,即目標圖象,需要和源圖片有1樣的尺寸和類型。
- 第3個參數(shù),InputArray類型的kernel,膨脹操作的核。若為NULL時,表示的是使用參考點位于中心3x3的核。
- 第4個參數(shù),Point類型的anchor,錨的位置,其有默許值(⑴,⑴),表示錨位于中心。
- 第5個參數(shù),int類型的iterations,迭代使用erode()函數(shù)的次數(shù),默許值為1。
- 第6個參數(shù),int類型的borderType,用于推斷圖象外部像素的某種邊界模式。注意它有默許值BORDER_DEFAULT。
- 第7個參數(shù),const Scalar&類型的borderValue,當邊界為常數(shù)時的邊界值,有默許值morphologyDefaultBorderValue(),1般我們不用去管他。需要用到它時,可以看官方文檔中的createMorphologyFilter()函數(shù)得到更詳細的解釋。
我們也能夠使用函數(shù)getStructuringElement配合這第3個參數(shù)的使用從而得到自定義的核。getStructuringElement函數(shù)會返回指定形狀和尺寸的結(jié)構(gòu)元素(內(nèi)核矩陣)。
其中,getStructuringElement函數(shù)的第1個參數(shù)表示內(nèi)核的形狀,我們可以選擇以下3種形狀之1:
- 矩形: MORPH_RECT
- 交叉形: MORPH_CROSS
- 橢圓形: MORPH_ELLIPSE
而getStructuringElement函數(shù)的第2和第3個參數(shù)分別是內(nèi)核的尺寸和錨點的位置。
我們1般在調(diào)用erode和dilate函數(shù)之前,先定義1個Mat類型的變量來取得getStructuringElement函數(shù)的返回值。對錨點的位置,有默許值Point(⑴,⑴),表示錨點位于中心。且需要注意,10字形的element形狀唯1依賴于錨點的位置。而在其他情況下,錨點只是影響了形態(tài)學運算結(jié)果的偏移。
eg。
Mat srcImage=imread("M:/圖象處理實驗/dilate/src.bmp");
Mat dstImage;
//自定義核
Mat structuringE = getStructuringElement(MORPH_RECT,Size(5,5),Point(2,2));
dilate( srcImage, dstImage, structuringE, Point(2,2), 1, BORDER_DEFAULT);
imwrite("M:/圖象處理實驗/dilate/dst.bmp", dstImage);
EmguCV中的函數(shù)原型:Public Shared Sub Dilate(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, element As Emgu.CV.IInputArray, anchor As System.Drawing.Point, iterations As Integer, borderType As Emgu.CV.CvEnum.BorderType, borderValue As Emgu.CV.Structure.MCvScalar)
參數(shù)含義與OpenCV中相同
第3個參數(shù)可以使用以下函數(shù)來獲得自定義核:
Public Shared Function GetStructuringElement(shape As Emgu.CV.CvEnum.ElementShape, ksize As System.Drawing.Size, anchor As System.Drawing.Point) As Emgu.CV.Mat
eg。
Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)("M:\圖象處理實驗\dilate\src.bmp")
Dim StructingElement As Emgu.CV.Mat = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, New Size(5, 5), New Point(2, 2))
CvInvoke.Dilate(img, img, StructingElement, New Point(2, 2), 1, Emgu.CV.CvEnum.BorderType.Default, New Emgu.CV.Structure.MCvScalar(0))
img.Save("M:\圖象處理實驗\dilate\src-result.bmp")
此函數(shù)的參數(shù)沒有默許值,使用起來比較繁瑣。也能夠以下調(diào)用。
Emgu.CV.Image(Of TColor, TDepth).Dilate(iterations As Integer) As Emgu.CV.Image(Of TColor, TDepth)
膨脹是指將圖象(或圖象中的1部份區(qū)域,A)與核B進行卷積。
核可以是任何的形狀或大小,它具有1個單獨定義出來的參考點。多數(shù)情況下,核是1個小的中間帶有參考點的實心正方形或圓盤。核可以視為模板或掩碼。
膨脹是求局部最大值的操作。
核B與圖象卷積,即計算核B覆蓋的區(qū)域的像素點最大值,并把這個最大值賦值給參考點指定的像素。這樣就會使圖象中的高亮區(qū)域逐步增長。這樣的增長就是膨脹操作的初衷。
因而可知,膨脹和腐蝕操作是對圖象中的高亮區(qū)域進行的,也就是圖象的白色區(qū)域。

②腐蝕 erode
OpenCV中的函數(shù)原型以下:
void erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(⑴,⑴), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );
- 第1個參數(shù),InputArray類型的src,輸入圖象,即源圖象,填Mat類的對象便可。圖象通道的數(shù)量可以是任意的,但圖象深度應(yīng)為CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之1。
- 第2個參數(shù),OutputArray類型的dst,即目標圖象,需要和源圖片有1樣的尺寸和類型。
- 第3個參數(shù),InputArray類型的kernel,腐蝕操作的內(nèi)核。若為NULL時,表示的是使用參考點位于中心3x3的核。我們1般使用函數(shù) getStructuringElement配合這個參數(shù)的使用。getStructuringElement函數(shù)會返回指定形狀和尺寸的結(jié)構(gòu)元素(內(nèi)核矩陣)。詳細信息可見上文。
- 第4個參數(shù),Point類型的anchor,錨的位置,其有默許值(⑴,⑴),表示錨位于單位(element)的中心,我們1般不用管它。
- 第5個參數(shù),int類型的iterations,迭代使用erode()函數(shù)的次數(shù),默許值為1。
- 第6個參數(shù),int類型的borderType,用于推斷圖象外部像素的某種邊界模式。注意它有默許值BORDER_DEFAULT。
- 第7個參數(shù),const Scalar&類型的borderValue,當邊界為常數(shù)時的邊界值,有默許值morphologyDefaultBorderValue(),1般我們不用去管他。需要用到它時,可以看官方文檔中的createMorphologyFilter()函數(shù)得到更詳細的解釋。
eg。
Mat srcImage=imread("M:/圖象處理實驗/erode/src.bmp");
Mat dstImage;
Mat structuringE = getStructuringElement(MORPH_RECT,Size(5,5),Point(2,2));
erode( srcImage, dstImage, structuringE, Point(2,2), 1, BORDER_DEFAULT);
imwrite("M:/圖象處理實驗/erode/dst.bmp", dstImage);
EmguCV中的函數(shù)原型以下:Public Shared Sub Erode(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, element As Emgu.CV.IInputArray, anchor As System.Drawing.Point, iterations As Integer, borderType As Emgu.CV.CvEnum.BorderType, borderValue As Emgu.CV.Structure.MCvScalar)
函數(shù)參數(shù)含義與OpenCV相同
eg。
Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)("M:\圖象處理實驗\erode\src.bmp") Dim StructingElement As Emgu.CV.Mat = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, New Size(5, 5), New Point(2, 2))
CvInvoke.Erode(img, img, StructingElement, New Point(2, 2), 1, Emgu.CV.CvEnum.BorderType.Default, New Emgu.CV.Structure.MCvScalar(0))
img.Save("M:\圖象處理實驗\erode\src-result.bmp")
腐蝕和膨脹是1對相反的操作,所以腐蝕就是求局部最小值的操作。
我們1般都會把腐蝕和膨脹對應(yīng)起來學習理解。
③ 開運算開運算,其實就是先腐蝕后膨脹的進程。
開運算可以用來消除小物體,在纖細點處罰離物體,并且在平滑較大物體的邊界的同時不明顯改變其面積。

④閉運算
閉運算,就是先膨脹后腐蝕的進程。
閉運算可以用來排除小型黑洞。
eg。(VB.NET、EmguCV)
Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)("M:\圖象處理實驗\2維碼\2維碼.bmp")
Dim StructingElement As Emgu.CV.Mat = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle, New Size(5, 5), New Point(2, 2))
'先膨脹
CvInvoke.Dilate(img, img, StructingElement, New Point(2, 2), 1, Emgu.CV.CvEnum.BorderType.Default, New Emgu.CV.Structure.MCvScalar(0))
'再腐蝕
CvInvoke.Erode(img, img, StructingElement, New Point(2, 2), 1, Emgu.CV.CvEnum.BorderType.Default, New Emgu.CV.Structure.MCvScalar(0))
img.Save("M:\圖象處理實驗\result\result.bmp")
原圖象與進行了閉運算后的輸出結(jié)果比較:
參考文獻:
Bradski & Kaebler ·《學習OpenCV(中文版)》· 清華大學出版社 · 2009
岡薩雷斯 · 《數(shù)字圖象處理》 · 電子工業(yè)出版社 · 2011
http://blog.csdn.net/poem_qianmo/article/details/23710721
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學習有所幫助,可以手機掃描二維碼進行捐贈