







代码实现:
运行方式:按P停止,在前景窗口鼠标点击目标,会自动生成外接矩形,再次按P,对该选定目标进行跟踪。
-
-
- #include "stdafx.h"
- #include <cv.h>
- #include <cxcore.h>
- #include <highgui.h>
- #include <math.h>
- # include <time.h>
- #include <iostream>
- using namespace std;
-
-
- #define B(image,x,y) ((uchar*)(image->imageData + image->widthStep*(y)))[(x)*3] //B
- #define G(image,x,y) ((uchar*)(image->imageData + image->widthStep*(y)))[(x)*3+1] //G
- #define R(image,x,y) ((uchar*)(image->imageData + image->widthStep*(y)))[(x)*3+2] //R
- #define S(image,x,y) ((uchar*)(image->imageData + image->widthStep*(y)))[(x)]
- #define Num 10 //帧差的间隔
- #define T 40 //Tf
- #define Re 30 //
- #define ai 0.08 //学习率
-
- #define CONTOUR_MAX_AREA 10000
- #define CONTOUR_MIN_AREA 50
-
- # define R_BIN 8 /* 红色分量的直方图条数 */
- # define G_BIN 8 /* 绿色分量的直方图条数 */
- # define B_BIN 8 /* 兰色分量的直方图条数 */
-
- # define R_SHIFT 5 /* 与上述直方图条数对应 */
- # define G_SHIFT 5 /* 的R、G、B分量左移位数 */
- # define B_SHIFT 5 /* log2( 256/8 )为移动位数 */
-
-
- #define IA 16807
- #define IM 2147483647
- #define AM (1.0/IM)
- #define IQ 127773
- #define IR 2836
- #define MASK 123459876
-
-
- typedef struct __SpaceState {
- int xt;
- int yt;
- float v_xt;
- float v_yt;
- int Hxt;
- int Hyt;
- float at_dot;
- } SPACESTATE;
-
-
- bool pause=false;
- bool track = false;
- IplImage *curframe=NULL;
- IplImage *pBackImg=NULL;
- IplImage *pFrontImg=NULL;
- IplImage *pTrackImg =NULL;
- unsigned char * img;
- int xin,yin;
- int xout,yout;
- int Wid,Hei;
- int WidIn,HeiIn;
- int WidOut,HeiOut;
-
- long ran_seed = 802163120;
-
- float DELTA_T = (float)0.05;
- int POSITION_DISTURB = 15;
- float VELOCITY_DISTURB = 40.0;
- float SCALE_DISTURB = 0.0;
- float SCALE_CHANGE_D = (float)0.001;
-
- int NParticle = 75;
- float * ModelHist = NULL;
- SPACESTATE * states = NULL;
- float * weights = NULL;
- int nbin;
- float Pi_Thres = (float)0.90;
- float Weight_Thres = (float)0.0001;
-
-
- long set_seed( long setvalue )
- {
- if ( setvalue != 0 )
- ran_seed = setvalue;
- else
- {
- ran_seed = time(NULL);
- }
- return( ran_seed );
- }
-
- void CalcuColorHistogram( int x0, int y0, int Wx, int Hy,
- unsigned char * image, int W, int H,
- float * ColorHist, int bins )
- {
- int x_begin, y_begin;
- int y_end, x_end;
- int x, y, i, index;
- int r, g, b;
- float k, r2, f;
- int a2;
-
- for ( i = 0; i < bins; i++ )
- ColorHist[i] = 0.0;
-
-
- if ( ( x0 < 0 ) || (x0 >= W) || ( y0 < 0 ) || ( y0 >= H )
- || ( Wx <= 0 ) || ( Hy <= 0 ) ) return;
-
- x_begin = x0 - Wx;
- y_begin = y0 - Hy;
- if ( x_begin < 0 ) x_begin = 0;
- if ( y_begin < 0 ) y_begin = 0;
- x_end = x0 + Wx;
- y_end = y0 + Hy;
- if ( x_end >= W ) x_end = W-1;
- if ( y_end >= H ) y_end = H-1;
- a2 = Wx*Wx+Hy*Hy;
- f = 0.0;
- for ( y = y_begin; y <= y_end; y++ )
- for ( x = x_begin; x <= x_end; x++ )
- {
- r = image[(y*W+x)*3] >> R_SHIFT;
- g = image[(y*W+x)*3+1] >> G_SHIFT;
- b = image[(y*W+x)*3+2] >> B_SHIFT;
- index = r * G_BIN * B_BIN + g * B_BIN + b;
- r2 = (float)(((y-y0)*(y-y0)+(x-x0)*(x-x0))*1.0/a2);
- k = 1 - r2;
- f = f + k;
- ColorHist[index] = ColorHist[index] + k;
- }
- for ( i = 0; i < bins; i++ )
- ColorHist[i] = ColorHist[i]/f;
-
- return;
- }
-
- float CalcuBhattacharyya( float * p, float * q, int bins )
- {
- int i;
- float rho;
-
- rho = 0.0;
- for ( i = 0; i < bins; i++ )
- rho = (float)(rho + sqrt( p[i]*q[i] ));
-
- return( rho );
- }
-
-
- # define SIGMA2 0.02 /* 2*sigma^2, 这里sigma = 0.1 */
-
- float CalcuWeightedPi( float rho )
- {
- float pi_n, d2;
-
- d2 = 1 - rho;
-
- pi_n = (float)(exp( - d2/SIGMA2 ));
-
- return( pi_n );
- }
-
-
- float ran0(long *idum)
- {
- long k;
- float ans;
-
-
- k=(*idum)/IQ;
- *idum=IA*(*idum-k*IQ)-IR*k;
- if (*idum < 0) *idum += IM;
- ans=AM*(*idum);
-
- return ans;
- }
-
-
- float rand0_1()
- {
- return( ran0( &ran_seed ) );
- }
-
-
-
- float randGaussian( float u, float sigma )
- {
- float x1, x2, v1, v2;
- float s = 100.0;
- float y;
-
-
- while ( s > 1.0 )
- {
- x1 = rand0_1();
- x2 = rand0_1();
- v1 = 2 * x1 - 1;
- v2 = 2 * x2 - 1;
- s = v1*v1 + v2*v2;
- }
- y = (float)(sqrt( -2.0 * log(s)/s ) * v1);
-
- return( sigma * y + u );
- }
-
-
-
- int Initialize( int x0, int y0, int Wx, int Hy,
- unsigned char * img, int W, int H )
- {
- int i, j;
- float rn[7];
-
- set_seed( 0 );
-
-
-
- states = new SPACESTATE [NParticle];
- if ( states == NULL ) return( -2 );
- weights = new float [NParticle];
- if ( weights == NULL ) return( -3 );
- nbin = R_BIN * G_BIN * B_BIN;
- ModelHist = new float [nbin];
- if ( ModelHist == NULL ) return( -1 );
-
-
- CalcuColorHistogram( x0, y0, Wx, Hy, img, W, H, ModelHist, nbin );
-
-
- states[0].xt = x0;
- states[0].yt = y0;
- states[0].v_xt = (float)0.0;
- states[0].v_yt = (float)0.0;
- states[0].Hxt = Wx;
- states[0].Hyt = Hy;
- states[0].at_dot = (float)0.0;
- weights[0] = (float)(1.0/NParticle);
- for ( i = 1; i < NParticle; i++ )
- {
- for ( j = 0; j < 7; j++ ) rn[j] = randGaussian( 0, (float)0.6 );
- states[i].xt = (int)( states[0].xt + rn[0] * Wx );
- states[i].yt = (int)( states[0].yt + rn[1] * Hy );
- states[i].v_xt = (float)( states[0].v_xt + rn[2] * VELOCITY_DISTURB );
- states[i].v_yt = (float)( states[0].v_yt + rn[3] * VELOCITY_DISTURB );
- states[i].Hxt = (int)( states[0].Hxt + rn[4] * SCALE_DISTURB );
- states[i].Hyt = (int)( states[0].Hyt + rn[5] * SCALE_DISTURB );
- states[i].at_dot = (float)( states[0].at_dot + rn[6] * SCALE_CHANGE_D );
-
- weights[i] = (float)(1.0/NParticle);
- }
-
- return( 1 );
- }
-
-
-
- void NormalizeCumulatedWeight( float * weight, float * cumulateWeight, int N )
- {
- int i;
-
- for ( i = 0; i < N+1; i++ )
- cumulateWeight[i] = 0;
- for ( i = 0; i < N; i++ )
- cumulateWeight[i+1] = cumulateWeight[i] + weight[i];
- for ( i = 0; i < N+1; i++ )
- cumulateWeight[i] = cumulateWeight[i]/ cumulateWeight[N];
-
- return;
- }
-
- int BinearySearch( float v, float * NCumuWeight, int N )
- {
- int l, r, m;
-
- l = 0; r = N-1;
- while ( r >= l)
- {
- m = (l+r)/2;
- if ( v >= NCumuWeight[m] && v < NCumuWeight[m+1] ) return( m );
- if ( v < NCumuWeight[m] ) r = m - 1;
- else l = m + 1;
- }
- return( 0 );
- }
-
- void ImportanceSampling( float * c, int * ResampleIndex, int N )
- {
- float rnum, * cumulateWeight;
- int i, j;
-
- cumulateWeight = new float [N+1];
- NormalizeCumulatedWeight( c, cumulateWeight, N );
- for ( i = 0; i < N; i++ )
- {
- rnum = rand0_1();
- j = BinearySearch( rnum, cumulateWeight, N+1 );
- if ( j == N ) j--;
- ResampleIndex[i] = j;
- }
-
- delete cumulateWeight;
-
- return;
- }
-
- void ReSelect( SPACESTATE * state, float * weight, int N )
- {
- SPACESTATE * tmpState;
- int i, * rsIdx;
-
- tmpState = new SPACESTATE[N];
- rsIdx = new int[N];
-
- ImportanceSampling( weight, rsIdx, N );
- for ( i = 0; i < N; i++ )
- tmpState[i] = state[rsIdx[i]];
- for ( i = 0; i < N; i++ )
- state[i] = tmpState[i];
-
- delete[] tmpState;
- delete[] rsIdx;
-
- return;
- }
-
- void Propagate( SPACESTATE * state, int N)
- {
- int i;
- int j;
- float rn[7];
-
-
- for ( i = 0; i < N; i++ )
- {
- for ( j = 0; j < 7; j++ ) rn[j] = randGaussian( 0, (float)0.6 );
- state[i].xt = (int)(state[i].xt + state[i].v_xt * DELTA_T + rn[0] * state[i].Hxt + 0.5);
- state[i].yt = (int)(state[i].yt + state[i].v_yt * DELTA_T + rn[1] * state[i].Hyt + 0.5);
- state[i].v_xt = (float)(state[i].v_xt + rn[2] * VELOCITY_DISTURB);
- state[i].v_yt = (float)(state[i].v_yt + rn[3] * VELOCITY_DISTURB);
- state[i].Hxt = (int)(state[i].Hxt+state[i].Hxt*state[i].at_dot + rn[4] * SCALE_DISTURB + 0.5);
- state[i].Hyt = (int)(state[i].Hyt+state[i].Hyt*state[i].at_dot + rn[5] * SCALE_DISTURB + 0.5);
- state[i].at_dot = (float)(state[i].at_dot + rn[6] * SCALE_CHANGE_D);
- cvCircle(pTrackImg,cvPoint(state[i].xt,state[i].yt),3, CV_RGB(0,255,0),-1);
- }
- return;
- }
-
- void Observe( SPACESTATE * state, float * weight, int N,
- unsigned char * image, int W, int H,
- float * ObjectHist, int hbins )
- {
- int i;
- float * ColorHist;
- float rho;
-
- ColorHist = new float[hbins];
-
- for ( i = 0; i < N; i++ )
- {
-
- CalcuColorHistogram( state[i].xt, state[i].yt,state[i].Hxt, state[i].Hyt,
- image, W, H, ColorHist, hbins );
-
- rho = CalcuBhattacharyya( ColorHist, ObjectHist, hbins );
-
- weight[i] = CalcuWeightedPi( rho );
- }
-
- delete ColorHist;
-
- return;
- }
-
- void Estimation( SPACESTATE * state, float * weight, int N,
- SPACESTATE & EstState )
- {
- int i;
- float at_dot, Hxt, Hyt, v_xt, v_yt, xt, yt;
- float weight_sum;
-
- at_dot = 0;
- Hxt = 0; Hyt = 0;
- v_xt = 0; v_yt = 0;
- xt = 0; yt = 0;
- weight_sum = 0;
- for ( i = 0; i < N; i++ )
- {
- at_dot += state[i].at_dot * weight[i];
- Hxt += state[i].Hxt * weight[i];
- Hyt += state[i].Hyt * weight[i];
- v_xt += state[i].v_xt * weight[i];
- v_yt += state[i].v_yt * weight[i];
- xt += state[i].xt * weight[i];
- yt += state[i].yt * weight[i];
- weight_sum += weight[i];
- }
-
- if ( weight_sum <= 0 ) weight_sum = 1;
- EstState.at_dot = at_dot/weight_sum;
- EstState.Hxt = (int)(Hxt/weight_sum + 0.5 );
- EstState.Hyt = (int)(Hyt/weight_sum + 0.5 );
- EstState.v_xt = v_xt/weight_sum;
- EstState.v_yt = v_yt/weight_sum;
- EstState.xt = (int)(xt/weight_sum + 0.5 );
- EstState.yt = (int)(yt/weight_sum + 0.5 );
-
- return;
- }
-
-
- # define ALPHA_COEFFICIENT 0.2 /* 目标模型更新权重取0.1-0.3 */
-
- int ModelUpdate( SPACESTATE EstState, float * TargetHist, int bins, float PiT,
- unsigned char * img, int W, int H )
- {
- float * EstHist, Bha, Pi_E;
- int i, rvalue = -1;
-
- EstHist = new float [bins];
-
-
- CalcuColorHistogram( EstState.xt, EstState.yt, EstState.Hxt,
- EstState.Hyt, img, W, H, EstHist, bins );
-
- Bha = CalcuBhattacharyya( EstHist, TargetHist, bins );
-
- Pi_E = CalcuWeightedPi( Bha );
-
- if ( Pi_E > PiT )
- {
- for ( i = 0; i < bins; i++ )
- {
- TargetHist[i] = (float)((1.0 - ALPHA_COEFFICIENT) * TargetHist[i]
- + ALPHA_COEFFICIENT * EstHist[i]);
- }
- rvalue = 1;
- }
-
- delete EstHist;
-
- return( rvalue );
- }
-
- void ClearAll()
- {
- if ( ModelHist != NULL ) delete [] ModelHist;
- if ( states != NULL ) delete [] states;
- if ( weights != NULL ) delete [] weights;
-
- return;
- }
-
- int ColorParticleTracking( unsigned char * image, int W, int H,
- int & xc, int & yc, int & Wx_h, int & Hy_h,
- float & max_weight)
- {
- SPACESTATE EState;
- int i;
-
- ReSelect( states, weights, NParticle );
-
- Propagate( states, NParticle);
-
- Observe( states, weights, NParticle, image, W, H,
- ModelHist, nbin );
-
- Estimation( states, weights, NParticle, EState );
- xc = EState.xt;
- yc = EState.yt;
- Wx_h = EState.Hxt;
- Hy_h = EState.Hyt;
-
- ModelUpdate( EState, ModelHist, nbin, Pi_Thres, image, W, H );
-
-
- max_weight = weights[0];
- for ( i = 1; i < NParticle; i++ )
- max_weight = max_weight < weights[i] ? weights[i] : max_weight;
-
- if ( xc < 0 || yc < 0 || xc >= W || yc >= H ||
- Wx_h <= 0 || Hy_h <= 0 ) return( -1 );
- else
- return( 1 );
- }
-
-
-
- void IplToImge(IplImage* src, int w,int h)
- {
- int i,j;
- for ( j = 0; j < h; j++ )
- for ( i = 0; i < w; i++ )
- {
- img[ ( j*w+i )*3 ] = R(src,i,j);
- img[ ( j*w+i )*3+1 ] = G(src,i,j);
- img[ ( j*w+i )*3+2 ] = B(src,i,j);
- }
- }
- void mouseHandler(int event, int x, int y, int flags, void* param)
- {
- CvMemStorage* storage = cvCreateMemStorage(0);
- CvSeq * contours;
- IplImage* pFrontImg1 = 0;
- int centerX,centerY;
- int delt = 10;
- pFrontImg1=cvCloneImage(pFrontImg);
- switch(event){
- case CV_EVENT_LBUTTONDOWN:
-
-
- if(pause)
- {
- cvFindContours(pFrontImg,storage,&contours,sizeof(CvContour),CV_RETR_EXTERNAL,
- CV_CHAIN_APPROX_SIMPLE);
-
-
- for (;contours;contours = contours->h_next)
- {
- CvRect r = ((CvContour*)contours)->rect;
- if(x>r.x&&x<(r.x+r.width)&&y>r.y&&r.y<(r.y+r.height))
- {
- if (r.height*r.width>CONTOUR_MIN_AREA && r.height*r.width<CONTOUR_MAX_AREA)
- {
- centerX = r.x+r.width/2;
- centerY = r.y+r.height/2;
- WidIn = r.width/2;
- HeiIn = r.height/2;
- xin = centerX;
- yin = centerY;
- cvRectangle(pFrontImg1,cvPoint(r.x,r.y),cvPoint(r.x+r.width,r.y+r.height),cvScalar(255,255,255),2,8,0);
-
-
- Initialize( centerX, centerY, WidIn, HeiIn, img, Wid, Hei );
- track = true;
- cvShowImage("foreground",pFrontImg1);
- return;
-
- }
- }
-
- }
- }
-
- break;
-
- case CV_EVENT_LBUTTONUP:
- printf("Left button up\n");
- break;
- }
- }
-
- void main()
- {
- int FrameNum=0;
- int k=0;
- CvCapture *capture = cvCreateFileCapture("test.avi");
- char res1[20],res2[20];
-
-
- IplImage* frame[Num];
- int i,j;
- uchar key = false;
- float rho_v;
- float max_weight;
-
- int sum=0;
- for (i=0;i<Num;i++)
- {
- frame[i]=NULL;
- }
-
- IplImage *curFrameGray=NULL;
- IplImage *frameGray=NULL;
-
- CvMat *Mat_D,*Mat_F;
- int row ,col;
- cvNamedWindow("video",1);
-
- cvNamedWindow("background",1);
- cvNamedWindow("foreground",1);
- cvNamedWindow("tracking",1);
- cvSetMouseCallback("tracking",mouseHandler,0);
-
- while (capture)
- {
- curframe=cvQueryFrame(capture);
- if(FrameNum<Num)
- {
- if(FrameNum==0)
- {
- curFrameGray=cvCreateImage(cvGetSize(curframe),IPL_DEPTH_8U,1);
- frameGray=cvCreateImage(cvGetSize(curframe),IPL_DEPTH_8U,1);
- pBackImg=cvCreateImage(cvGetSize(curframe),IPL_DEPTH_8U,1);
- pFrontImg=cvCreateImage(cvGetSize(curframe),IPL_DEPTH_8U,1);
- pTrackImg = cvCreateImage(cvGetSize(curframe),IPL_DEPTH_8U,3);
-
- cvSetZero(pFrontImg);
- cvCvtColor(curframe,pBackImg,CV_RGB2GRAY);
-
- row=curframe->height;
- col=curframe->width;
- Mat_D=cvCreateMat(row,col,CV_32FC1);
- cvSetZero(Mat_D);
- Mat_F=cvCreateMat(row,col,CV_32FC1);
- cvSetZero(Mat_F);
- Wid = curframe->width;
- Hei = curframe->height;
- img = new unsigned char [Wid * Hei * 3];
- }
- frame[k]=cvCloneImage(curframe);
- pTrackImg = cvCloneImage(curframe);
- }
- else
- {
- k=FrameNum%Num;
- pTrackImg = cvCloneImage(curframe);
- IplToImge(curframe,Wid,Hei);
- cvCvtColor(curframe,curFrameGray,CV_RGB2GRAY);
- cvCvtColor(frame[k],frameGray,CV_RGB2GRAY);
- for(i=0;i<curframe->height;i++)
- for(j=0;j<curframe->width;j++)
- {
- sum=S(curFrameGray,j,i)-S(frameGray,j,i);
- sum=sum<0 ? -sum : sum;
- if(sum>T)
- {
- CV_MAT_ELEM(*Mat_F,float,i,j)=1;
- }
- else
- {
- CV_MAT_ELEM(*Mat_F,float,i,j)=0;
- }
-
- if(CV_MAT_ELEM(*Mat_F,float,i,j)!=0)
- CV_MAT_ELEM(*Mat_D,float,i,j)=Re;
- else{
- if(CV_MAT_ELEM(*Mat_D,float,i,j)!=0)
- CV_MAT_ELEM(*Mat_D,float,i,j)=CV_MAT_ELEM(*Mat_D,float,i,j)-1;
- }
- if(CV_MAT_ELEM(*Mat_D,float,i,j)==0.0)
- {
-
- S(pBackImg,j,i)=(uchar)((1-ai)*S(pBackImg,j,i)+ai*S(curFrameGray,j,i));
- }
- sum=S(curFrameGray,j,i)-S(pBackImg,j,i);
- sum=sum<0 ? -sum : sum;
- if(sum>40)
- {
- S(pFrontImg,j,i)=255;
- }
- else
- S(pFrontImg,j,i)=0;
-
- }
- frame[k]=cvCloneImage(curframe);
- }
- FrameNum++;
- k++;
- cout<<FrameNum<<endl;
-
-
- cvDilate(pFrontImg, pFrontImg, 0, 2);
- cvErode(pFrontImg, pFrontImg, 0, 3);
- cvDilate(pFrontImg, pFrontImg, 0, 1);
- if(track)
- {
-
- rho_v = ColorParticleTracking( img, Wid, Hei, xout, yout, WidOut, HeiOut, max_weight);
-
- if ( rho_v > 0 && max_weight > 0.0001 )
- {
- cvRectangle(pFrontImg,cvPoint(xout - WidOut,yout - HeiOut),cvPoint(xout+WidOut,yout+HeiOut),cvScalar(255,255,255),2,8,0);
- cvRectangle(pTrackImg,cvPoint(xout - WidOut,yout - HeiOut),cvPoint(xout+WidOut,yout+HeiOut),cvScalar(255,255,255),2,8,0);
- xin = xout; yin = yout;
- WidIn = WidOut; HeiIn = HeiOut;
-
- }
- }
-
- cvShowImage("video",curframe);
- cvShowImage("foreground",pFrontImg);
- cvShowImage("background",pBackImg);
- cvShowImage("tracking",pTrackImg);
-
- cvSetMouseCallback("foreground",mouseHandler,0);
- key = cvWaitKey(1);
- if(key == ‘p‘) pause = true;
- while(pause)
- if(cvWaitKey(0)==‘p‘)
- pause = false;
-
- }
- cvReleaseImage(&curFrameGray);
- cvReleaseImage(&frameGray);
- cvReleaseImage(&pBackImg);
- cvReleaseImage(&pFrontImg);
- cvDestroyAllWindows();
- ClearAll();
- }
实验结果:



基于粒子滤波器的目标跟踪算法及实现
原文:http://www.cnblogs.com/ywsoftware/p/4434602.html