opencv程序十八:运动目标检测之三帧差分法

程序如下:

// 25MotionDetetion_ThreeDiff.cpp : 定义控制台应用程序的入口点。
//三帧差分法

#include "stdafx.h"
#include <cv.h>  
#include <cxcore.h>  
#include <highgui.h>  
//CAM定义用摄像头获得视频else文件
//#define CAM   
 int apos=30;  
void on_trackbar(int pos)  
{  
        apos=pos;   
}    
  
int main( int argc, char** argv )  
{  
    //声明IplImage指针  
    IplImage* pFrame = NULL; //原始视频帧  
    IplImage* pFrImg = NULL; //提取的前景图像,即运动目标  
    IplImage* pBkImg = NULL; //背景图像 
	IplImage* pMiImg = NULL; //中间帧图像
  
    CvMat* pFrameMat = NULL; //原始视频矩阵 
    CvMat* pFrMat = NULL;    //前景矩阵  第一帧
    CvMat* pBkMat = NULL;    //背景矩阵  第三帧
    CvMat* pMiMat = NULL;    //中间帧矩阵 第二帧
	CvMat* pRe1Mat = NULL;   //结果1
	CvMat* pRe2Mat = NULL;   //结果2
    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); 
	// 滑动条          
    int nThreshold = 30;        
    cvCreateTrackbar("阀值", "foreground", &nThreshold, 100, on_trackbar); 
  
#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);  
			pMiMat = 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);  
        }
		//如果是第er帧,需要申请内存,并初始化
		else if(nFrmNum==2)
		{
			pMiImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);  
			pMiMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
			pRe1Mat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
			pRe2Mat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
			cvCvtColor(pFrame, pMiImg, CV_BGR2GRAY);
			cvConvert(pMiImg, pMiMat);
		}
        else  
        {  
            cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);  
            cvConvert(pFrImg, pFrameMat);  
            //高斯滤波先,以平滑图像  
            //cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);  
  
            //当前帧跟背景图相减 计算两个数组差的绝对值 
			cvAbsDiff(pMiMat, pBkMat, pRe1Mat);
            cvAbsDiff(pFrameMat, pMiMat, pRe2Mat);  
			cvAnd(pRe1Mat,pRe2Mat,pFrMat,NULL); 
            //二值化前景图  
            cvThreshold(pFrMat, pFrImg, apos, 255.0, CV_THRESH_BINARY);  
			
            //进行形态学滤波,去掉噪音    
            //cvErode(pFrImg, pFrImg, 0, 1);  
            //cvDilate(pFrImg, pFrImg, 0, 1);  
			/*cvDilate(pFrImg, pFrImg, 0, 1);
			cvErode(pFrImg, pFrImg, 0, 1);  */
            //更新背景  
            //cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);  
            //将背景转化为图像格式,用以显示  
            cvConvert(pBkMat, pBkImg); 
			cvCopy(pMiMat,pBkMat,NULL);
			cvCopy(pFrameMat,pMiMat,NULL);
			//pBkMat=pFrameMat;
            //显示图像  
            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);  
	cvReleaseImage(&pMiImg);

    cvReleaseMat(&pFrameMat);  
    cvReleaseMat(&pFrMat);  
    cvReleaseMat(&pBkMat);
	cvReleaseMat(&pMiMat);
  
    cvReleaseCapture(&pCapture);  
  
    return 0;  
}  



  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值