您的位置:首页 > 其它

腐蚀函数cvErode 和 膨胀函数cvDilate

2014-12-09 21:32 246 查看
Erode腐蚀, Dilate膨胀,这两个形态学函数总是成对出现,前者可以消除较小的点如噪音,后者可以使不连通的图像合并成块。

void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );
void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 );
这两个函数的参数相同,是一对“相反”的函数(这里的相反并不是指后一个函数可以将前一个函数处理的图像恢复,而是一个缩小图像团块,一个放大图像的团块)

src 输入图像.

dst 输出图像.

element 用于膨胀的结构元素。若为 NULL, 则使用 3×3 长方形的结构元素

iterations 膨胀的次数。 膨胀可以重复进行 (iterations) 次. 对彩色图像,每个彩色通道单独处理。

下面的程序将演示这两个函数,腐蚀和膨胀的过程

#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
int main(int argc, char** argv)
{
if (argc<2)
return 0;//检查输入参数
int a = 1;
int eIter = 1, dIter = 1, exitFlag = 1;
IplImage *image, *image1, *image2;
image = cvLoadImage(argv[1]);
image1 = cvCreateImage(cvSize(image->width, image->height), 8, 1);//创建首地址并分配存储空间
image2 = cvCreateImage(cvSize(image->width, image->height), 8, 1);

cvCvtColor(image, image1, CV_RGB2GRAY);//实现RGB颜色向HSV,HSI等颜色空间的转换. 参数CV_RGB2GRAY是RGB到gray(灰度图)c参数 CV_GRAY2RGB是gray到RGB.
cvCvtColor(image, image2, CV_RGB2GRAY);
cvNamedWindow("image", 1);
cvShowImage("image", image);
/* 对话框未使用
cvNamedWindow("Select", 1);
cvCreateTrackbar("eIterations", "Select", &eIter, 20, 0);
//参数1滑块名称  参数2显示窗口  参数3 OPENCV将当前滑块位置值传给指针指向的整数   参数4滑块调整范围最大值  参数5指向回调函数的指针,当滑动条被拖动时,函数自动调用

cvCreateTrackbar("dIterations", "Select", &dIter, 20, 0);
//参数1滑块名称  参数2显示窗口  参数3 OPENCV将当前滑块位置值传给指针指向的整数   参数4滑块调整范围最大值  参数5指向回调函数的指针,当滑动条被拖动时,函数自动调用
*/
cvNamedWindow("Erode_fushi", 1);
cvNamedWindow("Dilate_pengzhang", 1);
cvShowImage("Erode_fushi", image1);
cvShowImage("Dilate_pengzhang", image2);
cvWaitKey(0);

while (1)
{
cvErode(image1, image1, 0, 1);
/*
cvErode
腐蚀,消除细小物质
src  输入图像.
dst  输出图像.
element   用于腐蚀的结构元素。若为 NULL, 则使用 3×3 长方形的结构元素
iterations   腐蚀的次数.  腐蚀可以重复进行(iterations) 次.对彩色图像,每个彩色通道单独处理。
*/
cvShowImage("Erode_fushi", image1);
std::cout << "Erode_fushi" << std::endl;
a = cvWaitKey(0);
if ((char)a == 'q')
break;
}
cvCopy(image1, image2);
a = 1;

while (1)
{
cvDilate(image2, image2, 0, 1);		//膨胀,填充物体内细小物质
/*
cvDilate
膨胀,消除细小物质
src  输入图像.
dst  输出图像.
element   用于膨胀的结构元素。若为 NULL, 则使用 3×3 长方形的结构元素
iterations   膨胀的次数.  膨胀可以重复进行(iterations) 次.对彩色图像,每个彩色通道单独处理。
*/
cvShowImage("Dilate_pengzhang", image2);
std::cout << "Dilate_pengzhang" << std::endl;
a = cvWaitKey(0);
if ((char)a == 'q')
break;
}

//释放窗口资源
return 0;
}

原图:



腐蚀:



膨胀:



一 引言

数学形态学是一门建立在集论基础上的学科,是几何形态学分析和描述的有力工具。数学形态学的历史可回溯到19世纪。1964年法国的Matheron和Serra在积分几何的研究成果上,将数学形态学引入图像处理领域,并研制了基于数学形态学的图像处理系统。1982年出版的专著《ImageAnalysis and MathematicalMorphology》是数学形态学发展的重要里程碑,表明数学形态学在理论上趋于完备及应用上不断深入。数学形态学蓬勃发展,由于其并行快速,易于硬件实现,已引起了人们的广泛关注。目前,数学形态学已在计算机视觉、信号处理与图像分析、模式识别、计算方法与数据处理等方面得到了极为广泛的应用。

数学形态学可以用来解决抑制噪声、特征提取、边缘检测、图像分割、形状识别、纹理分析、图像恢复与重建、图像压缩等图像处理问题。该文将主要对数学形态学的基本理论及其在图像处理中的应用进行综述。


二 数学形态学的定义和分类

数学形态学是以形态结构元素为基础对图像进行分析的数学工具。它的基本思想是用具有一定形态的结构元素去度量和提取图像中的对应形状以达到对图像分析和识别的目的。数学形态学的应用可以简化图像数据,保持它们基本的形状特征,并除去不相干的结构。数学形态学的基本运算有4个:膨胀、腐蚀、开启和闭合。它们在二值图像中和灰度图像中各有特点。基于这些基本运算还可以推导和组合成各种数学形态学实用算法。


(1)二值形态学

数学形态学中二值图像的形态变换是一种针对集合的处理过程。其形态算子的实质是表达物体或形状的集合与结构元素间的相互作用,结构元素的形状就决定了这种运算所提取的信号的形状信息。形态学图像处理是在图像中移动一个结构元素,然后将结构元素与下面的二值图像进行交、并等集合运算。

基本的形态运算是腐蚀和膨胀。

在形态学中,结构元素是最重要最基本的概念。结构元素在形态变换中的作用相当于信号处理中的“滤波窗口”。用B(x)代表结构元素,对工作空间E中的每一点x,腐蚀和膨胀的定义为:



用B(x)对E进行腐蚀的结果就是把结构元素B平移后使B包含于E的所有点构成的集合。用B(x)对E进行膨胀的结果就是把结构元素B平移后使B与E的交集非空的点构成的集合。先腐蚀后膨胀的过程称为开运算。它具有消除细小物体,在纤细处分离物体和平滑较大物体边界的作用。先膨胀后腐蚀的过程称为闭运算。它具有填充物体内细小空洞,连接邻近物体和平滑边界的作用。

可见,二值形态膨胀与腐蚀可转化为集合的逻辑运算,算法简单,适于并行处理,且易于硬件实现,适于对二值图像进行图像分割、细化、抽取骨架、边缘提取、形状分析。但是,在不同的应用场合,结构元素的选择及其相应的处理算法是不一样的,对不同的目标图像需设计不同的结构元素和不同的处理算法。结构元素的大小、形状选择合适与否,将直接影响图像的形态运算结果。因此,很多学者结合自己的应用实际,提出了一系列的改进算法。如梁勇提出的用多方位形态学结构元素进行边缘检测算法既具有较好的边缘定位能力,又具有很好的噪声平滑能力。许超提出的以最短线段结构元素构造准圆结构元素或序列结构元素生成准圆结构元素相结合的设计方法,用于骨架的提取,可大大减少形态运算的计算量,并可同时满足尺度、平移及旋转相容性,适于对形状进行分析和描述。


(2)灰度数学形态学

二值数学形态学可方便地推广到灰度图像空间。只是灰度数学形态学的运算对象不是集合,而是图像函数。以下设f(x,y)是输入图像,b(x,y)是结构元素。用结构元素b对输入图像y进行膨胀和腐蚀运算分别定义为:



对灰度图像的膨胀(或腐蚀)操作有两类效果:

(1)如果结构元素的值都为正的,则输出图像会比输入图像亮(或暗);

(2)根据输入图像中暗(或亮)细节的灰度值以及它们的形状相对于结构元素的关系,它们在运算中或被消减或被除掉。灰度数学形态学中开启和闭合运算的定义与在二值数学形态学中的定义一致。用b对f进行开启和闭合运算的定义为:



(3)模糊数学形态学

将模糊集合理论用于数学形态学就形成了模糊形态学。模糊算子的定义不同,相应的模糊形态运算的定义也不相同。在此,选用Shinba的定义方法。模糊性由结构元素对原图像的适应程度来确定。用有界支撑的模糊结构元素对模糊图像的腐蚀和膨胀运算按它们的隶属函数定义为:






其中,x,y∈Z2代表空间坐标,ua,ub分别代表图像和结构元素的隶属函数。从(7),(8)式的结果可知,经模糊形态腐蚀膨胀运算后的隶属函数均落在[0,1]的区间内。模糊形态学是传统数学形态学从二值逻辑向模糊逻辑的推广,与传统数学形态学有相似的计算结果和相似的代数特性。模糊形态学重点研究n维空间目标物体的形状特征和形态变换,主要应用于图像处理领域,如模糊增强、模糊边缘检测、模糊分割等。

三 数学形态学在图像处理中的主要应用

近年来,数学形态学在图像处理方面得到了日益广泛的应用。下面主要就数学形态学在边缘检测、图像分割、图像细化以及噪声滤除等方面的应用做简要介绍。

(1) 边缘检测

边缘检测是大多数图像处理必不可少的一步,提供了物体形状的重要信息。对于二值图像,边缘检测是求一个集合A的边界,记为B(A):





对于灰度图像,边缘检测是求一幅图像的形态学梯度,记为g:

数学形态学运算用于边缘检测,存在着结构元素单一的问题。它对与结构元素同方向的边缘敏感,而与其不同方向的边缘(或噪声)会被平滑掉,即边缘的方向可以由结构元素的形状确定。但如果采用对称的结构元素,又会减弱对图像边缘的方向敏感性。所以在边缘检测中,可以考虑用多方位的形态结构元素,运用不同的结构元素的逻辑组合检测出不同方向的边缘。

梁勇等人构造了8个方向的多方位形态学结构元素,应用基本形态运算,得到8个方向的边缘检测结果,再把这些结果进行归一化运算、加权求和,得到最终的图像边缘。该算法在保持图像细节特征和平滑边缘等方面,取得了较好的效果。

(2) 图像分割

基于数学形态学的图像分割算法是利用数学形态学变换,把复杂目标X分割成一系列互不相交的简单子集X1,X2,…,XN,即:

对目标X的分割过程可按下面的方法完成:首先求出X的最大内接“圆”X1,然后将X1从X中减去,再求X-X1的最大内接“圆”X2,…,依此类推,直到最后得到的集合为空集为止。下面以二值图像为例,介绍用数学形态学方法求解子集X1,X2,…,XN的过程。

设B为结构元素,B可以是圆、三角形、正方形等简单的几何基元,那么“简单”形状集合Xi可以用下面的公式来定义:

式中ni为一整数,用上式定义Xi分割目标,有时会产生分割过程不唯一的现象。为此可采用下面公式来定义简单集合Xi:

其中Li为一个点或一条线,当Li为点时,则与(12)式定义等价。(13)式定义的简单形状Xi可由niB沿线Li移动而产生。即将“产生器”niB的中心沿“脊骨”Li移动产生。如果niB为圆,则得到的Xi称Blum带。它具有一些特殊的性质,如Xi的边界是光滑的,Xi的最大圆与其边界相切,Xi的脊骨与产生器都是唯一的等等。

有了简单形状集合Xi的定义,则目标X可按下面方法分割。首先按式(14)求出X的最大内切结构元素Xi:

数学形态学用于图像分割的缺点是对边界噪声敏感。为了改善这一问题,刘志敏等人提出了基于图像最大内切圆的数学形态学形状描述图像分割算法和基于目标最小闭包结构元素的数学形态学形状描述图像分割算法,并使用该算法对二值图像进行了分割,取得了较好的效果。邓世伟等人提出一种基于数学形态学的深度图像分割算法。作者首先利用形态学算子获得分别含有阶跃边缘与屋脊边缘的凸脊和凹谷图像,然后利用控制区域生长过程得到最终的分割结果。与传统方法相比,该方法速度快,抗噪性能好。

(3) 形态骨架提取

形态骨架描述了物体的形状和方向信息。它具有平移不变性、逆扩张性和等幂性等性质,是一种有效的形状描述方法。二值图像A的形态骨架可以通过选定合适的结构元素B,对A进行连续腐蚀和开启运算来求取,设S(A)代表A的骨架,定义为:

蒋刚毅等人运用数学形态学方法,对交通标志的内核形状提取形态骨架函数,将其作为用于模式匹配的形状特征。A的形态骨架函数SKF(A)表示为:

SKF(X)中值较大的点对应大的n,并代表了形态骨架的主要成分,即表达了形状的主体结构;而SKF(X)中值较小的点对应小的n,是形态骨架的细节成分,与形状的边缘信息相联系。

形态骨架函数完整简洁地表达了形态骨架的所有信息,因此,根据形态骨架函数的模式匹配能够实现对不同形状物体的识别。算法具有位移不变性,因而使识别更具稳健性。

(4) 噪声滤除

对图像中的噪声进行滤除是图像预处理中不可缺少的操作。将开启和闭合运算结合起来可构成形态学噪声滤除器。

对于二值图像,噪声表现为目标周围的噪声块和目标内部的噪声孔。用结构元素B对集合A进行开启操作,就可以将目标周围的噪声块消除掉;用B对A进行闭合操作,则可以将目标内部的噪声孔消除掉。该方法中,对结构元素的选取相当重要,它应当比所有的噪声孔和噪声块都要大。

对于灰度图像,滤除噪声就是进行形态学平滑。实际中常用开启运算消除与结构元素相比尺寸较小的亮细节,而保持图像整体灰度值和大的亮区域基本不变;用闭合运算消除与结构元素相比尺寸较小的暗细节,而保持图像整体灰度值和大的暗区域基本不变。将这两种操作综合起来可达到滤除亮区和暗区中各类噪声的效果。同样的,结构元素的选取也是个重要问题。

四 选取结构元素的方法

分析表明,各种数学形态学算法的应用可分解为形态学运算和结构元素选择两个基本问题,形态学运算的规则已由定义确定,于是形态学算法的性能就取决于结构元素的选择,亦即结构元素决定着形态学算法的目的和性能。因此如何自适应地优化确定结构元素,就成为形态学领域中人们长期关注的研究热点和技术难点。目前较多采用多个结构元素对图像进行处理的方法。

(1) 多结构元素运算

在许多形态学应用中,往往只采用一个结构元素,这通常不能产生满意的结果。在模式识别中,如果要提取某个特定的模式,只采用一个结构元素,那么,只有与结构元素形状、大小完全相同的模式才能被提取,而与此结构元素表示的模式即使有微小差别的其他模式的信息都不能获取。

解决此问题的一个有效方法之一就是将形态学运算与集合运算结合起来,同时采用多个结构元素,分别对图像进行运算,然后将运算后的图像合并起来,即多结构元素形态学运算。

(2) 用遗传算法选取结构元素

遗传算法的思想来源于自然界物竞天择、优胜劣汰、适者生存的演化规律和生物进化原理,并引用随机统计理论而形成,具有高效并行全局优化搜索能力,能有效地解决机器学习中参数的复杂优化和组合优化等难题。

近年来不少国外学者已进行了这方面的探索与研究,Ehrgardt设计了形态滤波的遗传算法,用于二值图像的去噪和根据二值纹理特性消除预定目标;Huttumen利用遗传算法构造了软式形态滤波器及其参数优化的设计方法,以实现灰度图像的降噪功能。余农、李予蜀等人用遗传算法在自然景象的目标检测与提取方面进行了研究,通过自适应优化训练使结构元素具有图像目标的形态结构特征,从而赋予结构元素特定的知识,使形态滤波过程融入特有的智能,以实现对复杂变化的图像具有良好的滤波性能和稳健的适应能力。其实质是解决滤波器设计中知识获取和知识精炼的机器学习问题。

五 数学形态学存在的问题与进一步的研究方向

数学形态学是一门建立在集论基础之上的学科,是几何形状分析和描述的有力工具。近年来,数学形态学在数字图像处理、计算机视觉与模式识别等领域中得到了越来越广泛的应用,渐渐形成了一种新的数字图像分析方法和理论,引起了国内外相关领域研究人员的广泛关注。目前,数学形态学存在的问题及研究方向主要集中在以下几个方面:

(1) 形态运算实质上是一种二维卷积运算,当图像维数较大时,特别是用灰度形态学、软数学形态学、模糊形态学等方法时,运算速度很慢,因而不适于实时处理。

(2) 由于结构元素对形态运算的结果有决定性的作用,所以,需结合实际应用背景和期望合理选择结构元素的大小与形状。

(3) 软数学形态学中关于结构元素核心、软边界的定义,及对加权统计次数*的选择也具有较大的灵活性,应根据图像拓扑结构合理选择,没有统一的设计标准。

(4) 为达到最佳的滤波效果,需结合图像的拓扑特性选择形态开、闭运算的复合方式。

(5) 对模糊形态学,不同的模糊算子会直接影响模糊形态学的定义及其运算结果。

(6) 有待进一步将数学形态学与神经网络、模糊数学结合研究灰度图像、彩色图像的处理和分析方法。

(7) 有待进一步研究开发形态运算的光学实现及其它硬件实现方法。

(8) 有待将形态学与小波、分形等方法结合起来对现有图像处理方法进行改进,进一步推广应用。所以如何实现灰度形态学、软数学形态学、模糊软数学形态学的快速算法,如何改善形态运算的通用性,增强形态运算的适应性,并结合数学形态学的最新应用进展,将其应用到图像处理领域,丰富和发展利用数学形态学的图像处理与分析方法,成为数学形态学今后的发展方向。

六 结论

数学形态学对图像的处理具有直观上的简明性和数学上的严谨性,在定量描述图像的形态特征上具有独特的优势,为基于形状细节进行图像处理提供了强有力的手段。建立在集合理论基础上的数学形态学,主要通过选择相应的结构元素采用膨胀、腐蚀、开启、闭合#种基本运算的组合来处理图像。数学形态学在图像处理中的应用广泛,有许多实用的算法,但在每种算法中结构元素的选取都是一个重要的问题。

算法思路:

腐蚀的算法:

用3x3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作:如果都为1,结果图像的该像素为1。否则为0。
结果:使二值图像减小一圈
定义:E = B  S = { x,y | SxyB}

膨胀的算法:
用3x3的结构元素,扫描图像的每一个像素,用结构元素与其覆盖的二值图像做“与”操作:如果都为0,结果图像的该像素为0。否则为1
结果:使二值图像扩大一圈
定义:E = B  S = { x,y | Sxy∩B ≠Ф}

代码: VC++code

转自:http://blog.csdn.net/vincentzhao2009/archive/2009/10/24/4723469.aspx

腐蚀:

把结构元素S 平移x 后得到Sx ,若Sx 包含于X ,我们记下这个x 点,所有满足上述条件的x 点组成的集合称做X 被S 腐蚀(Erosion)的结果。用公式表示为:





腐蚀的方法是,拿S 的原点和X上的点一个一个地对比,如果S 上的所有点都在X 的范围内,则S 的原点对应的点保留,否则将该点去掉。以下是详细的代码,并且附上测试图片:

#include

#include


#include


#include


#include


unsigned char **get_matrix_space(int m,intn)

{


int i;


unsigned char **a;


a=(unsigned char **)calloc(m,sizeof(unsigned char*));


for(i=0;ireturn a;


}


main(){

FILE *fs,*fd;


unsigned charc1,c2,**ps,**pd,**get_matrix_space(int,int);


int width,height,L,i,j,l,m,match;
if((fs=fopen("sourcea.pgm","rb")) ==NULL){ printf("can't
open %s\n","source.pgm");
exit(1); } if((fd =fopen("destination.pgm","wb")) ==NULL){ printf("can't
open%s\n","destination.pgm");
exit(1); }

fscanf(fs,"%c%c\n%d%d\n%d\n",&c1,&c2,&width,&height,&L);

ps=get_matrix_space(height,width);


pd=get_matrix_space(height,width);


for(i=0;i for(j=0;j fread(&ps[i][j],sizeof(unsignedchar),1,fs); pd[i][j]
= 0;
}

}


///////////////////////

match = 1;


for(i=0;i
for(j=0;j for(m=i;m for(l=j;l if(ps[m][l]!=255){ match
= 0;
} } } if(match
!= 0){
pd[i][j]=255; } match
= 1;
}

}


//////////////////////


fprintf(fd,"%c%c\n%d%d\n%d\n",'P','5',width,height,L);


for(i=0;i
for(j=0;j fwrite(&pd[i][j],sizeof(unsignedchar),1,fd); }

}


}








膨胀:

把结构元素S 平移x 后得到Sx ,若Sx 与X 相交不为空,我们记下这个x 点,所有满足上述条件的x 点组成的集合称做X 被S 膨胀((dilation))的结果。用公式表示为:





膨胀的方法是,拿S 的原点和X 上的点一个一个地对比,如果S 上有一个点落在X 的范围内,则S 的原点对应的点就为图像。以下是详细的代码,并且附上测试图片:

#include

#include


#include


#include


#include


unsigned char **get_matrix_space(int m,intn)

{


int i;


unsigned char **a;


a=(unsigned char **)calloc(m,sizeof(unsigned char*));

for(i=0;ireturn a;


}


main(){

FILE *fs,*fd;


unsigned charc1,c2,**ps,**pd,**v,**get_matrix_space(int,int);


intwidth,height,L,i,j,l,m,windowSize,match;
if((fs=fopen("source.pgm","rb")) ==NULL){ printf("can't
open %s\n","source.pgm");
exit(1); } if((fd =fopen("destination.pgm","wb")) ==NULL){ printf("can't
open%s\n","destination.pgm");
exit(1); }

fscanf(fs,"%c%c\n%d%d\n%d\n",&c1,&c2,&width,&height,&L);

ps=get_matrix_space(height,width);


pd=get_matrix_space(height,width);


for(i=0;i for(j=0;j fread(&ps[i][j],sizeof(unsignedchar),1,fs); }

}


match = 0;


//////////////////////


//用2x2方块作为膨胀的结构元素。


for(i=0;i
for(j=0;j for(l=i;l for(m=j;m if(ps[l][m]==255){ match
= 1;
} } } if(match
== 1){
pd[i][j]
= 255;
match
= 0;
} }

}


//////////////////////


fprintf(fd,"%c%c\n%d%d\n%d\n",'P','5',width,height,L);


for(i=0;i
for(j=0;j fwrite(&pd[i][j],sizeof(unsignedchar),1,fd); }

}


}








Matlab

originalBW =imread('f.jpg');

se=strel('line',20,0);

BW=imdilate(originalBW,se);

imshow(BW)

imwrite(BW,'腐蚀膨胀后的图像.jpg')

一般先将处理图像转为整型或逻辑型再处理即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: