学习OpenCV---形态学操作

图像形态学

形态学操作就是基于形状的一系列图像处理操作,也可以理解为一种滤波行为。最基本的形态学操作使:膨胀和腐蚀。


膨胀和腐蚀

膨胀是图像和核进行卷积,然后取覆盖区域的最大值,这样就会使图像的高亮区域增大,OpenCV的API是dilate。和膨胀相反的,腐蚀是取的覆盖区域最小值。这样会使图像的高亮区域减少,OpenCV的API是erode。

void dilate( InputArray src, OutputArray dst, InputArray kernel,
                          Point anchor = Point(-1,-1), int iterations = 1,
                          int borderType = BORDER_CONSTANT,
                          const Scalar& borderValue = morphologyDefaultBorderValue() );

void erode( InputArray src, OutputArray dst, InputArray kernel,
                         Point anchor = Point(-1,-1), int iterations = 1,
                         int borderType = BORDER_CONSTANT,
                         const Scalar& borderValue = morphologyDefaultBorderValue() );


和卷积核不同的是,我们可以自定义自己的形态核,形态核不需要任何数值的填充,核在图像上移动时候,核元素只需要确定简单的标明在哪个范围内取最大值和最小值。自定义核的API函数是getStructuringElement。

Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));

综合编程

Mat src,dst,dst1,mapx,mapy;
char OUTPUT[] ="Win2";
int TrackBarPos = 0;
int TrackBarMax = 21;	
void CallBack(int, void*);
int main()
{

	src = imread("D:/Lena.jpg");
	if(!src.data)  
	{  
		cout<<"Picture loading failed !"<<endl;  
		return -1;  
	}
	namedWindow("Win1");
	imshow("Win1",src);
	namedWindow("Win2");
	createTrackbar("Value",OUTPUT,&TrackBarPos,TrackBarMax,CallBack);
	CallBack(0,0);

	waitKey(0);
	return 0;
}
void CallBack(int, void*)
{
	int ker = 2*TrackBarPos+1;
	//创建形态核(不同于卷积核),只需要确定确定一个移动的范围即可。不需要填充任何数字
	Mat StruEle = getStructuringElement(MORPH_RECT,Size(ker,ker),Point(-1,-1));
	dilate(src,dst,StruEle,Point(-1,-1),1);//erode(src,dst1,StruEle,Point(-1,-1),1);
	imshow(OUTPUT,dst);
	
}

通用的形态学

通用的形态学操作使用的API函数是:
void morphologyEx( InputArray src, OutputArray dst,
                                int op, InputArray kernel,
                                Point anchor = Point(-1,-1), int iterations = 1,
                                int borderType = BORDER_CONSTANT,
                                const Scalar& borderValue = morphologyDefaultBorderValue() );

其中:op参数可以选择:
①腐蚀操作(MORPH_ERODE = 0)
②膨胀操作(MORPH_DILATE =1)
注意:腐蚀和膨胀都说的是亮的区域,膨胀是亮的区域变大,腐蚀和膨胀相反,是亮的区域变小。
③开运算(MORPH_OPEN =2)
开运算是先腐蚀再膨胀,开操作去除小的明亮区域,剩余亮的区域被隔绝,但是大小不变。
理解:先腐蚀的话,亮的区域变小,再膨胀操作,可以排除小团物体。
下图是进行开操作的结果:


④闭运算(MORPH_CLOSE = 3)
和开操作相反,闭运算是通过先对图像膨胀再腐蚀实现的。
⑤形态学梯度:把团块的边缘突出来。
⑥礼帽
礼帽是从A中减去A的开运算,局部的极大值点被分隔出来。
⑦黑帽 
闭运算结果图与原图像之差

综合编程

Mat src,dst,dst1,mapx,mapy;
char OUTPUT[] ="Win2";
int TrackBarPos = 0;
int TrackBarMax = 21;
int ModePos = 0;
int ModeMax = 6;
void CallBack(int, void*);
int main()
{

	src = imread("D:/dilate.jpg");
	if(!src.data)  
	{  
		cout<<"Picture loading failed !"<<endl;  
		return -1;  
	}
	namedWindow("Win1");
	imshow("Win1",src);
	namedWindow("Win2",WINDOW_NORMAL);
	createTrackbar("Mode",OUTPUT,&ModePos,ModeMax,CallBack);
	createTrackbar("Value",OUTPUT,&TrackBarPos,TrackBarMax,CallBack);
	CallBack(0,0);

	waitKey(0);
	return 0;
}
void CallBack(int, void*)
{
	int ker = 2*TrackBarPos+1;
	//创建形态核(不同于卷积核),只需要确定确定一个移动的范围即可。不需要填充任何数字
	Mat StruEle = getStructuringElement(MORPH_RECT,Size(ker,ker),Point(-1,-1));
	morphologyEx(src,dst,ModePos,StruEle,Point(-1,-1));
	imshow(OUTPUT,dst);	
}

实际例子

验证码的读取

int main()
{
	//读取图像
	Mat src, dst;
	src = imread("D:/121.png");
	if (!src.data)
	{
		cout<<"Picture loading failed !"<<endl;
		return  -1;
	}
	namedWindow("Win1",WINDOW_NORMAL);
	imshow("Win1",src);
	
	//转化为灰度图像
	Mat src_gray;
	cvtColor(src,src_gray,COLOR_BGR2GRAY);
	namedWindow("Win2",WINDOW_NORMAL);
	imshow("Win2",src_gray);

	//转化为二值图像
	Mat src_bin;
	adaptiveThreshold(~src_gray,src_bin,255,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,7,0);
	namedWindow("Win3",WINDOW_NORMAL);
	imshow("Win3",src_bin);

	//开操作
	Mat StrElem = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
	morphologyEx(src_bin,dst,MORPH_OPEN,StrElem,Point(-1,-1),1);
	blur(dst,dst,Size(3,3));
	namedWindow("Win4",WINDOW_NORMAL);
	imshow("Win4",dst);
	
	waitKey(0);
	return 0;

}

程序结果:






























  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值