OpenCV 图像处理(形态学滤波:腐蚀与膨胀,开运算闭运算形态学梯度顶帽黑帽)
Posted ybqjymy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV 图像处理(形态学滤波:腐蚀与膨胀,开运算闭运算形态学梯度顶帽黑帽)相关的知识,希望对你有一定的参考价值。
腐蚀与膨胀
膨胀(求局部最大值)(dilate函数)
1 #include <opencv2/core/core.hpp>
2 #include <opencv2/highgui/highgui.hpp>
3 #include <opencv2/imgproc/imgproc.hpp>
4 #include <iostream>
5
6 //-----------------------------------【命名空间声明部分】---------------------------------------
7 // 描述:包含程序所使用的命名空间
8 //-----------------------------------------------------------------------------------------------
9 using namespace std;
10 using namespace cv;
11
12 //-----------------------------------【main( )函数】--------------------------------------------
13 // 描述:控制台应用程序的入口函数,我们的程序从这里开始
14 //-----------------------------------------------------------------------------------------------
15 int main()
16 {
17
18 //载入原图
19 Mat image = imread("1.jpg");
20
21 //创建窗口
22 namedWindow("【原图】膨胀操作");
23 namedWindow("【效果图】膨胀操作");
24
25 //显示原图
26 imshow("【原图】膨胀操作", image);
27
28 //进行膨胀操作
29 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
30 Mat out;
31 dilate(image, out, element);
32
33 //显示效果图
34 imshow("【效果图】膨胀操作", out);
35
36 waitKey(0);
37
38 return 0;
39 }
腐蚀(求局部最小值)(erode)
1 #include <opencv2/highgui/highgui.hpp>
2 #include <opencv2/imgproc/imgproc.hpp>
3 using namespace cv;
4
5 //-----------------------------------【main( )函数】--------------------------------------------
6 // 描述:控制台应用程序的入口函数,我们的程序从这里开始
7 //-----------------------------------------------------------------------------------------------
8 int main()
9 {
10 //载入原图
11 Mat srcImage = imread("1.jpg");
12 //显示原图
13 imshow("【原图】腐蚀操作", srcImage);
14 //进行腐蚀操作
15 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
16 Mat dstImage;
17 erode(srcImage, dstImage, element);
18 //显示效果图
19 imshow("【效果图】腐蚀操作", dstImage);
20 waitKey(0);
21
22 return 0;
23 }
1 #include <opencv2/highgui/highgui.hpp>
2 #include <opencv2/imgproc/imgproc.hpp>
3 using namespace cv;
4
5 //-----------------------------------【main( )函数】--------------------------------------------
6 // 描述:控制台应用程序的入口函数,我们的程序从这里开始
7 //-----------------------------------------------------------------------------------------------
8 int main()
9 {
10 //载入原图
11 Mat srcImage = imread("1.jpg");
12 //显示原图
13 imshow("【原图】腐蚀操作", srcImage);
14 //进行腐蚀操作
15 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
16 Mat dstImage;
17 erode(srcImage, dstImage, element);
18 //显示效果图
19 imshow("【效果图】腐蚀操作", dstImage);
20 waitKey(0);
21
22 return 0;
23 }
腐蚀与膨胀滑动条实例
1 #include <opencv2/opencv.hpp>
2 #include <opencv2/highgui/highgui.hpp>
3 #include <opencv2/imgproc/imgproc.hpp>
4 #include <iostream>
5 using namespace std;
6 using namespace cv;
7
8
9 //-----------------------------------【全局变量声明部分】--------------------------------------
10 // 描述:全局变量声明
11 //-----------------------------------------------------------------------------------------------
12 Mat g_srcImage, g_dstImage;//原始图和效果图
13 int g_nTrackbarNumer = 0;//0表示腐蚀erode, 1表示膨胀dilate
14 int g_nStructElementSize = 3; //结构元素(内核矩阵)的尺寸
15
16
17 //-----------------------------------【全局函数声明部分】--------------------------------------
18 // 描述:全局函数声明
19 //-----------------------------------------------------------------------------------------------
20 void Process();//膨胀和腐蚀的处理函数
21 void on_TrackbarNumChange(int, void *);//回调函数
22 void on_ElementSizeChange(int, void *);//回调函数
23 void ShowHelpText();
24
25 //-----------------------------------【main( )函数】--------------------------------------------
26 // 描述:控制台应用程序的入口函数,我们的程序从这里开始
27 //-----------------------------------------------------------------------------------------------
28 int main()
29 {
30 //改变console字体颜色
31 system("color 2F");
32
33 //载入原图
34 g_srcImage = imread("1.jpg");
35 if (!g_srcImage.data) { printf("读取srcImage错误~!
"); return false; }
36
37 ShowHelpText();
38
39 //显示原始图
40 namedWindow("【原始图】");
41 imshow("【原始图】", g_srcImage);
42
43 //进行初次腐蚀操作并显示效果图
44 namedWindow("【效果图】");
45 //获取自定义核
46 Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));
47 erode(g_srcImage, g_dstImage, element);
48 imshow("【效果图】", g_dstImage);
49
50 //创建轨迹条
51 createTrackbar("腐蚀/膨胀", "【效果图】", &g_nTrackbarNumer, 1, on_TrackbarNumChange);
52 createTrackbar("内核尺寸", "【效果图】", &g_nStructElementSize, 21, on_ElementSizeChange);
53
54 //输出一些帮助信息
55 cout << endl << " 运行成功,请调整滚动条观察图像效果~
"
56 << " 按下“q”键时,程序退出。
";
57
58 //轮询获取按键信息,若下q键,程序退出
59 while (char(waitKey(1)) != ‘q‘) {}
60
61 return 0;
62 }
63
64 //-----------------------------【Process( )函数】------------------------------------
65 // 描述:进行自定义的腐蚀和膨胀操作
66 //-----------------------------------------------------------------------------------------
67 void Process()
68 {
69 //获取自定义核
70 Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));
71
72 //进行腐蚀或膨胀操作
73 if (g_nTrackbarNumer == 0) {
74 erode(g_srcImage, g_dstImage, element);
75 }
76 else {
77 dilate(g_srcImage, g_dstImage, element);
78 }
79
80 //显示效果图
81 imshow("【效果图】", g_dstImage);
82 }
83
84
85 //-----------------------------【on_TrackbarNumChange( )函数】------------------------------------
86 // 描述:腐蚀和膨胀之间切换开关的回调函数
87 //-----------------------------------------------------------------------------------------------------
88 void on_TrackbarNumChange(int, void *)
89 {
90 //腐蚀和膨胀之间效果已经切换,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
91 Process();
92 }
93
94
95 //-----------------------------【on_ElementSizeChange( )函数】-------------------------------------
96 // 描述:腐蚀和膨胀操作内核改变时的回调函数
97 //-----------------------------------------------------------------------------------------------------
98 void on_ElementSizeChange(int, void *)
99 {
100 //内核尺寸已改变,回调函数体内需调用一次Process函数,使改变后的效果立即生效并显示出来
101 Process();
102 }
103
104
105 //-----------------------------------【ShowHelpText( )函数】-----------------------------
106 // 描述:输出一些帮助信息
107 //----------------------------------------------------------------------------------------------
108 void ShowHelpText()
109 {
110 //输出欢迎信息和OpenCV版本
111
112 printf("
当前使用的OpenCV版本为:" CV_VERSION);
113 printf("
----------------------------------------------------------------------------
");
114 }
开运算、闭运算、形态学梯度、顶帽、黑帽(morphologyEx函数)
开运算(先腐蚀后膨胀)
闭运算(先膨胀后腐蚀)
形态学梯度(膨胀图与腐蚀图之差)
顶帽(原图像与开运算之差)
黑帽(闭运算与原图像之差)
核心API函数(morphologyEx函数)
范例
1 #include <opencv2/opencv.hpp>
2 #include <opencv2/highgui/highgui.hpp>
3 #include <opencv2/imgproc/imgproc.hpp>
4 using namespace cv;
5
6
7 //-----------------------------------【main( )函数】------------------------------------------
8 // 描述:控制台应用程序的入口函数,我们的程序从这里开始
9 //-----------------------------------------------------------------------------------------------
10 int main( )
11 {
12 //载入原始图
13 Mat image = imread("1.jpg"); //工程目录下应该有一张名为1.jpg的素材图
14 //创建窗口
15 namedWindow("【原始图】形态学梯度");
16 namedWindow("【效果图】形态学梯度");
17 //显示原始图
18 imshow("【原始图】形态学梯度", image);
19 //定义核
20 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
21 //进行形态学操作
22 morphologyEx(image, image, MORPH_GRADIENT, element);
23 //显示效果图
24 imshow("【效果图】形态学梯度", image);
25
26 waitKey(0);
27
28 return 0;
29 }
综合实例
1 #include <opencv2/opencv.hpp>
2 #include <opencv2/highgui/highgui.hpp>
3 #include <opencv2/imgproc/imgproc.hpp>
4 using namespace std;
5 using namespace cv;
6
7
8 //-----------------------------------【全局变量声明部分】-----------------------------------
9 // 描述:全局变量声明
10 //-----------------------------------------------------------------------------------------------
11 Mat g_srcImage, g_dstImage;//原始图和效果图
12 int g_nElementShape = MORPH_RECT;//元素结构的形状
13
14 //变量接收的TrackBar位置参数
15 int g_nMaxIterationNum = 10;
16 int g_nOpenCloseNum = 0;
17 int g_nErodeDilateNum = 0;
18 int g_nTopBlackHatNum = 0;
19
20
21
22 //-----------------------------------【全局函数声明部分】--------------------------------------
23 // 描述:全局函数声明
24 //-----------------------------------------------------------------------------------------------
25 static void on_OpenClose(int, void*);//回调函数
26 static void on_ErodeDilate(int, void*);//回调函数
27 static void on_TopBlackHat(int, void*);//回调函数
28 static void ShowHelpText();
29
30
31 //-----------------------------------【main( )函数】--------------------------------------------
32 // 描述:控制台应用程序的入口函数,我们的程序从这里开始
33 //-----------------------------------------------------------------------------------------------
34 int main()
35 {
36 //改变console字体颜色
37 system("color 2F");
38
39 ShowHelpText();
40
41 //载入原图
42 g_srcImage = imread("1.jpg");
43 if (!g_srcImage.data) { printf("Oh,no,读取srcImage错误~!
"); return false; }
44
45 //显示原始图
46 namedWindow("【原始图】");
47 imshow("【原始图】", g_srcImage);
48
49 //创建三个窗口
50 namedWindow("【开运算/闭运算】", 1);
51 namedWindow("【腐蚀/膨胀】", 1);
52 namedWindow("【顶帽/黑帽】", 1);
53
54 //参数赋值
55 g_nOpenCloseNum = 9;
56 g_nErodeDilateNum = 9;
57 g_nTopBlackHatNum = 2;
58
59 //分别为三个窗口创建滚动条
60 createTrackbar("迭代值", "【开运算/闭运算】", &g_nOpenCloseNum, g_nMaxIterationNum * 2 + 1, on_OpenClose);
61 createTrackbar("迭代值", "【腐蚀/膨胀】", &g_nErodeDilateNum, g_nMaxIterationNum * 2 + 1, on_ErodeDilate);
62 createTrackbar("迭代值", "【顶帽/黑帽】", &g_nTopBlackHatNum, g_nMaxIterationNum * 2 + 1, on_TopBlackHat);
63
64 //轮询获取按键信息
65 while (1)
66 {
67 int c;
68
69 //执行回调函数
70 on_OpenClose(g_nOpenCloseNum, 0);
71 on_ErodeDilate(g_nErodeDilateNum, 0);
72 on_TopBlackHat(g_nTopBlackHatNum, 0);
73
74 //获取按键
75 c = waitKey(0);
76
77 //按下键盘按键Q或者ESC,程序退出
78 if ((char)c == ‘q‘ || (char)c == 27)
79 break;
80 //按下键盘按键1,使用椭圆(Elliptic)结构元素结构元素MORPH_ELLIPSE
81 if ((char)c == 49)//键盘按键1的ASII码为49
82 g_nElementShape = MORPH_ELLIPSE;
83 //按下键盘按键2,使用矩形(Rectangle)结构元素MORPH_RECT
84 else if ((char)c == 50)//键盘按键2的ASII码为50
85 g_nElementShape = MORPH_RECT;
86 //按下键盘按键3,使用十字形(Cross-shaped)结构元素MORPH_CROSS
87 else if ((char)c == 51)//键盘按键3的ASII码为51
88 g_nElementShape = MORPH_CROSS;
89 //按下键盘按键space,在矩形、椭圆、十字形结构元素中循环
90 else if ((char)c == ‘ ‘)
91 g_nElementShape = (g_nElementShape + 1) % 3;
92 }
93
94 return 0;
95 }
96
97
98 //-----------------------------------【on_OpenClose( )函数】----------------------------------
99 // 描述:【开运算/闭运算】窗口的回调函数
100 //-----------------------------------------------------------------------------------------------
101 static void on_OpenClose(int, void*)
102 {
103 //偏移量的定义
104 int offset = g_nOpenCloseNum - g_nMaxIterationNum;//偏移量
105 int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
106 //自定义核
107 Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
108 //进行操作
109 if (offset < 0)
110 //此句代码的OpenCV2版为:
111 //morphologyEx(g_srcImage, g_dstImage, CV_MOP_OPEN, element);
112 //此句代码的OpenCV3版为:
113 morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
114 else
115 //此句代码的OpenCV2版为:
116 //morphologyEx(g_srcImage, g_dstImage, CV_MOP_CLOSE, element);
117 //此句代码的OpenCV3版为:
118 morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
119
120
121
122 //显示图像
123 imshow("【开运算/闭运算】", g_dstImage);
124 }
125
126
127 //-----------------------------------【on_ErodeDilate( )函数】----------------------------------
128 // 描述:【腐蚀/膨胀】窗口的回调函数
129 //-----------------------------------------------------------------------------------------------
130 static void on_ErodeDilate(int, void*)
131 {
132 //偏移量的定义
133 int offset = g_nErodeDilateNum - g_nMaxIterationNum; //偏移量
134 int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
135 //自定义核
136 Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
137 //进行操作
138 if (offset < 0)
139 erode(g_srcImage, g_dstImage, element);
140 else
141 dilate(g_srcImage, g_dstImage, element);
142 //显示图像
143 imshow("【腐蚀/膨胀】", g_dstImage);
144 }
145
146
147 //-----------------------------------【on_TopBlackHat( )函数】--------------------------------
148 // 描述:【顶帽运算/黑帽运算】窗口的回调函数
149 //----------------------------------------------------------------------------------------------
150 static void on_TopBlackHat(int, void*)
151 {
152 //偏移量的定义
153 int offset = g_nTopBlackHatNum - g_nMaxIterationNum;//偏移量
154 int Absolute_offset = offset > 0 ? offset : -offset;//偏移量绝对值
155 //自定义核
156 Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
157 //进行操作
158 if (offset < 0)
159 morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
160 else
161 morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
162 //显示图像
163 imshow("【顶帽/黑帽】", g_dstImage);
164 }
165
166 //-----------------------------------【ShowHelpText( )函数】----------------------------------
167 // 描述:输出一些帮助信息
168 //----------------------------------------------------------------------------------------------
169 static void ShowHelpText()
170 {
171 //输出欢迎信息和OpenCV版本
172
173 printf("
当前使用的OpenCV版本为:" CV_VERSION);
174 printf("
----------------------------------------------------------------------------
");
175
176 //输出一些帮助信息
177 printf("
请调整滚动条观察图像效果
");
178 printf("
按键操作说明:
"
179 " 键盘按键【ESC】或者【Q】- 退出程序
"
180 " 键盘按键【1】- 使用椭圆(Elliptic)结构元素
"
181 " 键盘按键【2】- 使用矩形(Rectangle )结构元素
"
182 " 键盘按键【3】- 使用十字型(Cross-shaped)结构元素
"
183 " 键盘按键【空格SPACE】- 在矩形、椭圆、十字形结构元素中循环
");
184 }
以上是关于OpenCV 图像处理(形态学滤波:腐蚀与膨胀,开运算闭运算形态学梯度顶帽黑帽)的主要内容,如果未能解决你的问题,请参考以下文章