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 图像处理(形态学滤波:腐蚀与膨胀,开运算闭运算形态学梯度顶帽黑帽)的主要内容,如果未能解决你的问题,请参考以下文章

opencv —— erodedilate 腐蚀与膨胀

滤波形态学腐蚀与卷积(合集)

OpenCV实战(11)——形态学变换详解

形态学滤波:腐蚀与膨胀 开运算,闭运算,形态学梯度,顶帽,黑帽

OpenCV学习笔记 008基于形态学运算的图像变换

OpenCV 形态学操作:膨胀与腐蚀