opencv程序十七:运动目标检测之背景减除法

程序如下:

// 23MotionDetection.cpp : 定义控制台应用程序的入口点。
//背景减除法,第一帧视为背景

#include "stdafx.h"
#include   
#include   
#include   
//CAM定义用摄像头获得视频else文件
//#define CAM   
  
  
int main( int argc, char** argv )  
{  
    //声明IplImage指针  
    IplImage* pFrame = NULL; //原始视频帧  
    IplImage* pFrImg = NULL; //提取的前景图像,即运动目标  
    IplImage* pBkImg = NULL; //背景图像 
  
    CvMat* pFrameMat = NULL; //原始视频矩阵 
    CvMat* pFrMat = NULL;    //前景矩阵
    CvMat* pBkMat = NULL;    //背景矩阵
  
    CvCapture* pCapture = NULL;  
    //帧数
    int nFrmNum = 0;  
  
    //创建窗口  
    cvNamedWindow("video", 1);  
    cvNamedWindow("background",1);  
    cvNamedWindow("foreground",1);  
    //使窗口有序排列  
    cvMoveWindow("video", 30, 0);  
    cvMoveWindow("background", 360, 0);  
    cvMoveWindow("foreground", 690, 0);  
  
#ifdef CAM
    if( !(pCapture = cvCaptureFromCAM(0)))  
    {  
        //pCapture = cvCaptureFromCAM(-1))  
        fprintf(stderr, "Can not open CAM .\n");  
        return -2;  
    }  
#else
	char *filename="../../0VideoSource/1344.avi";
	if( !(pCapture = cvCaptureFromAVI(filename)))  
    {  
        //pCapture = cvCaptureFromCAM(-1))  
        fprintf(stderr, "Can not open file %s.\n",filename);  
        return -2;  
    }    
#endif
	//逐帧读取视频  
    while(pFrame = cvQueryFrame( pCapture ))  
    {  
        nFrmNum++;  
  
        //如果是第一帧,需要申请内存,并初始化  
        if(nFrmNum == 1)  
        {  
            pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);  
            pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);  
  
            pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);  
            pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);  
            pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);  
  
            //转化成单通道图像再处理  
            cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY); //第一帧作为背景了 
            //cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY); // 
			//转换成矩阵
            cvConvert(pBkImg, pFrameMat);  //虽然没用,相当于给矩阵赋了初值
            cvConvert(pBkImg, pFrMat);	   //虽然没用,相当于给矩阵赋了初值
            cvConvert(pBkImg, pBkMat);  
        }  
        else  
        {  
            cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);  
            cvConvert(pFrImg, pFrameMat);  
            //高斯滤波先,以平滑图像  
            //cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);  
  
            //当前帧跟背景图相减 计算两个数组差的绝对值 
            cvAbsDiff(pFrameMat, pBkMat, pFrMat);  
  
            //二值化前景图  
            cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);  
			
            //进行形态学滤波,去掉噪音    
            //cvErode(pFrImg, pFrImg, 0, 1);  
            //cvDilate(pFrImg, pFrImg, 0, 1);  
  
            //更新背景  
            cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);  
            //将背景转化为图像格式,用以显示  
            cvConvert(pBkMat, pBkImg);  
			
            //显示图像  
            cvShowImage("video", pFrame);  
            cvShowImage("background", pBkImg);  
            cvShowImage("foreground", pFrImg);  
  
            //如果有按键事件,则跳出循环  
            //此等待也为cvShowImage函数提供时间完成显示  
            //等待时间可以根据CPU速度调整  
            if( cvWaitKey(20) >= 0 )  
            {  
                break;  
            }  
        }  
    }  
    cvWaitKey();  
  
    //销毁窗口  
    cvDestroyWindow("video");  
    cvDestroyWindow("background");  
    cvDestroyWindow("foreground");  
  
    //释放图像和矩阵  
    cvReleaseImage(&pFrImg);  
    cvReleaseImage(&pBkImg);  
  
    cvReleaseMat(&pFrameMat);  
    cvReleaseMat(&pFrMat);  
    cvReleaseMat(&pBkMat);  
  
    cvReleaseCapture(&pCapture);  
  
    return 0;  
}  

效果图如下

opencv程序十七:运动目标检测之背景减除法_第1张图片

你可能感兴趣的:(OpenCV)