看了tornadomeet的前景检测算法_4(opencv自带GMM)
http://www.cnblogs.com/tornadomeet
代码没有问题,我用vs2012和opencv2.4.4跑了一下,有两个小地方需要注意:
1. 把包含287张图片的WavingTrees文件夹与*.vcxproj放在同一个文件夹里;
2. 第63行和104行代码中的"/"用"\\"代替。
实验结果:
为方便自己,代码就放在这里
#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 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(200,5,0.7,10);
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)
{
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>283)
{
i=-1;
}
src_img_name+=chari;
src_img_name+=".bmp";
img=imread(src_img_name);
if( img.empty() )
break;
//update the model
bg_model(img, fgmask,0.005 );//计算前景mask图像,其中输出fgmask为8-bit二进制图像,第3个参数为学习速率,如果学习速率为0,则为背景相减法
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;
}