Opencv 2 프레임 차 법 검 측 운동 목표 및 윤곽 추출

Opencv 학습 의 2 프레임 차 법 운동 목표 검 측 과 윤곽 추출 을 참고 하 시기 바 랍 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
코드 는 인터넷 에서 발췌 하여 배 운 것 으로 많은 주석 을 달 았 는데 마치 책 을 읽 으 면서 필 기 를 하 는 것 처럼 만 족 스 러 운 즐거움 을 주 었 다.Let's do this!

#include "highgui.h"
#include "cv.h"
#include "stdio.h"
#include <time.h>
#include <math.h>
#include <string.h>

const double MHI_DURATION=0.1;//           0.1s
const double MAX_TIME_DELTA=0.5//      0.5s
const double MIN_TIME_DELTA=0.05;//      0.05s
const int N=3;
const int CONTOUR_MAX_AERA=16;

/*            */
IplImage **buf=0;
int last=0;
/*    */
IplImage* mhi=0;//      mhi

CvConnectedComp* cur_comp,mincomp;
/*typedef struct CvConnectedComp 
 {
 double area; //     
 CvScalar value; //        
 CvRect rect; //          
 CvSeq * contour; //          
 };*/
/*         */
CvMemStorage* storage;
/*        ,     ,   0    , x、y  */
CvPoint pt[4];

/*      */
int nCurFrameIndex=0;

/*               */
/*img-     ;dst-    */
void update(IplImage *img,IplImage *dst,int diff_threshold)
{
 /*      ,    */
 double timestamp=clock()/100;
 /*          ,   size */
 CvSize size=cvSize(img->width,img->height);
 /*           */
 int i,idx1,idx2;
 /*            ,          nimg */
 IplImage* nimg;
 /*       - -!*/
 IplImage* pyr=cvCreateImage(cvSize((size.width&-2)/2,(size.height&-2)/2),8,1);
 /*         */
 CvMemStorage* stor;
 /*          seq*/
 CvSeq* seq;

 /*         */
 /*        ,                    (           ?)*/
 if(!mhi||mhi->width!=size.width||mhi->height!=size.height)
 {
 /*  buf     ,  buf    */
 if(buf==0)
 {
  /*N=3*/
  buf=(IplImage**)malloc(N*sizeof(buf[0]));
  /*   s                       ch   ASCII ,            :memset(void *s,char ch,unsigned n)。        buf        */
  memset(buf,0,N*sizeof(buf[0]));
 }
 /* buf      ,  buf  */
 for(i=0;i<N;i++)
 {
  cvReleaseImage(&buf[i]);
  buf[i]=cvCreateImage(size,IPL_DEPTH_8U,1);
  cvZero(buf[i]);
 }
 /*           mhi*/
 cvReleaseImage(&mhi);
 mhi=cvCreateImage(size,IPL_DEPTH_32F,1);
 cvZero(mhi);
 }

 /*              ,  buf     */
 cvCvtColor(img,buf[last],CV_BGR2GRAY);
 /*         , buf[idx1]         ,buf[idx2]     */
 idx1=last;
 idx2=(last+1)%N;
 last=idx2;
 /*   ,   cvAbsDiff            */
 nimg=buf[idx2];
 cvAbsDiff(buf[idx1],buf[idx2],nimg);
 /*    ,         */
 cvThreshold(nimg,nimg,50,255,CV_THRESH_BINARY);
 /*                */
 cvUpdateMotionHistory(nimg,mhi,timestamp,MHI_DURATION);
 cvConvert(mhi,dst);
 /*    ,      
   cvPyrDown  Gaussian              ,    ,           
   cvDialate     ,          
   cvPyrUp  Gaussian              ,    ,         */
 cvSmooth(dst,dst,CV_MEDIAN,3,0,0,0);
 cvPyrDown(dst,pyr,CV_GAUSSIAN_5x5);
 cvDilate(pyr,pyr,0,1);
 cvPyrUp(pyr,dst,CV_GAUSSIAN_5x5);

 /*    */
 stor=cvCreateMemStorage(0);
 seq=cvCreateSeq(CV_SEQ_ELTYPE_POINT,//                  
 sizeof(CvSeq),//            ;       sizeof(CvSeq)
 /*           ,    。           ( seq_flags  )   ,  ,        ,     CV_SEQ_ELTYPE_POINT     ,  elem_size     sizeof(CvPoint)。
*/
 sizeof(CvPoint),
 stor);//               

 /*      */
 cvFindContours(dst,//     
 stor,//       
 &seq,//    ,          。
 sizeof(CvContour),
 CV_RETR_EXTERNAL,//mode:EXTERNAL――        
 CV_CHAIN_APPROX_NONE,//       ,       - -
 cvPoint(0,0));

 /*   CONTOUR        */
 /*  seq  */
 for(;seq;seq=seq->h_next)
 {
 /*         ,  rect    x、y      ,      */
 CvRect r=((CvContour*)cont)->rect;//               ?
 /*             ,  ;         */
 if((r.height*r.width>CONTOUR_MAX_AERA)&&(r.height*r.width>2560))
 {
  /*cvRectangle           ,    */
  cvRectangle(img,//  
  cvPoint(r.x,r.y),//    
  cvPoint(r.x + r.width, r.y + r.height),//     
  CV_RGB(255,0,0),//    
  1,//      
  CV_AA,//    
  0); //         
 }
 }

 /*      ,    */
 cvReleaseMemStorage(&stor);
 cvReleaseImage(&pyr);
}

/    ,   /
int main(int argc,char**argv)
{
 IplImage *motion=0;
 CvCapture *capture=0;
 /*     */
 capture=cvCaptureFromFile("D:\\  \\01.mp4");
 if(capture)
 {
 cvNamedWindow("Motion",1);
 for(;;)
 {
  IplImage *image;
  /*  cvGrabFrame     */
  if(!cvGrabFrame(capture))
  break;
  /*  cvRetrieveFrame     cvGrabFrame    */
  image=cvRetrieveFrame(capture);
  if(image)
  {
  /*  motion     ,       。   motion   */
  if(!motion)
  {
   motion=cvCreateImage(cvSize(image->width,image->height),8,1);
   cvZero(motion);
   /*                  */
   motion->origin=image->origin;
  }
  }
  /*        ,  motion   ,     */
  update(image,motion,10);
  /*        */
  cvShowImage("Motion",image);

  /*10ms           ,   */
  if(cvWaitKey(10)>=0)
  break;
 }
 /*     for       ,                     */
 cvReleaseCapture(&capture);
 cvDestroyWindow("Motion");
 }
 return 0;
}
테스트 를 통 해 이 프로그램 은 이동 하 는 차량 과 행인 을 빨간색 테두리 로 성공 적 으로 감지 하고 동 그 라 미 를 칠 수 있다.
개선 해 야 할 부분 은 다음 과 같다.
① 영상 처리 속도 가 느 려 서 영상 처리 속 도 는 영상 정상 재생 속도 의 2 분 의 1 에 불과 하 다.
② 행인 의 검 측 에 있어 서 빨간색 사각형 이 불안정 하고 전체 행인 을 테두리 로 만 드 는 것 이 아니 라 한 사람의 여러 부위 에 orz 를 그 리 는 경우 가 많다.
③ 두 물체 가 약간 중첩 되면 중첩 물 체 를 하나의 물체 로 동 그 라 미 를 친다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기