openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽

原理

 openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽_第1张图片

 openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽_第2张图片

 openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽_第3张图片

openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽_第4张图片

openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽_第5张图片

openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽_第6张图片

openCV学习笔记(二十三) —— 形态学滤波—— 开运算、闭运算、形态学梯度、顶帽、黑帽_第7张图片

程序

#include

using namespace std;
using namespace cv;

/*
	宏定义
*/
#define ORIGINAL_WINDOW_NAME	"【原始图】"
#define OPEN_CLOSE_WINDOW_NAME	"【开运算/闭运算】"
#define ERODE_DILATE_WINDOW_NAME	"【腐蚀/膨胀】"
#define TOP_BLACK_HAT_WINDOW_NAME	"【顶帽/黑帽】"
#define GRADIENT_WINDOW_NAME	"形态学梯度"

/*
	全局变量声明
*/
Mat g_srcImage, g_dstImage;	//原始图和效果图
int g_nElementShape = MORPH_RECT;	//元素结构的形状

									//变量接收的TrackBar位置参数
int g_nMaxIteratorNum = 10;
int g_nOpenCloseNum = 0;
int g_nErodeDilateNum = 0;
int g_nTopBlackHatNum = 0;
int g_nGradientNum = 0;

/*
	全局函数声明
*/
static void onOpenClose(int, void *);
static void onErodeDilate(int, void *);
static void onTopBlackHat(int, void *);
static void onGradient(int, void *);

/*
	main()函数
*/
int main()
{
	//载入原图
	g_srcImage = imread("test.jpg");
	if (!g_srcImage.data)
	{
		printf("读取srcImage错误!\n");
		return -1;
	}

	//显示原始图
	namedWindow(ORIGINAL_WINDOW_NAME);
	imshow(ORIGINAL_WINDOW_NAME, g_srcImage);

	//创建四个窗口
	namedWindow(OPEN_CLOSE_WINDOW_NAME);
	namedWindow(ERODE_DILATE_WINDOW_NAME);
	namedWindow(TOP_BLACK_HAT_WINDOW_NAME);
	namedWindow(GRADIENT_WINDOW_NAME);

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

	//分别为四个窗口创建滚动条
	createTrackbar("迭代值", OPEN_CLOSE_WINDOW_NAME, &g_nOpenCloseNum, g_nMaxIteratorNum * 2 + 1, onOpenClose);
	createTrackbar("迭代值", ERODE_DILATE_WINDOW_NAME, &g_nErodeDilateNum, g_nMaxIteratorNum * 2 + 1, onErodeDilate);
	createTrackbar("迭代值", TOP_BLACK_HAT_WINDOW_NAME, &g_nTopBlackHatNum, g_nMaxIteratorNum * 2 + 1, onTopBlackHat);
	createTrackbar("迭代值", GRADIENT_WINDOW_NAME, &g_nGradientNum, g_nMaxIteratorNum * 2 + 1, onGradient);

	//轮询获取按键信息
	while (true)
	{
		int c;

		//执行回调函数
		onOpenClose(g_nOpenCloseNum, NULL);
		onErodeDilate(g_nErodeDilateNum, NULL);
		onTopBlackHat(g_nTopBlackHatNum, NULL);

		//获取按键
		c = waitKey(0);

		//按下键盘按键Q或者ESC, 程序退出
		if ((char)c == 'q' || (char)c == 27)
		{
			break;
		}

		//按下键盘按键1,使用椭圆(Ellipse)结构元素MORPH_ELLIPSE
		if ((char)c == 49)	//键盘按键1的ASCII码为49
		{
			printf("使用椭圆结构元素");
			g_nElementShape = MORPH_ELLIPSE;
		}
		//按下键盘按键2,使用矩形(Rectangle)结构元素MORPH_RECT
		else if ((char)c == 50)	//键盘按键2的ASCII码为50
		{
			printf("使用矩形结构元素");
			g_nElementShape = MORPH_RECT;
		}
		//按下键盘按键3,使用十字形(Cross-shaped)结构元素MORPH_RECT
		else if ((char)c == 51)	//键盘按键3的ASCII码为50
		{
			printf("使用十字形结构元素");
			g_nElementShape = MORPH_CROSS;
		}
		//按下键盘空格,在矩形、椭圆、十字形结构元素中循环
		else if ((char)c == ' ')
		{
			printf("在矩形、椭圆、十字形结构元素中循环");
			g_nElementShape = (g_nElementShape + 1) % 3;
		}
	}

	destroyAllWindows();

	return 0;
}

/*
	开运算/闭运算窗口的回调函数
*/
static void onOpenClose(int, void *)
{
	//偏移量的定义
	int offset = g_nOpenCloseNum - g_nMaxIteratorNum;	//偏移量
	int AbsoluteOffset = offset > 0 ? offset : -offset;	//偏移量绝对值

														//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(AbsoluteOffset * 2 + 1, AbsoluteOffset * 2 + 1), Point(AbsoluteOffset, AbsoluteOffset));

	//进行操作
	if (offset < 0)
	{
		printf("开运算...\n");
		morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
	}
	else
	{
		printf("闭运算...\n");
		morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
	}

	imshow(OPEN_CLOSE_WINDOW_NAME, g_dstImage);
}

/*
腐蚀/膨胀窗口的回调函数
*/
static void onErodeDilate(int, void *)
{
	//偏移量的定义
	int offset = g_nErodeDilateNum - g_nMaxIteratorNum;	//偏移量
	int AbsoluteOffset = offset > 0 ? offset : -offset;	//偏移量绝对值

														//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(AbsoluteOffset * 2 + 1, AbsoluteOffset * 2 + 1), Point(AbsoluteOffset, AbsoluteOffset));

	//进行操作
	if (offset < 0)
	{
		printf("腐蚀运算...\n");
		erode(g_srcImage, g_dstImage, element);
	}
	else
	{
		printf("膨胀运算...\n");
		dilate(g_srcImage, g_dstImage, element);
	}

	imshow(ERODE_DILATE_WINDOW_NAME, g_dstImage);
}

/*
顶帽/黑帽窗口的回调函数
*/
static void onTopBlackHat(int, void *)
{
	//偏移量的定义
	int offset = g_nTopBlackHatNum - g_nMaxIteratorNum;	//偏移量
	int AbsoluteOffset = offset > 0 ? offset : -offset;	//偏移量绝对值

														//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(AbsoluteOffset * 2 + 1, AbsoluteOffset * 2 + 1), Point(AbsoluteOffset, AbsoluteOffset));

	//进行操作
	if (offset < 0)
	{
		printf("顶帽运算...\n");
		morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
	}
	else
	{
		printf("黑帽运算...\n");
		morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
	}

	imshow(TOP_BLACK_HAT_WINDOW_NAME, g_dstImage);
}


/*
形态学梯度窗口的回调函数
*/
static void onGradient(int, void *)
{
	//偏移量的定义
	int offset = g_nGradientNum - g_nMaxIteratorNum;	//偏移量
	int AbsoluteOffset = offset > 0 ? offset : -offset;	//偏移量绝对值

														//自定义核
	Mat element = getStructuringElement(g_nElementShape, Size(AbsoluteOffset * 2 + 1, AbsoluteOffset * 2 + 1), Point(AbsoluteOffset, AbsoluteOffset));

	//进行操作
	printf("形态学梯度运算...\n");
	morphologyEx(g_srcImage, g_dstImage, MORPH_GRADIENT, element);

	imshow(GRADIENT_WINDOW_NAME, g_dstImage);
}

 

你可能感兴趣的:(openCV)