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

原理

 

 

 

程序

#includeusing 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_ELLIPSEif ((char)c == 49)	//键盘按键1的ASCII码为49{printf("使用椭圆结构元素");g_nElementShape = MORPH_ELLIPSE;}//按下键盘按键2,使用矩形(Rectangle)结构元素MORPH_RECTelse if ((char)c == 50)	//键盘按键2的ASCII码为50{printf("使用矩形结构元素");g_nElementShape = MORPH_RECT;}//按下键盘按键3,使用十字形(Cross-shaped)结构元素MORPH_RECTelse 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);
}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部