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

来源:互联网 发布:算法 第四版 pdf 编辑:程序博客网 时间:2024/05/15 23:44

程序如下:

// 23MotionDetection.cpp : 定义控制台应用程序的入口点。//背景减除法,第一帧视为背景#include "stdafx.h"#include <cv.h>  #include <cxcore.h>  #include <highgui.h>  //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;      }  #elsechar *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;  }  

效果图如下


0 1
原创粉丝点击