视频目标检测与跟踪实现代码:视频目标检测与跟踪实现代码:#includestdafx.h#includecv.h#includehighgui.h#includetime.h#includemath.h#includestdio.h#includestring.h//varioustrackingparameters(inseconds)//跟踪的参数(单位为秒)constdoubleMHI_DURATION=1;//0.5s为运动跟踪的最大持续时间constdoubleMAX_TIME_DELTA=0.5;//最大时间增量为0.5sconstdoubleMIN_TIME_DELTA=0.05;//最小时间增量0.05sconstintN=3;//constintCONTOUR_MAX_AERA=1000;//ringimagebuffer圈出图像缓冲IplImage**buf=0;//指针的指针intlast=0;//temporaryimages临时图像IplImage*mhi=0;//MHI:motionhistoryimage运动历史图像CvFilterfilter=CV_GAUSSIAN_5x5;CvConnectedComp*cur_comp,min_comp;//连接部件CvConnectedCompcomp;CvMemStorage*storage;//内存存储器CvPointpt[4];//二维坐标系下的点,类型为整型,通常以0点为原点,有x坐标和y坐标intnCurFrameIndex=0;//参数://img–输入视频帧//dst–检测结果voidupdate_mhi(IplImage*img,IplImage*dst,intdiff_threshold){doubletimestamp=clock()/100.;//getcurrenttimeinseconds时间戳CvSizesize=cvSize(img-width,img-height);//getcurrentframesize,得到当前帧的尺寸inti,idx1,idx2;IplImage*silh;IplImage*pyr=cvCreateImage(cvSize((size.width&-2)/2,(size.height&-2)/2),8,1);CvMemStorage*stor;CvSeq*cont;/*先进行数据的初始化*/if(!mhi||mhi-width!=size.width||mhi-height!=size.height){if(buf==0)//若尚没有初始化则分配内存给他{buf=(IplImage**)malloc(N*sizeof(buf[0]));memset(buf,0,N*sizeof(buf[0]));}for(i=0;iN;i++){cvReleaseImage(&buf[i]);buf[i]=cvCreateImage(size,IPL_DEPTH_8U,1);cvZero(buf[i]);//clearBufferFrameatthebeginning}cvReleaseImage(&mhi);mhi=cvCreateImage(size,IPL_DEPTH_32F,1);cvZero(mhi);//clearMHIatthebeginning}//endofif(mhi)/*将当前要处理的帧转化为灰度放到buffer的最后一帧中*/cvCvtColor(img,buf[last],CV_BGR2GRAY);//convertframetograyscale/*设定帧的序号*//*last----idx1^|||idx2-----(last+1)%3*/idx1=last;idx2=(last+1)%N;//indexof(last-(N-1))thframelast=idx2;//做帧差silh=buf[idx2];//差值的指向idx2|idx2-idx1|--idx2(-silh)cvAbsDiff(buf[idx1],buf[idx2],silh);//getdifferencebetweenframes//对差图像做二值化cvThreshold(silh,silh,50,255,CV_THRESH_BINARY);//thresholdit,二值化cvUpdateMotionHistory(silh,mhi,timestamp,MHI_DURATION);//updateMHIcvConvert(mhi,dst);//将mhi转化为dst,dst=mhi//中值滤波,消除小的噪声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);//向上采样,恢复图像,图像是原图像的四倍////下面的程序段用来找到轮廓////Createdynamicstructureandsequence.stor=cvCreateMemStorage(0);cont=cvCreateSeq(CV_SEQ_ELTYPE_POINT,sizeof(CvSeq),sizeof(CvPoint),stor);//找到所有轮廓cvFindContours(dst,stor,&cont,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));//直接使用CONTOUR中的矩形来画轮廓for(;cont;cont=cont-h_next){CvRectr=((CvContour*)cont)-rect;if(r.height*r.widthCONTOUR_MAX_AERA)//面积小的方形抛弃掉{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);}}//freememorycvReleaseMemStorage(&stor);cvReleaseImage(&pyr);}intmain(intargc,char**argv){//保存视频文件charszVideoSaveName[]=F:\\VideoSave.avi;//!将保存视频文件的名字设置成C:\\VideoSave.aviCvVideoWriter*pVideoWriter=NULL;//用于保存视频文件IplImage*pFrame=NULL;IplImage*pImage=NULL;IplImage*motion=0;CvCapture*capture=0;//if(argc==1||(argc==2&&strlen(argv[1])==1&&isdigit(argv[1][0])))//capture=cvCaptureFromCAM(argc==2?argv[1][0]-'0':0);//摄像头为视频来源if(argc==1)capture=cvCaptureFromAVI(1.avi);//AVI为视频来源if(capture){cvNamedWindow(Motion,1);//建立窗口for(;;){IplImage*image;if(!cvGrabFrame(capture))//捕捉一桢break;image=cvRetrieveFrame(capture);//取出这个帧if(image)//若取到则判断motion是否为空{if(!motion){motion=cvCreateImage(cvSize(image-width,image-height),8,1);//创建motion帧,八位,一通道cvZero(motion);//零填充motionmotion-origin=image-origin;//内存存储的顺序和取出的帧相同}}update_mhi(image,motion,60);//更新历史图像cvShowImage(Motion,image);//显示处理过的图像pVideoWriter=cvCreateVideoWriter(VideoSave.avi,CV_FOURCC('M','J','P','G'),10,cvSize(640,480),1);cvWriteFrame(pVideoWriter,image);//nCurFrameIndex++;//strFrameString.Format(CurrentFrame:%d,nCurFrameIndex);//cvPutText(image,strFrameString,cvPoint(5,pFrame-height-15),&font,cvScalar(0,255,0));cvReleaseVideoWriter(&pVideoWriter);if(cvWaitKey(10)=0)//10ms中按任意键退出break;}cvReleaseCapture(&capture);//释放设备cvDestroyWindow(Motion);//销毁窗口}return0;}现在还有点问题,我想输出保存处理后的视频,显示的结果好像只有一帧的信息,谁能帮忙一下新手的烦恼?