关于图像形态学在《OpenCV3编程入门》学习笔记六:图像处理 中涉及到过,但给的例程不是特别好。这里再给出一个比较直观的例子。
源码:
#include<opencv2/opencv.hpp>
#include<iostream>
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()
{
g_srcImage = imread("poster_geometry.jpg");
namedWindow("【原始图】");
imshow("【原始图】", g_srcImage);
//创建三个窗口
namedWindow("【开运算/闭运算】");
namedWindow("【腐蚀/膨胀】");
namedWindow("【顶帽/黑帽】");
//参数赋值
g_nOpenCloseNum = 9;
g_nErodeDilateNum = 9;
g_nTopBlackHatNum = 9;
//分别为三个窗口创建滚动条
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(1);
if ((char)c == 'q' || (char)c == 27) //按下键盘按键q或ESC,程序退出
break;
else if ((char)c == '1') //按下键盘按键1,使用椭圆结构元素MORPH_ELLIPSE
g_nElementShape = MORPH_ELLIPSE;
else if ((char)c == '2') //按下键盘按键2,使用矩形结构元素MORPH_RECT
g_nElementShape = MORPH_RECT;
else if ((char)c == '3') //按下键盘按键3,使用十字形结构元素MORPH_CROSS
g_nElementShape = MORPH_CROSS;
else if ((char)c == ' ') //按下键盘按键space,在矩形、椭圆、十字形结构元素中循环
g_nElementShape = (g_nElementShape+1)%3;
}
return 0;
}
static 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));//自定义核
if (offset < 0)
morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
else
morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
imshow("【开运算/闭运算】", g_dstImage);
}
static 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));//自定义核
if (offset < 0)
morphologyEx(g_srcImage, g_dstImage, MORPH_ERODE, element);
else
morphologyEx(g_srcImage, g_dstImage, MORPH_DILATE, element);
imshow("【腐蚀/膨胀】", g_dstImage);
}
/*
顶帽:原图像与开运算结果之差
黑帽:原图像与闭运算结果之差
*/
static 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));//自定义核
if (offset < 0)
morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
else
morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
imshow("【顶帽/黑帽】", g_dstImage);
}
素材:
效果图:
提示:
关于图像形态学部分,左飞的《数字图像处理 原理与实践(MATLAB版)》第5章图像的形态学处理介绍的比较详细。