双背景建模即建立两个背景模型,一个更新快的背景模型: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;
}
本文介绍了一种基于双背景建模的运动目标检测方法,通过快速背景和慢速背景的对比,有效检测出运动变化区域。该方法适用于监控场景中物品的移除检测。
8423

被折叠的 条评论
为什么被折叠?



