OpenCV讀視頻文件和運動問題檢測

cvRunningAvg

  opencv中的函數,用來更新移動平均。用法:ide

  void cvRunningAvg(const CvArr * image,函數

  CvArr* acc,ui

  double alpha,spa

  const CvArr* mask=NULL)指針

  image:輸入圖像,1或3通道,8比特或32比特的float型code

  acc:累加器,和image同樣大小視頻

  alpha:更新時,image所佔的權重事件

  mask:操做符掩碼ip

  if mask(x,y)!= 0 (1-alpha)*acc(x,y)+alpha*image(x,y) =>acc(x,y)內存

#if 0
#include <stdio.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "highgui.lib")
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( !(pCapture = cvCaptureFromAVI(".\\test.avi")))
 {
  //pCapture = cvCaptureFromCAM(-1))
  fprintf(stderr, "Can not open camera.\n");
  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(20) >= 0 )
   {
    break;
   }
  }
 }
 cvWaitKey();
 //銷燬窗口
 cvDestroyWindow("video");
 cvDestroyWindow("background");
 cvDestroyWindow("foreground");
 //釋放圖像和矩陣
 cvReleaseImage(&pFrImg);
 cvReleaseImage(&pBkImg);
 cvReleaseMat(&pFrameMat);
 cvReleaseMat(&pFrMat);
 cvReleaseMat(&pBkMat);
 cvReleaseCapture(&pCapture);
 return 0;
}
#else
#include <cv.h>
#include <highgui.h>
#pragma comment(lib, "cv.lib")
#pragma comment(lib, "cxcore.lib")
#pragma comment(lib, "highgui.lib")
int main( int argc, char** argv )
{
 CvCapture* capture = NULL;
 IplImage *frame = NULL;
 IplImage  *frame_last = NULL;//存儲上一幀
 IplImage  *m_out_image = NULL;
 IplImage* frame_gray = NULL;
 IplImage* frame_gray_last = NULL;
 IplImage* m_out_image_copy = NULL;
 int nFrmNum = 0;
 //capture = cvCaptureFromCAM(-1);
 capture = cvCaptureFromAVI(".\\test.avi");
 //建立窗口
 cvNamedWindow( "result", 1 );
 cvNamedWindow("差分");
 //逐幀讀取視頻
 while(frame = cvQueryFrame( capture ))
 {
  nFrmNum++;
  //若是是第一幀,須要申請內存,並初始化
  if(nFrmNum == 1)
  {
   frame_last = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels);
   cvCopy(frame,frame_last);
  }
  else
  {
   frame_gray = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U, 1);
   frame_gray_last = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U, 1);
   m_out_image = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U, 1);
   m_out_image_copy = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, 1 );
   cvCvtColor(frame,frame_gray,CV_RGB2GRAY);
   cvCvtColor(frame_last,frame_gray_last,CV_RGB2GRAY);
   cvAbsDiff(frame_gray,frame_gray_last,m_out_image);
   //cvThreshold(m_out_image,m_out_image,128, 255,CV_THRESH_BINARY);
   //將處理後的圖像寫出到第二個圖像中
   if( m_out_image_copy->origin == IPL_ORIGIN_TL )
   {
    cvCopy( m_out_image, m_out_image_copy, 0 );
   }
   else
   {
    cvFlip( m_out_image, m_out_image_copy, 0 );
   }
   frame_last = cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels);
   cvCopy(frame,frame_last);
   cvShowImage("差分",m_out_image_copy);
   cvShowImage("result",frame);
   cvReleaseImage( &m_out_image_copy );
   cvReleaseImage( &frame_gray_last );
   cvReleaseImage( &frame_gray );
   if( cvWaitKey( 20 ) >= 0 )
   {
    break;
   }
  }
 }
 cvWaitKey();
 cvReleaseImage( &m_out_image );
 cvReleaseImage( &frame_last );
 cvReleaseImage( &frame );
 cvReleaseCapture( &capture );
 cvDestroyWindow("result");
 cvDestroyWindow("差分");
 return 0;
}
#endif
相關文章
相關標籤/搜索