双背景建模即建立两个背景模型,一个更新快的背景模型:1帧更新一次,一个是更新慢的背景模型:30帧(或者N帧)更新一次。更新背景模型我选用平均加权(cvRuningAvg)
效果图为演示 检测出杯子被拿走的情况:
因为快背景更新较快,所以杯子被拿走后,快背景中的杯子会马上消失
而慢背景中的杯子驻留的时间较长。将快慢背景相减 就能获取被子。
// lostDetection.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "opencv/highgui.h"
#include "opencv/cv.h"
#include "opencv/cxcore.h"
//#include "ml.h"
#include <iostream>
#ifdef DEBUG
#pragma comment(lib,"opencv_core231d.lib")
#pragma comment(lib,"opencv_features2d231d.lib")
#pragma comment(lib,"opencv_flann231d.lib")
#pragma comment(lib,"opencv_gpu231d.lib")
#pragma comment(lib,"opencv_highgui231d.lib")
#pragma comment(lib,"opencv_imgproc231d.lib")
#pragma comment(lib,"opencv_ml231d.lib")
#else
#pragma comment(lib,"opencv_core231.lib")
#pragma comment(lib,"opencv_features2d231.lib")
#pragma comment(lib,"opencv_flann231.lib")
#pragma comment(lib,"opencv_gpu231.lib")
#pragma comment(lib,"opencv_highgui231.lib")
#pragma comment(lib,"opencv_imgproc231.lib")
#pragma comment(lib,"opencv_ml231.lib")
#endif
using namespace std;
using namespace cv;
#define UPDATEDELAY 30 //慢背景更新间隔
int _tmain(int argc, _TCHAR* argv[])
{
CvCapture * cap = cvCreateCameraCapture(0);
if (!cap)
{
printf("failed to open device\n");
getchar();
return 0 ;
}
IplImage * pImg = cvQueryFrame(cap);
if (!pImg)
{
printf("failed to query image\n");
getchar();
return 0 ;
}
// 空循环:因为偶的摄像头在刚启动的时候会自动调光。。。。
for (int i = 0 ; i < 100 ; i ++)
{
pImg = cvQueryFrame(cap);
}
int nwidth = pImg->width;
int nheight = pImg->height;
IplImage *pImgCurrent = cvCreateImage(cvSize(nwidth,nheight),8,1); // 当前帧
IplImage * pImgFastBk = cvCreateImage(cvSize(nwidth,nheight),8,1); // 快背景
IplImage * pImgSlowBk = cvCreateImage(cvSize(nwidth,nheight),8,1); //慢背景
IplImage * pImgFore = cvCreateImage(cvSize(nwidth,nheight),8,1); // 前景
CvMat *pMatCurrent = cvCreateMat(nheight,nwidth,CV_32FC1);
CvMat *pMatFastBk = cvCreateMat(nheight,nwidth,CV_32FC1);
CvMat *pMatSlowBk = cvCreateMat(nheight,nwidth,CV_32FC1);
CvMat *pMatFore = cvCreateMat(nheight,nwidth,CV_32FC1);
// 初始化
cvCvtColor(pImg,pImgCurrent,CV_BGR2GRAY);
cvConvert(pImgCurrent,pMatCurrent);
cvCopy(pMatCurrent,pMatFastBk);
cvCopy(pMatCurrent,pMatSlowBk);
int nwaitkey = -1;
int ncount = 0;
while (nwaitkey !='a')
{
pImg = cvQueryFrame(cap);
if (!pImg)
{
printf("failed to query image\n");
break;
}
cvCvtColor(pImg,pImgCurrent,CV_BGR2GRAY);
cvConvert(pImgCurrent,pMatCurrent);
// 1. 快背景更新(均值加权)
cvRunningAvg(pMatCurrent,pMatFastBk,0.005);
ncount++;
// 2. 慢背景更新
if (ncount >UPDATEDELAY)
{
cvRunningAvg(pMatCurrent,pMatSlowBk,0.005);
ncount = 0 ;
}
// 3. 两背景相减
cvAbsDiff(pMatFastBk,pMatSlowBk,pMatFore);
cvConvert(pMatFore,pImgFore);
cvShowImage("foreimage",pImgFore);
// 4. 阈值分割
cvThreshold(pImgFore,pImgFore,60,255,CV_THRESH_BINARY);
cvConvert(pMatFastBk,pImgFastBk);
cvConvert(pMatSlowBk,pImgSlowBk);
// 5 . 轮廓查找
cvShowImage("fastbk",pImgFastBk);
cvShowImage("slowbk",pImgSlowBk);
cvShowImage("currentImg",pImgCurrent);
cvShowImage("foreImgeThreshold",pImgFore);
nwaitkey = cvWaitKey(40);
}
cvReleaseImage(&pImgFastBk);
cvReleaseImage(&pImgSlowBk);
cvReleaseImage(&pImgFore);
cvReleaseImage(&pImgCurrent);
cvReleaseMat(&pMatFastBk);
cvReleaseMat(&pMatSlowBk);
cvReleaseMat(&pMatFore);
cvReleaseMat(&pMatCurrent);
cvWaitKey(-1);
return 0;
}
//
#include "stdafx.h"
#include "opencv/highgui.h"
#include "opencv/cv.h"
#include "opencv/cxcore.h"
//#include "ml.h"
#include <iostream>
#ifdef DEBUG
#pragma comment(lib,"opencv_core231d.lib")
#pragma comment(lib,"opencv_features2d231d.lib")
#pragma comment(lib,"opencv_flann231d.lib")
#pragma comment(lib,"opencv_gpu231d.lib")
#pragma comment(lib,"opencv_highgui231d.lib")
#pragma comment(lib,"opencv_imgproc231d.lib")
#pragma comment(lib,"opencv_ml231d.lib")
#else
#pragma comment(lib,"opencv_core231.lib")
#pragma comment(lib,"opencv_features2d231.lib")
#pragma comment(lib,"opencv_flann231.lib")
#pragma comment(lib,"opencv_gpu231.lib")
#pragma comment(lib,"opencv_highgui231.lib")
#pragma comment(lib,"opencv_imgproc231.lib")
#pragma comment(lib,"opencv_ml231.lib")
#endif
using namespace std;
using namespace cv;
#define UPDATEDELAY 30 //慢背景更新间隔
int _tmain(int argc, _TCHAR* argv[])
{
CvCapture * cap = cvCreateCameraCapture(0);
if (!cap)
{
printf("failed to open device\n");
getchar();
return 0 ;
}
IplImage * pImg = cvQueryFrame(cap);
if (!pImg)
{
printf("failed to query image\n");
getchar();
return 0 ;
}
// 空循环:因为偶的摄像头在刚启动的时候会自动调光。。。。
for (int i = 0 ; i < 100 ; i ++)
{
pImg = cvQueryFrame(cap);
}
int nwidth = pImg->width;
int nheight = pImg->height;
IplImage *pImgCurrent = cvCreateImage(cvSize(nwidth,nheight),8,1); // 当前帧
IplImage * pImgFastBk = cvCreateImage(cvSize(nwidth,nheight),8,1); // 快背景
IplImage * pImgSlowBk = cvCreateImage(cvSize(nwidth,nheight),8,1); //慢背景
IplImage * pImgFore = cvCreateImage(cvSize(nwidth,nheight),8,1); // 前景
CvMat *pMatCurrent = cvCreateMat(nheight,nwidth,CV_32FC1);
CvMat *pMatFastBk = cvCreateMat(nheight,nwidth,CV_32FC1);
CvMat *pMatSlowBk = cvCreateMat(nheight,nwidth,CV_32FC1);
CvMat *pMatFore = cvCreateMat(nheight,nwidth,CV_32FC1);
// 初始化
cvCvtColor(pImg,pImgCurrent,CV_BGR2GRAY);
cvConvert(pImgCurrent,pMatCurrent);
cvCopy(pMatCurrent,pMatFastBk);
cvCopy(pMatCurrent,pMatSlowBk);
int nwaitkey = -1;
int ncount = 0;
while (nwaitkey !='a')
{
pImg = cvQueryFrame(cap);
if (!pImg)
{
printf("failed to query image\n");
break;
}
cvCvtColor(pImg,pImgCurrent,CV_BGR2GRAY);
cvConvert(pImgCurrent,pMatCurrent);
// 1. 快背景更新(均值加权)
cvRunningAvg(pMatCurrent,pMatFastBk,0.005);
ncount++;
// 2. 慢背景更新
if (ncount >UPDATEDELAY)
{
cvRunningAvg(pMatCurrent,pMatSlowBk,0.005);
ncount = 0 ;
}
// 3. 两背景相减
cvAbsDiff(pMatFastBk,pMatSlowBk,pMatFore);
cvConvert(pMatFore,pImgFore);
cvShowImage("foreimage",pImgFore);
// 4. 阈值分割
cvThreshold(pImgFore,pImgFore,60,255,CV_THRESH_BINARY);
cvConvert(pMatFastBk,pImgFastBk);
cvConvert(pMatSlowBk,pImgSlowBk);
// 5 . 轮廓查找
cvShowImage("fastbk",pImgFastBk);
cvShowImage("slowbk",pImgSlowBk);
cvShowImage("currentImg",pImgCurrent);
cvShowImage("foreImgeThreshold",pImgFore);
nwaitkey = cvWaitKey(40);
}
cvReleaseImage(&pImgFastBk);
cvReleaseImage(&pImgSlowBk);
cvReleaseImage(&pImgFore);
cvReleaseImage(&pImgCurrent);
cvReleaseMat(&pMatFastBk);
cvReleaseMat(&pMatSlowBk);
cvReleaseMat(&pMatFore);
cvReleaseMat(&pMatCurrent);
cvWaitKey(-1);
return 0;
}