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 // 标准库函数

#include // 标准输入输出

#include // 字符串操作

// 使用标准的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("@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);