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);