OpenCV与EmguCV中的形态学滤波
形态学(morphology)1词通常表示生物学的1个分支,该分支主要研究动植物的形态和结构。而我们图象处理中指的形态学,常常表示的是数学形态学。下面1起来了解数学形态学的概念。 数学形态学是由1组形态学的代数运算子组成的,它的基本运算有4个: 膨胀、腐蚀、开启和闭合, 它们在2值图象和灰度图象中各有特点。 简单来说,形态学操作就是基于形状的1系列图象处理操作。 OpenCV为进行图象的形态学变换提供了快捷、方便的函数。基本的形态学操作有2种,他们是:膨胀与腐蚀(Dilation与Erosion)。 膨胀与腐蚀能实现多种多样的功能:消除噪声、分割(isolate)出独立的图象元素和在图象中连接(join)相邻的元素。形态学也常被用于寻觅图象中的明显的极大值区域或极小值区域和求出图象的梯度。 ①膨胀 dilate OpenCV中的函数原型以下: void dilate( InputArray src,OutputArray dst,InputArray kernel,Point anchor=Point(⑴,⑴),int iterations=1,int borderType=BORDER_CONSTANT,const Scalar& borderValue=morphologyDefaultBorderValue() );
我们也能够使用函数getStructuringElement配合这第3个参数的使用从而得到自定义的核。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。 其中,getStructuringElement函数的第1个参数表示内核的形状,我们可以选择以下3种形状之1:
而getStructuringElement函数的第2和第3个参数分别是内核的尺寸和锚点的位置。 我们1般在调用erode和dilate函数之前,先定义1个Mat类型的变量来取得getStructuringElement函数的返回值。对锚点的位置,有默许值Point(⑴,⑴),表示锚点位于中心。且需要注意,10字形的element形状唯1依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。 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,2),1,BORDER_DEFAULT);
imwrite("M:/图象处理实验/dilate/dst.bmp",dstImage); EmguCV中的函数原型: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) 参数含义与OpenCV中相同 第3个参数可以使用以下函数来获得自定义核: 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:图象处理实验dilatesrc.bmp")
Dim StructingElement As Emgu.CV.Mat = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,New Size(5,New Point(2,2))
CvInvoke.Dilate(img,img,StructingElement,Emgu.CV.CvEnum.BorderType.Default,New Emgu.CV.Structure.MCvScalar(0))
img.Save("M:图象处理实验dilatesrc-result.bmp") 此函数的参数没有默许值,使用起来比较繁琐。也能够以下调用。 Emgu.CV.Image(Of TColor,TDepth).Dilate(iterations As Integer) As Emgu.CV.Image(Of TColor,TDepth) 膨胀是指将图象(或图象中的1部份区域,A)与核B进行卷积。 核可以是任何的形状或大小,它具有1个单独定义出来的参考点。多数情况下,核是1个小的中间带有参考点的实心正方形或圆盘。核可以视为模板或掩码。 膨胀是求局部最大值的操作。 核B与图象卷积,即计算核B覆盖的区域的像素点最大值,并把这个最大值赋值给参考点指定的像素。这样就会使图象中的高亮区域逐步增长。这样的增长就是膨胀操作的初衷。 因而可知,膨胀和腐蚀操作是对图象中的高亮区域进行的,也就是图象的白色区域。 ②腐蚀 erode void erode( InputArray src,const Scalar& borderValue=morphologyDefaultBorderValue() );
eg。 Mat srcImage=imread("M:/图象处理实验/erode/src.bmp");
Mat dstImage;
Mat structuringE = getStructuringElement(MORPH_RECT,2));
erode( srcImage,BORDER_DEFAULT);
imwrite("M:/图象处理实验/erode/dst.bmp",dstImage); Public Shared Sub Erode(src As Emgu.CV.IInputArray,borderValue As Emgu.CV.Structure.MCvScalar) 函数参数含义与OpenCV相同 eg。 Dim img As Image(Of Gray,Byte)("M:图象处理实验erodesrc.bmp") Dim StructingElement As Emgu.CV.Mat = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,2))
CvInvoke.Erode(img,New Emgu.CV.Structure.MCvScalar(0))
img.Save("M:图象处理实验erodesrc-result.bmp") 腐蚀和膨胀是1对相反的操作,所以腐蚀就是求局部最小值的操作。 我们1般都会把腐蚀和膨胀对应起来学习理解。 ③ 开运算 开运算,其实就是先腐蚀后膨胀的进程。 开运算可以用来消除小物体,在纤细点处罚离物体,并且在平滑较大物体的边界的同时不明显改变其面积。 ④闭运算 闭运算,就是先膨胀后腐蚀的进程。 闭运算可以用来排除小型黑洞。 eg。(VB.NET、EmguCV) Dim img As Image(Of Gray,Byte)("M:图象处理实验2维码2维码.bmp")
Dim StructingElement As Emgu.CV.Mat = CvInvoke.GetStructuringElement(Emgu.CV.CvEnum.ElementShape.Rectangle,2))
'先膨胀
CvInvoke.Dilate(img,New Emgu.CV.Structure.MCvScalar(0))
'再腐蚀
CvInvoke.Erode(img,New Emgu.CV.Structure.MCvScalar(0))
img.Save("M:图象处理实验resultresult.bmp") 原图象与进行了闭运算后的输出结果比较:参考文献: Bradski & Kaebler ·《学习OpenCV(中文版)》· 清华大学出版社 · 2009 冈萨雷斯 · 《数字图象处理》 · 电子工业出版社 · 2011 http://blog.csdn.net/poem_qianmo/article/details/23710721 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |