《Open CV3编程入门》学习笔记7

最基本形态学操作:腐蚀与膨胀

实现功能:消除噪声;分割出独立的图像元素,在图像中连接相邻的元素;寻找图像中的明显的极大值区域或极小值区域;求出图像的梯度;

腐蚀膨胀针对高亮部分;膨胀就是利用一形状的核与图像卷积,即计算出核内覆盖的图像区域的像素点中的最大值,并将其赋给锚点,结果就会使图像中高亮的部分延伸扩大,腐蚀正好相反。

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;


Mat g_srcImage, g_dstImage;//原始图和效果图
int g_nTrackbarNumer = 0;//0表示腐蚀erode, 1表示膨胀dilate
int g_nStructElementSize = 3; //结构元素(内核矩阵)的尺寸



void Process();//膨胀和腐蚀的处理函数
void on_TrackbarNumChange(int, void *);//回调函数
void on_ElementSizeChange(int, void *);//回调函数
void ShowHelpText();


int main( )
{


	//载入原图
	g_srcImage = imread("1.jpg");
	if( !g_srcImage.data ) { printf("读取srcImage错误~! \n"); return false; }



	//显示原始图
	namedWindow("【原始图】");
	imshow("【原始图】", g_srcImage);

	//进行初次腐蚀操作并显示效果图,因为在滑动条未动时,不调用腐蚀膨胀函数
	namedWindow("【效果图】");
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));
	erode(g_srcImage, g_dstImage, element);
	imshow("【效果图】", g_dstImage);

	//创建轨迹条
	createTrackbar("腐蚀/膨胀", "【效果图】", &g_nTrackbarNumer, 1, on_TrackbarNumChange);
	createTrackbar("内核尺寸", "【效果图】", &g_nStructElementSize, 21, on_ElementSizeChange);

	//输出一些帮助信息
	cout<<endl<<"\t运行成功,请调整滚动条观察图像效果~\n\n"
		<<"\t按下“q”键时,程序退出。\n";

	//轮询获取按键信息,若下q键,程序退出
	while(char(waitKey(1)) != 'q') {}

	return 0;
}

//-----------------------------【Process( )函数】------------------------------------
//		描述:进行自定义的腐蚀和膨胀操作
//-----------------------------------------------------------------------------------------
void Process() 
{
	//获取自定义核
	Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));
	/*getStructuringElement该函数会返回指定形状和尺寸的结构元素(内核矩阵);
	第一个参数:内核的形状:可选   矩阵:MORPH_RECT;交叉形(十字形):MORPH_CROSS;椭圆形:MORPH_ELLIPSE;十字形唯一依赖于锚点的位置,而其他只是影响运算结果的偏移
	第二个参数:内核的尺寸Size(width,height)
	第三个参数:锚点的位置,可用默认值Point(-1,-1)表示锚点位于中心*/
	
	//进行腐蚀或膨胀操作
	if(g_nTrackbarNumer == 0) {    
		erode(g_srcImage, g_dstImage, element);
		/*腐蚀:第一个参数:输入图像,图像的通道的数量可以是任意的,但图形的深度应为CV_8U、CV_16U、CV_16S、CV_32F、CV_64F其中之一;
		第二个参数为输出图像,需要与源图像一样的尺寸和类型;
		第三个参数:InputArray类型的kernel,膨胀操作的核。当为NULL时,表示的是使用参考点位于中心的3*3的核
		第四个参数:锚点的位置,前面核已定义了锚点,此处再定义不知是重复,还是锚点再次位移?
		第五个参数:迭代的次数,有默认值1;
		第六个参数:边界同以前笔记说明
		第七个参数:constScalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般不管*/
	}
	else {
		dilate(g_srcImage, g_dstImage, element);
		/*膨胀:第一个参数:输入图像,图像的通道的数量可以是任意的,但图形的深度应为CV_8U、CV_16U、CV_16S、CV_32F、CV_64F其中之一;
		第二个参数为输出图像,需要与源图像一样的尺寸和类型;
		第三个参数:InputArray类型的kernel,膨胀操作的核。当为NULL时,表示的是使用参考点位于中心的3*3的核
		第四个参数:锚点的位置;
		第五个参数:迭代的次数,有默认值1;
		第六个参数:边界模式同以前笔记说明
		第七个参数:constScalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue()*/
	}
	//腐蚀与膨胀函数一般只需填前面三个参数,后面四个都有默认值,而且往往结合getStrcturingElement一起使用

	//显示效果图
	imshow("【效果图】", g_dstImage);
}


//-----------------------------【on_TrackbarNumChange( )函数】------------------------------------
//		描述:腐蚀和膨胀之间切换开关的回调函数
//-----------------------------------------------------------------------------------------------------
void on_TrackbarNumChange(int, void *) 
{
	//腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}


//-----------------------------【on_ElementSizeChange( )函数】-------------------------------------
//		描述:腐蚀和膨胀操作内核改变时的回调函数
//-----------------------------------------------------------------------------------------------------
void on_ElementSizeChange(int, void *)
{
	//内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
	Process();
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值