首先介绍两个最简单的形态学处理:膨胀(dilate)和腐蚀(erode)
它们的作用:1.去除噪声
2.分离出单个元素和连接分离的元素
3.找出强度凸起和孔洞
膨胀是使用核去遍历图像,图像在核覆盖区域中寻找最大值,以最大值覆盖核心处图像值。结果必然使图像高亮度区域增加。
腐蚀是膨胀的姊妹,但腐蚀是寻找核覆盖区域下的最小值,以最小值覆盖核心处图像值。结果必然使图像低亮度区域增加。
#include "cv.h"
#include "highgui.h"
using namespace std;
using namespace cv;
Mat src,dilateDst,erodeDst;
int dilateShape=0,erodeShape=0,dilateSize=0,erodeSize=0;
void dilateFcn(int, void*);
void erodeFcn(int, void*);
int main(int argc,char *argv[])
{
src=imread("src.jpg");
imshow("src",src);
namedWindow("Dilate");
namedWindow("Erode");
createTrackbar("Kernel shape:(0:RECT;1:CROSS;2:ELLIPSE)","Dilate",&dilateShape,2);
createTrackbar("Kernel size:","Dilate",&dilateSize,10,dilateFcn);
createTrackbar("Kernel shape:(0:RECT;1:CROSS;2:ELLIPSE)","Erode",&erodeShape,2);
createTrackbar("Kernel size:","Erode",&erodeSize,10,erodeFcn);
dilateFcn(0,0);erodeFcn(0,0);
waitKey(0);
destroyAllWindows();
return 0;
}
void dilateFcn(int, void*)
{
switch(dilateShape)
{
case 0:
dilateShape=MORPH_RECT;
break;
case 1:
dilateShape=MORPH_CROSS;
break;
case 2:
dilateShape=MORPH_ELLIPSE;
}
Mat dilateKernel=getStructuringElement(dilateShape,Size(2*dilateSize+1,2*dilateSize+1),Point(-1,-1));
dilate(src,dilateDst,dilateKernel);
imshow("Dilate",dilateDst);
}
void erodeFcn(int, void*)
{
switch(erodeShape)
{
case 0:
erodeShape=MORPH_RECT;
break;
case 1:
erodeShape=MORPH_CROSS;
break;
case 2:
erodeShape=MORPH_ELLIPSE;
}
Mat erodeKernel=getStructuringElement(erodeShape,Size(2*erodeSize+1,2*erodeSize+1),Point(-1,-1));
erode(src,erodeDst,erodeKernel);
imshow("Erode",erodeDst);
}
窗口TrackBar不美观
原图: 膨胀(核为矩形7*7)
膨胀(核为十字7*7) 膨胀(核为椭圆7*7)
腐蚀(核为矩形9*9) 腐蚀(核为十字9*9)
腐蚀(核为椭圆9*9)
可以看到结果图像上的白点或黑点的形状与核的形状一致!
使用morphologyEx()函数可以完成更多的形态学处理:
– Opening
– Closing
– Morphological Gradient(形态梯度)
– Top Hat
– Black Hat