您的位置:首页 > 运维架构

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

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

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

  /article/4670201.html

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

  /article/4670213.html

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

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

  


  


  


  其工程代码如下:

// gmm_wavetrees.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include "opencv2/core/core.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <stdio.h>

using namespace std;
using namespace cv;

//this is a sample for foreground detection functions
string src_img_name="WavingTrees/b00";
const char *src_img_name1;
Mat img, fgmask, fgimg;
int i=-1;
char chari[500];
bool update_bg_model = true;
bool pause=false;

//第一种gmm,用的是KaewTraKulPong, P. and R. Bowden (2001).
//An improved adaptive background mixture model for real-time tracking with shadow detection.
BackgroundSubtractorMOG bg_model;

void refineSegments(const Mat& img, Mat& mask, Mat& dst)
{
int niters = 3;

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

Mat temp;

dilate(mask, temp, Mat(), Point(-1,-1), niters);//膨胀,3*3的element,迭代次数为niters
erode(temp, temp, Mat(), Point(-1,-1), niters*2);//腐蚀
dilate(temp, temp, Mat(), Point(-1,-1), niters);

findContours( temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );//找轮廓

dst = Mat::zeros(img.size(), CV_8UC3);

if( contours.size() == 0 )
return;

// iterate through all the top-level contours,
// draw each connected component with its own random color
int idx = 0, largestComp = 0;
double maxArea = 0;

for( ; idx >= 0; idx = hierarchy[idx][0] )//这句没怎么看懂
{
const vector<Point>& c = contours[idx];
double area = fabs(contourArea(Mat(c)));
if( area > maxArea )
{
maxArea = area;
largestComp = idx;//找出包含面积最大的轮廓
}
}
Scalar color( 0, 255, 0 );
drawContours( dst, contours, largestComp, color, CV_FILLED, 8, hierarchy );
}

int main(int argc, const char** argv)
{
bg_model.noiseSigma = 10;
img=imread("WavingTrees/b00000.bmp");
if(img.empty())
{
namedWindow("image",1);//不能更改窗口
namedWindow("foreground image",1);
namedWindow("mean background image", 1);
}
for(;;)
{
if(!pause)
{
i++;
itoa(i,chari,10);
if(i<10)
{
src_img_name+="00";
}
else if(i<100)
{
src_img_name+="0";
}
else if(i>285)
{
i=-1;
}
if(i>=230)
update_bg_model=false;
else update_bg_model=true;

src_img_name+=chari;
src_img_name+=".bmp";

img=imread(src_img_name);
if( img.empty() )
break;

//update the model
bg_model(img, fgmask, update_bg_model ? 0.005 : 0);//计算前景mask图像,其中输出fgmask为8-bit二进制图像,第3个参数为学习速率
refineSegments(img, fgmask, fgimg);

imshow("image", img);
imshow("foreground image", fgimg);

src_img_name="WavingTrees/b00";

}
char k = (char)waitKey(80);
if( k == 27 ) break;

if( k == ' ' )
{
pause=!pause;
}
}

return 0;
}


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

  


  


  


  其工程代码如下:

// gmm2_wavetrees.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include "opencv2/core/core.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <stdio.h>

using namespace std;
using namespace cv;

//this is a sample for foreground detection functions
string src_img_name="WavingTrees/b00";
const char *src_img_name1;
Mat img, fgmask, fgimg;
int i=-1;
char chari[500];
bool update_bg_model = true;
bool pause=false;

//第一种gmm,用的是KaewTraKulPong, P. and R. Bowden (2001).
//An improved adaptive background mixture model for real-time tracking with shadow detection.
BackgroundSubtractorMOG2 bg_model;

void refineSegments(const Mat& img, Mat& mask, Mat& dst)
{
int niters = 3;

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

Mat temp;

dilate(mask, temp, Mat(), Point(-1,-1), niters);
erode(temp, temp, Mat(), Point(-1,-1), niters*2);
dilate(temp, temp, Mat(), Point(-1,-1), niters);

findContours( temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

dst = Mat::zeros(img.size(), CV_8UC3);

if( contours.size() == 0 )
return;

// iterate through all the top-level contours,
// draw each connected component with its own random color
int idx = 0, largestComp = 0;
double maxArea = 0;

for( ; idx >= 0; idx = hierarchy[idx][0] )
{
const vector<Point>& c = contours[idx];
double area = fabs(contourArea(Mat(c)));
if( area > maxArea )
{
maxArea = area;
largestComp = idx;
}
}
Scalar color( 255, 0, 0 );
drawContours( dst, contours, largestComp, color, CV_FILLED, 8, hierarchy );
}

int main(int argc, const char** argv)
{
img=imread("WvingTrees/b00000.bmp");
if(img.empty())
{
namedWindow("image",1);//不能更改窗口
//cvNamedWindow("image",0);
namedWindow("foreground image",1);
//    namedWindow("mean background image", 1);
}
for(;;)
{
if(!pause)
{
i++;
itoa(i,chari,10);
if(i<10)
{
src_img_name+="00";
}
else if(i<100)
{
src_img_name+="0";
}
else if(i>285)
{
i=-1;
}
//    if(i>=230)
//        update_bg_model=false;
//    else update_bg_model=true;

src_img_name+=chari;
src_img_name+=".bmp";

img=imread(src_img_name);
if( img.empty() )
break;

//update the model
bg_model(img, fgmask, update_bg_model ? 0.005 : 0);//计算前景mask图像,其中输出fgmask为8-bit二进制图像,第3个参数为学习速率
refineSegments(img, fgmask, fgimg);

imshow("foreground image", fgimg);
imshow("image", img);

src_img_name="WavingTrees/b00";

}
char k = (char)waitKey(100);
if( k == 27 ) break;

if( k == ' ' )
{
pause=!pause;
}
}

return 0;
}


  可以看出gmm1效果比gmm2的好,但是研究发现,gmm2是在gmm1上改进的,不会越该越差吧,除非2个函数的使用方法不同(虽然函数形式一样),也就是说相同的参数值对函数功能的影响不同。以后有时间在研究了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: