《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽

6.4 形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽

高级形态学变换,基于腐蚀与膨胀,利用morphologyEx函数实现

6.4.1 开运算

1.腐蚀后膨胀的过程,数学表达式:dst=open(src,element)=dilate(erode(src,element))
2.作用:消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界的同时不明显改变其面积

6.4.2 闭运算

1.膨胀后腐蚀的过程,数学表达式:dst=close(src,element)=erode(dilate(src,element))
2.作用:排除小型黑洞

6.4.3 形态学梯度

1.膨胀图与腐蚀图之差,数学表达式:dst=morph-grad(src,element)=dilate(src,element)-erode(src,element)
2.作用:将团块的边缘突出,保留物体边缘轮廓

6.4.4 顶帽(Top Hat)

1.原图像与开运算结果之差,数学表达式:dst=tophat(src,element)=src-open(src,element)
2.作用:开运算放大了裂缝或局部低亮度区域,所以顶帽突出了比原图轮廓周围区域更明亮的区域,用来分离比临近点亮一些的区域,在一幅大背景物品微小有规律的图像中,可以进行背景提取

6.4.5 黑帽(Black Hat)

1.闭运算结果与原图之差,数学表达式:dst=blackhhat(src,element)=close(src,element)-src
2.作用:黑帽突出了比原图轮廓周围区域更暗的区域,用来分离比临近点暗一些的区域,效果图有非常完美的轮廓

6.4.6 OpenCV源码核心API函数:morphologyEx()

1.函数原型

void morphologyEx(InputArray src,OutputArray dst,int op,InputArraykernel,Pointanchor=Point(-1,-1),intiterations=1,intborderType=BORDER_CONSTANT,constScalar& borderValue=morphologyDefaultBorderValue() );

2.参数说明
(1)输入图像
(2)目标图像
(3)形态学运算类型
《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第1张图片
(4)形态学运算内核,getStructuringElement函数配合使用
(5)锚的位置,默认(-1,-1)表示中心
(6)迭代使用函数次数,默认1
(7)用于推断图像外部像素的某种边界模式,默认BORDER_CONSTANT
(8)当边界为常数时的边界值,默认值morphologyDefaultValue()

6.4.7 综合示例

/* 
   效果:
   4个显示窗口,原始图,开/闭运算,腐蚀/膨胀,顶帽/黑帽
   滚动条控制形态学效果,迭代值为10的时候为中间点
   通过按键1、2、3及空格调节成不同的元素结构(矩形、椭圆、十字形)
*/
#include
#include
#include
#include
using namespace cv;
using namespace std;

//全局变量
Mat g_srcImage, g_dstImage;
int g_nElementShape = MORPH_RECT;//元素结构形状
//变量接收的TrackBar位置参数
int g_nMaxIterationNum = 10;
int g_nOpenCloseNum = 0;
int g_nErodeDilateNum = 0;
int g_nTopBlackHatNum = 0;

//全局函数
static void on_OpenClose(int, void*);
static void on_ErodeDilate(int, void*);
static void on_TopBlackHat(int, void*);
static void ShowHelpText();

int main()
{
	//改变console颜色
	system("color 3B");

	//显示提示信息
	ShowHelpText();
	
	//载入原图
	g_srcImage = imread("love.jpg");
	if (!g_srcImage.data)
	{
		printf("载入原图像失败~!\n");
		return false;
	}
	//显示原图
	namedWindow("【原始图】");
	imshow("【原始图】", g_srcImage);

	//创建三个窗口
	namedWindow("【开运算/闭运算】",1);
	namedWindow("【腐蚀/膨胀】",1);
	namedWindow("【顶帽/黑帽】",1);

	//参数赋值
	g_nOpenCloseNum = 9;
	g_nErodeDilateNum = 9;
	g_nTopBlackHatNum = 2;

	//创建滚动条
	createTrackbar("迭代值", "【开运算/闭运算】", &g_nOpenCloseNum, g_nMaxIterationNum * 2 + 1, on_OpenClose);
	createTrackbar("迭代值", "【腐蚀/膨胀】", &g_nErodeDilateNum, g_nMaxIterationNum * 2 + 1, on_ErodeDilate);
	createTrackbar("迭代值", "【顶帽/黑帽】", &g_nTopBlackHatNum, g_nMaxIterationNum * 2 + 1, on_TopBlackHat);

	//轮询获取按键信息
	while (1)
	{
		int c;
		//执行回调函数
		on_OpenClose(g_nOpenCloseNum, 0);
		on_ErodeDilate(g_nErodeDilateNum, 0);
		on_TopBlackHat(g_nTopBlackHatNum, 0);
		//获取按键
		c = waitKey(0);
		//按下键盘按键Q或ESC,程序退出
		if ((char)c == 'q' || (char)c == 27)
			break;
		//按下键盘按键1,使用椭圆结构元素MORPH_ELLIPSE
		if ((char)c == 49)//键盘1的ASII码为49
			g_nElementShape = MORPH_ELLIPSE;
		//按下键盘按键2,使用矩形结构元素MORPH_RECT
		else if ((char)c == 50)//键盘2的ASII码为50
			g_nElementShape = MORPH_RECT;
		//按下键盘按键3,使用十字形结构元素MORPH_CROSS
		else if ((char)c == 51)//键盘3的ASII码为51
			g_nElementShape = MORPH_CROSS;
		//按下键盘按键space,在矩形、椭圆、十字形结构元素中循环
		else if ((char)c == ' ')
			g_nElementShape = (g_nElementShape + 1) % 3;
	}
	return 0;
}
//【开运算/闭运算】窗口回调函数
static void on_OpenClose(int, void*)
{
	//偏移量定义(滑动条以g_nMaxIterationNum点为原点,计算偏移量(<0)绝对值为开运算度,偏移量(>0)绝对值为闭运算度
	int offset = g_nOpenCloseNum - g_nMaxIterationNum;//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
	//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
	//进行操作
	if (offset < 0)  //g_nOpenCloseNum=0~9
		morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
	else             //g_OpenCloseNum=10~21
		morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
	//显示图像
	imshow("【开运算/闭运算】", g_dstImage);
}
//【腐蚀/膨胀】窗口回调函数
static void on_ErodeDilate(int, void*)
{
	//偏移量定义(滑动条以g_nMaxIterationNum点为原点,计算偏移量(<0)绝对值为腐蚀度,偏移量(>0)绝对值为膨胀度
	int offset = g_nErodeDilateNum - g_nMaxIterationNum;//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
	//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
	//进行操作
	if (offset < 0)  //g_nErodeDilateNum=0~9
		erode(g_srcImage, g_dstImage, element);
	else             //g_nErodeDilateNum=10~21
		dilate(g_srcImage, g_dstImage, element);
	//显示图像
	imshow("【腐蚀/膨胀】", g_dstImage);
}
//【顶帽运算/黑帽运算】窗口回调函数
static void on_TopBlackHat(int, void*)
{
	//偏移量定义(滑动条以g_nMaxIterationNum点为原点,计算偏移量(<0)绝对值为顶帽度,偏移量(>0)绝对值为黑帽度
	int offset = g_nTopBlackHatNum - g_nMaxIterationNum;//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
	//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
	//进行操作
	if (offset < 0)  //g_nTopBlackHatNum=0~9
		morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
	else             //g_nTopBlackHatNum=10~21
		morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
	//显示图像
	imshow("【顶帽/黑帽】", g_dstImage);
}
static void ShowHelpText()
{
	printf("--------------------------------------------------------------------\n");
	printf("请调整滑动条观察图像效果\n");
	printf("按键操作说明:\n");
	printf("\t\t键盘按键[ESC]或[Q]-退出程序\n");
	printf("\t\t键盘按键[1]-使用椭圆结构元素\n");
	printf("\t\t键盘按键[2]-使用矩形结构元素\n");
	printf("\t\t键盘按键[3]-使用十字形结构元素\n");
	printf("\t\t键盘按键[space]-在巨型、椭圆、十字形结构元素中循环\n");
	printf("--------------------------------------------------------------------\n");
}

运行效果
《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第2张图片  《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第3张图片
《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第4张图片《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第5张图片《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第6张图片《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第7张图片
《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第8张图片《OpenCV3编程入门》学习笔记6 图像处理(四)形态学滤波(2):开运算、闭运算、形态学梯度、顶帽、黑帽_第9张图片

你可能感兴趣的:(OpenCV)