// sf115.cpp : 定义控制台应用程序的入口点。 // //来自于仕琪的讲稿 《使用OpenCV进行图像处理》]中的例程 /**************************************************  * 背景建模,运动物体检测  *        **************************************************/  /***********************************************************************  * OpenCV example  * By Shiqi Yu 2006  ***********************************************************************/  #include "stdafx.h" #include <stdio.h>  #include <cv.h> #include <cxcore.h> #include <highgui.h>  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);     if( argc > 2 )     {       fprintf(stderr, "Usage: bkgrd [video_file_name]\n");       return -1;     }    //打开摄像头   if (argc ==1)     if( !(pCapture = cvCaptureFromCAM(-1)))       { 	fprintf(stderr, "Can not open camera.\n"); 	return -2;       }    //打开视频文件   if(argc == 2)     if( !(pCapture = cvCaptureFromFile(argv[1])))       { 	fprintf(stderr, "Can not open video file %s\n", argv[1]); 	return -2;       }      //逐帧读取视频   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(pFrImg, pFrameMat); 	  cvConvert(pFrImg, pFrMat); 	  cvConvert(pFrImg, 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(2) >= 0 ) 	    break; 	}     }   //销毁窗口   cvDestroyWindow("video");   cvDestroyWindow("background");   cvDestroyWindow("foreground");    //释放图像和矩阵   cvReleaseImage(&pFrImg);   cvReleaseImage(&pBkImg);    cvReleaseMat(&pFrameMat);   cvReleaseMat(&pFrMat);   cvReleaseMat(&pBkMat);    cvReleaseCapture(&pCapture);    return 0; }