element_shape = MORPH_ELLIPSE;
element_shape = MORPH_RECT
element_shape = MORPH_CROSS;
// 包含必要的OpenCV头文件
#include "opencv2/imgproc.hpp" // 图像处理
#include "opencv2/imgcodecs.hpp" // 图像编码解码
#include "opencv2/highgui.hpp" // 高层GUI
#include <stdlib.h> // 标准库函数
#include <stdio.h> // 标准输入输出
#include <string> // 字符串操作
// 使用标准的OpenCV命名空间
using namespace cv;
// 功能帮助信息的静态函数
static void help(char** argv)
{
// 打印帮助信息
printf("\nShow off image morphology: erosion, dialation, open and close\n"
"Call:\n %s [image]\n"
"This program also shows use of rect, ellipse and cross kernels\n\n", argv[0]);
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tr - use rectangle structuring element\n"
"\te - use elliptic structuring element\n"
"\tc - use cross-shaped structuring element\n"
"\tSPACE - loop through all the options\n" );
}
// 声明原图像和结果图像的矩阵
Mat src, dst;
// 默认形状为矩形
int element_shape = MORPH_RECT;
// 进行形态学操作的最大迭代数
int max_iters = 10;
// 开运算和闭运算的位置参数
int open_close_pos = 0;
// 腐蚀和膨胀的位置参数
int erode_dilate_pos = 0;
// 用于开运算/闭运算的轨迹条的回调函数
static void OpenClose(int, void*)
{
int n = open_close_pos;
int an = abs(n);
// 创建结构元素
Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an) );
if( n < 0 )
// 执行开运算
morphologyEx(src, dst, MORPH_OPEN, element);
else
// 执行闭运算
morphologyEx(src, dst, MORPH_CLOSE, element);
// 显示结果
imshow("Open/Close",dst);
}
// 用于腐蚀/膨胀的轨迹条的回调函数
static void ErodeDilate(int, void*)
{
int n = erode_dilate_pos;
int an = abs(n);
// 创建结构元素
Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an) );
if( n < 0 )
// 执行腐蚀
erode(src, dst, element);
else
// 执行膨胀
dilate(src, dst, element);
// 显示结果
imshow("Erode/Dilate",dst);
}
// 主函数
int main( int argc, char** argv )
{
// 解析命令行参数
cv::CommandLineParser parser(argc, argv, "{help h||}{ @image | baboon.jpg | }");
if (parser.has("help"))
{
// 如果有帮助命令,显示帮助
help(argv);
return 0;
}
// 获取文件名
std::string filename = samples::findFile(parser.get<std::string>("@image"));
// 读取图片
if( (src = imread(filename,IMREAD_COLOR)).empty() )
{
// 图片为空则显示帮助
help(argv);
return -1;
}
// 创建窗口显示输出图像
namedWindow("Open/Close",1);
namedWindow("Erode/Dilate",1);
// 设置轨迹条位置
open_close_pos = erode_dilate_pos = max_iters;
createTrackbar("iterations", "Open/Close",&open_close_pos,max_iters*2+1,OpenClose);
setTrackbarMin("iterations", "Open/Close", -max_iters);
setTrackbarMax("iterations", "Open/Close", max_iters);
setTrackbarPos("iterations", "Open/Close", 0);
createTrackbar("iterations", "Erode/Dilate",&erode_dilate_pos,max_iters*2+1,ErodeDilate);
setTrackbarMin("iterations", "Erode/Dilate", -max_iters);
setTrackbarMax("iterations", "Erode/Dilate", max_iters);
setTrackbarPos("iterations", "Erode/Dilate", 0);
// 主循环
for(;;)
{
// 根据轨迹条位置执行开闭运算和腐蚀膨胀
OpenClose(open_close_pos, 0);
ErodeDilate(erode_dilate_pos, 0);
// 按键响应
char c = (char)waitKey(0);
if( c == 27 ) // ESC键退出
break;
// 更换结构元素的形状
if( c == 'e' )
element_shape = MORPH_ELLIPSE;
else if( c == 'r' )
element_shape = MORPH_RECT;
else if( c == 'c' )
element_shape = MORPH_CROSS;
else if( c == ' ' )
element_shape = (element_shape + 1) % 3;
}
return 0;
}
Mat element = getStructuringElement(element_shape, Size(an*2+1, an*2+1), Point(an, an) );
morphologyEx(src, dst, MORPH_OPEN, element);
morphologyEx(src, dst, MORPH_CLOSE, element);
erode(src, dst, element);
dilate(src, dst, element);