前景检测算法_4(opencv自带GMM)

原文地址为: 前景检测算法_4(opencv自带GMM)

  前面已经有3篇博文介绍了背景减图方面相关知识(见下面的链接),在第3篇博文中自己也实现了gmm简单算法,但效果不是很好,下面来体验下opencv自带2个gmm算法。

  opencv实现背景减图法1(codebook和平均背景法)

  http://www.cnblogs.com/tornadomeet/archive/2012/04/08/2438158.html

  opencv实现背景减图法2(帧差法)

  http://www.cnblogs.com/tornadomeet/archive/2012/05/01/2477629.html

  opencv实现背景减图法3(GMM)

  http://www.cnblogs.com/tornadomeet/archive/2012/06/02/2531565.html

  工程环境opencv2.3.1+vs2010

  实现功能:与上面第三篇博文一样,完成动态背景的训练,来检测前景。

  数据来源和前面的一样: http://research.microsoft.com/en-us/um/people/jckrumm/WallFlower/TestImages.htm 由于该数据是286张bmp格式的图片,所以用的前200张图片来作为GMM参数训练,后186张作为测试。训练的过程中树枝被很大幅度的摆动,测试过程中有行人走动,该行人是需要迁就检测的部分。

  Opencv自带的gmm算法1的实验结果如下:

  

  

  

  其工程代码如下:

  1 // gmm_wavetrees.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5
6 #include "opencv2/core/core.hpp"
7 #include "opencv2/video/background_segm.hpp"
8 #include "opencv2/highgui/highgui.hpp"
9 #include "opencv2/imgproc/imgproc.hpp"
10 #include <stdio.h>
11
12 using namespace std;
13 using namespace cv;
14
15 //this is a sample for foreground detection functions
16 string src_img_name="WavingTrees/b00";
17 const char *src_img_name1;
18 Mat img, fgmask, fgimg;
19 int i=-1;
20 char chari[500];
21 bool update_bg_model = true;
22 bool pause=false;
23
24 //第一种gmm,用的是KaewTraKulPong, P. and R. Bowden (2001).
25 //An improved adaptive background mixture model for real-time tracking with shadow detection.
26 BackgroundSubtractorMOG bg_model;
27
28 void refineSegments(const Mat& img, Mat& mask, Mat& dst)
29 {
30 int niters = 3;
31
32 vector<vector<Point> > contours;
33 vector<Vec4i> hierarchy;
34
35 Mat temp;
36
37 dilate(mask, temp, Mat(), Point(-1,-1), niters);//膨胀,3*3的element,迭代次数为niters
38 erode(temp, temp, Mat(), Point(-1,-1), niters*2);//腐蚀
39 dilate(temp, temp, Mat(), Point(-1,-1), niters);
40
41 findContours( temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );//找轮廓
42
43 dst = Mat::zeros(img.size(), CV_8UC3);
44
45 if( contours.size() == 0 )
46 return;
47
48 // iterate through all the top-level contours,
49 // draw each connected component with its own random color
50 int idx = 0, largestComp = 0;
51 double maxArea = 0;
52
53 for( ; idx >= 0; idx = hierarchy[idx][0] )//这句没怎么看懂
54 {
55 const vector<Point>& c = contours[idx];
56 double area = fabs(contourArea(Mat(c)));
57 if( area > maxArea )
58 {
59 maxArea = area;
60 largestComp = idx;//找出包含面积最大的轮廓
61 }
62 }
63 Scalar color( 0, 255, 0 );
64 drawContours( dst, contours, largestComp, color, CV_FILLED, 8, hierarchy );
65 }
66
67 int main(int argc, const char** argv)
68 {
69 bg_model.noiseSigma = 10;
70 img=imread("WavingTrees/b00000.bmp");
71 if(img.empty())
72 {
73 namedWindow("image",1);//不能更改窗口
74 namedWindow("foreground image",1);
75 namedWindow("mean background image", 1);
76 }
77 for(;;)
78 {
79 if(!pause)
80 {
81 i++;
82 itoa(i,chari,10);
83 if(i<10)
84 {
85 src_img_name+="00";
86 }
87 else if(i<100)
88 {
89 src_img_name+="0";
90 }
91 else if(i>285)
92 {
93 i=-1;
94 }
95 if(i>=230)
96 update_bg_model=false;
97 else update_bg_model=true;
98
99 src_img_name+=chari;
100 src_img_name+=".bmp";
101
102 img=imread(src_img_name);
103 if( img.empty() )
104 break;
105
106 //update the model
107 bg_model(img, fgmask, update_bg_model ? 0.005 : 0);//计算前景mask图像,其中输出fgmask为8-bit二进制图像,第3个参数为学习速率
108 refineSegments(img, fgmask, fgimg);
109
110 imshow("image", img);
111 imshow("foreground image", fgimg);
112
113 src_img_name="WavingTrees/b00";
114
115 }
116 char k = (char)waitKey(80);
117 if( k == 27 ) break;
118
119 if( k == ' ' )
120 {
121 pause=!pause;
122 }
123 }
124
125 return 0;
126 }

  Opencv自带的gmm算法2的实验结果如下:

  

  

  

 

  其工程代码如下:

  1 // gmm2_wavetrees.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5
6 #include "opencv2/core/core.hpp"
7 #include "opencv2/video/background_segm.hpp"
8 #include "opencv2/highgui/highgui.hpp"
9 #include "opencv2/imgproc/imgproc.hpp"
10 #include <stdio.h>
11
12 using namespace std;
13 using namespace cv;
14
15 //this is a sample for foreground detection functions
16 string src_img_name="WavingTrees/b00";
17 const char *src_img_name1;
18 Mat img, fgmask, fgimg;
19 int i=-1;
20 char chari[500];
21 bool update_bg_model = true;
22 bool pause=false;
23
24 //第一种gmm,用的是KaewTraKulPong, P. and R. Bowden (2001).
25 //An improved adaptive background mixture model for real-time tracking with shadow detection.
26 BackgroundSubtractorMOG2 bg_model;
27
28 void refineSegments(const Mat& img, Mat& mask, Mat& dst)
29 {
30 int niters = 3;
31
32 vector<vector<Point> > contours;
33 vector<Vec4i> hierarchy;
34
35 Mat temp;
36
37 dilate(mask, temp, Mat(), Point(-1,-1), niters);
38 erode(temp, temp, Mat(), Point(-1,-1), niters*2);
39 dilate(temp, temp, Mat(), Point(-1,-1), niters);
40
41 findContours( temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
42
43 dst = Mat::zeros(img.size(), CV_8UC3);
44
45 if( contours.size() == 0 )
46 return;
47
48 // iterate through all the top-level contours,
49 // draw each connected component with its own random color
50 int idx = 0, largestComp = 0;
51 double maxArea = 0;
52
53 for( ; idx >= 0; idx = hierarchy[idx][0] )
54 {
55 const vector<Point>& c = contours[idx];
56 double area = fabs(contourArea(Mat(c)));
57 if( area > maxArea )
58 {
59 maxArea = area;
60 largestComp = idx;
61 }
62 }
63 Scalar color( 255, 0, 0 );
64 drawContours( dst, contours, largestComp, color, CV_FILLED, 8, hierarchy );
65 }
66
67 int main(int argc, const char** argv)
68 {
69 img=imread("WvingTrees/b00000.bmp");
70 if(img.empty())
71 {
72 namedWindow("image",1);//不能更改窗口
73 //cvNamedWindow("image",0);
74 namedWindow("foreground image",1);
75 // namedWindow("mean background image", 1);
76 }
77 for(;;)
78 {
79 if(!pause)
80 {
81 i++;
82 itoa(i,chari,10);
83 if(i<10)
84 {
85 src_img_name+="00";
86 }
87 else if(i<100)
88 {
89 src_img_name+="0";
90 }
91 else if(i>285)
92 {
93 i=-1;
94 }
95 // if(i>=230)
96 // update_bg_model=false;
97 // else update_bg_model=true;
98
99 src_img_name+=chari;
100 src_img_name+=".bmp";
101
102 img=imread(src_img_name);
103 if( img.empty() )
104 break;
105
106 //update the model
107 bg_model(img, fgmask, update_bg_model ? 0.005 : 0);//计算前景mask图像,其中输出fgmask为8-bit二进制图像,第3个参数为学习速率
108 refineSegments(img, fgmask, fgimg);
109
110 imshow("foreground image", fgimg);
111 imshow("image", img);
112
113 src_img_name="WavingTrees/b00";
114
115 }
116 char k = (char)waitKey(100);
117 if( k == 27 ) break;
118
119 if( k == ' ' )
120 {
121 pause=!pause;
122 }
123 }
124
125 return 0;
126 }

  可以看出gmm1效果比gmm2的好,但是研究发现,gmm2是在gmm1上改进的,不会越该越差吧,除非2个函数的使用方法不同(虽然函数形式一样),也就是说相同的参数值对函数功能的影响不同。以后有时间在研究了。

 

 

 

 


转载请注明本文地址: 前景检测算法_4(opencv自带GMM)

猜你喜欢

转载自blog.csdn.net/CHCH998/article/details/82795797