OpenCV之形态学滤波例程

代码

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/video.hpp>
 
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*);

int main(int argc, char** argv)
{
	//载入原图
	g_srcImage = imread("700levi.jpg");
	namedWindow("原始图");
	imshow("原始图", g_srcImage);

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

	//参数赋值
	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_nOpenCloseNum, 0);
		on_TopBlackHat(g_nOpenCloseNum, 0);
		//获取按键
		c = waitKey(0);
		if (char(c) == 'q' || char(c) == 27)
		{
			break;
		}
		if (char(c) == 49)// 1  切换内核的形状椭圆形
		{
			g_nElementShape = MORPH_ELLIPSE;
		}
		else if(char(c) == 50) { //2 切换为矩形
			g_nElementShape = MORPH_RECT;
		}else if (char(c) == 51){// 3 切换为交叉形
			g_nElementShape = MORPH_CROSS;
		}else if (char(c) == ' ') {
			//循环
			g_nElementShape = (g_nElementShape + 1) % 3;
		}
	}

	return 0;
}

void on_OpenClose(int, void*) {
	//偏移量定义
	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)
	{
		morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
	}
	else
	{
		morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
	}
	imshow("开闭运算", g_dstImage);
}
void on_ErodeDilate(int, void*) {
	//偏移量定义
	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)
	{
		erode(g_srcImage, g_dstImage, element);
	}
	else
	{
		dilate(g_srcImage, g_dstImage, element);
	}
	imshow("腐蚀膨胀", g_dstImage);
}
void on_TopBlackHat(int, void*) {
	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)
	{
		morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
	}
	else
	{
		morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
	}
	imshow("顶帽黑帽", g_dstImage);

}

效果

补充

这个例程可玩性还是挺高的, 可以通过按键123来改变内核的形状, 也可以通过滚动条来控制内核的大小.后面需要继续琢磨总结.

猜你喜欢

转载自blog.csdn.net/sono_io/article/details/124755246