前景检测算法_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的实验结果如下:

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

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

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

  其工程代码如下:

  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的实验结果如下:

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

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

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

 

  其工程代码如下:

  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个函数的使用方法不同(虽然函数形式一样),也就是说相同的参数值对函数功能的影响不同。以后有时间在研究了。

 

 

 

 

你可能感兴趣的:(opencv)