zoukankan      html  css  js  c++  java
  • 前景检测算法_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个函数的使用方法不同(虽然函数形式一样),也就是说相同的参数值对函数功能的影响不同。以后有时间在研究了。

     

     

     

     

    作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:tornadomeet,欢迎交流!)
  • 相关阅读:
    Linux中-POSIX 线程详解
    sql server 2008如何导入mdf,ldf文件
    div浏览器兼容问题
    桥(Bridge)模式
    JSTL核心标签
    filter中的dispatcher解析
    synchronized探究
    最全设计模式(转载)
    面试题总结
    企业为什么要去竞争?
  • 原文地址:https://www.cnblogs.com/tornadomeet/p/2531705.html
Copyright © 2011-2022 走看看