腐蚀与膨胀
腐蚀和膨胀是图像的形态学处理中最基本的操作,之后遇见的开操作和闭操作都是腐蚀和膨胀操作的结合运算。腐蚀和
膨胀的应用广泛,而且效果也很好。
我们先来谈谈腐蚀与膨胀的原理:
对于二值图像:
从图像处理角度看,二值图像的腐蚀和膨胀就是将一个小型二值图(结构元素,一般为3*3大小)在一个大的二值图上逐点移动并进行比较,根据比较的结果作出相应处理而已。
膨胀算法:用3X3的结构元素,扫描二值图像的每一个像素,用结构元素与其覆盖的二值图像做“与”运算,如果都为0,结构图像的该像素为0,否则为1.结果:使二值图像扩大一圈。
腐蚀算法:用3X3的结构元素,扫描二值图像的每一个像素,用结构元素与其覆盖的二值图像做“与”运算,如果都为1,结构图像的该像素为1,否则为0.结果:使二值图像减小一圈。
腐蚀算法:用3X3的结构元素,扫描二值图像的每一个像素,用结构元素与其覆盖的二值图像做“与”运算,如果都为1,结构图像的该像素为1,否则为0.结果:使二值图像减小一圈。
以上都是关于二值图像的形态学操作,对于灰度图像:
-
腐蚀操作
其中,g(x,y)为腐蚀后的灰度图像,f(x,y)为原灰度图像,B为结构元素。腐蚀运算是由结构元素确定的邻域块中选取图像值与结构元素值的差的最小值。
-
膨胀操作
其中,g(x,y)为腐蚀后的灰度图像,f(x,y)为原灰度图像,B为结构元素。 膨胀运算是由结构元素确定的邻域块中选取图像值与结构元素值的和的最大值。
在灰度图的形态学操作中,一般选择“平摊”的结构元素,即结构元素B的值为0,则上面对灰度图的形态学操作可简化如下:
接下来我们看一个例子:
#include<cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv){
IplImage *src1;
src1 = cvLoadImage(argv[4],0);
IplImage *src2 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);
IplImage *src3 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);
cvNamedWindow("1", CV_WINDOW_AUTOSIZE);
cvNamedWindow("2", CV_WINDOW_AUTOSIZE);
cvNamedWindow("3", CV_WINDOW_AUTOSIZE);
cvErode(src1, src2 );
cvDilate(src1, src3);
cvShowImage("1", src1);
cvShowImage("2", src2);
cvShowImage("3", src3);
cvWaitKey(0);
cvReleaseImage(&src1);
return 0;
}
#include <highgui.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv){
IplImage *src1;
src1 = cvLoadImage(argv[4],0);
IplImage *src2 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);
IplImage *src3 = cvCreateImage(cvGetSize(src1), src1->depth, src1->nChannels);
cvNamedWindow("1", CV_WINDOW_AUTOSIZE);
cvNamedWindow("2", CV_WINDOW_AUTOSIZE);
cvNamedWindow("3", CV_WINDOW_AUTOSIZE);
cvErode(src1, src2 );
cvDilate(src1, src3);
cvShowImage("1", src1);
cvShowImage("2", src2);
cvShowImage("3", src3);
cvWaitKey(0);
cvReleaseImage(&src1);
return 0;
}
效果如下:
原图:
原图:
腐蚀后:
膨胀后:
可以看见变化,所以通俗的讲:
膨胀算法使图像扩大一圈。
腐蚀算法使二值图像减小一圈。
腐蚀:删除对象边界的某些像素
膨胀:给图像中的对象边界添加像素