双背景建模实现 滞留物与失窃物检测

双背景建模即建立两个背景模型,一个更新快的背景模型: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;
}





posted @ 2012-08-08 13:52  小马_xiaoLV2  阅读(1420)  评论(0编辑  收藏  举报