粒子滤波的程序

 
粒子滤波的程序
2011-09-24 09:08

// particlebase.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include
#include
#include
#include "cvAux.h"   //粒子滤波所需的头文件
#include
#include
using namespace std;

IplImage *image = 0, *hsv = 0, *hue = 0, *mask = 0;
CvHistogram *hist = 0;
int select_object = 0;     //
int track_object = 0;      //
CvPoint origin;           
CvRect selection;        //the region of the object
CvRect track_window;      //the region of tracking place
int left_x = 0;
int left_y = 0;
double xv = 0.0;
double yv = 0.0;


//on_mouse select the region  .
//initialize the tracking place.
void on_mouse( int event, int x, int y, int flags, void *Non)
{
 if(!image)
  return;
 if(image->origin)
 {
  y = image->height - y;
 }
 if(select_object)
 {
  selection.x = MIN(x, origin.x); //ensure the start point less than the end point
  selection.y = MIN(y, origin.y);
  selection.width = selection.x + CV_IABS(x - origin.x); //ensure the width valid
  selection.height = selection.y + CV_IABS(y - origin.y);
  selection.x = MAX(selection.x, 0);     // start point must not be less than 0;
  selection.y = MAX(selection.y, 0);
  selection.width = MIN(selection.width, image->width);  
  selection.height = MIN(selection.height, image->height);
  selection.width -= selection.x;
  selection.height -= selection.y;
  track_window = cvRect(selection.x,selection.y,selection.width,selection.height);
 }
 switch(event)
 {
 case CV_EVENT_LBUTTONDOWN:
  origin = cvPoint(x, y);
  selection = cvRect(x, y, 0, 0);
  select_object = 1; //start to select object
  break;
 case CV_EVENT_LBUTTONUP:
  select_object = 0; //select finished
  left_x = selection.x;
  left_y = selection.y;
  if(selection.width > 0 && selection.height > 0)
   track_object = -1;  // if the region is valid ,then track the object
  cout<width<<"  "<height<<"   "<   break;
 }
}
/****************************************************/
//CalWeight
double CalWeight(int x, int y, IplImage *img, CvHistogram *object)
{
 IplImage* hue1;
 CvRect P_Region;

 CvHistogram *P_Hist;
 int histSize=180; //直方图针数
 float range0[]={0,180}; //第0维数值变化范围
 float * ranges[]={range0}; //第1维数值变化范围 

 P_Hist = cvCreateHist(1,&histSize,CV_HIST_ARRAY,ranges,1);//创建一个直方图

 P_Region = cvRect(x,y, selection.width, selection.height);
 cvSetImageROI(img, P_Region);
 hue1 = cvCreateImage( cvGetSize( img ), 8, 1);
 cvSplit(img, hue1, 0, 0, 0);
 cvResetImageROI(img);

 //计算粒子的直方图
 cvCalcHist(&hue1,P_Hist, 0, NULL);
 cvReleaseImage(&hue1);
 
 //直方图的归一化
 cvNormalizeHist(P_Hist, 1.0);
 cvNormalizeHist(object, 1.0);

 double ans = cvCompareHist(P_Hist, object,CV_COMP_BHATTACHARYYA);
// delete P_Hist;
 return 1- ans;
// cout<<"ans = "< // ans = (1/sqrt(2*3.1415926535897))*exp(-ans*ans);
// cout<<"weight = "< // return ans;
}

int main(int argc, char** argv)
{
 CvCapture* capture = 0;
 IplImage* tmp;
 IplImage* frame = 0;

//直方图部分
 CvHistogram *ObjectHist;
 int histSize=180; //直方图针数
 float range0[]={0,180}; //第0维数值变化范围
 float * ranges[]={range0}; //第1维数值变化范围
 ObjectHist=cvCreateHist(1,&histSize,CV_HIST_ARRAY,ranges,1);//创建一个直方图

//构造粒子对象
 int DP=2;             // 维度是2
 int MP=2;             //
 const int SamplesNum=100;  //  100   状态向量(x,y)的次元抽样个数为200


 CvConDensation* ConDens=cvCreateConDensation( DP, MP, SamplesNum );

//视频图像采集部分
 /*  capture = cvCreateFileCapture( "2.avi" );*/
 if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
  capture = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );//打开摄像头
 else if( argc == 2 )
  capture = cvCaptureFromAVI( argv[1] );//打开AVI文件
 if( !capture )
 {
  fprintf(stderr,"Could not initialize capturing...\n");//打开视频流失败处理
  return -1;
 }

//set a window for track
 cvNamedWindow("Particle_tracking_object", 1);

//设置回调函数
 cvSetMouseCallback("Particle_tracking_object", on_mouse);


  for( ; ; )
 {
  frame = cvQueryFrame( capture );
  if( !frame )
  {
   break;
  }
  if(! image)
  {
   image = cvCreateImage(cvGetSize(frame), 8, 3);
   image->origin = frame->origin ;
   hsv = cvCreateImage( cvGetSize(frame), 8, 3 );
   // add more information here
  }

  cvCopy(frame, image, 0);
  cvCvtColor( image, hsv, CV_BGR2HSV ); // convert RGB to HSV
  if(track_object)
  {
   //初始化粒子部分
   if(track_object<0)   
   {
    cvSetImageROI( hsv, selection );//set the region of interest
    tmp = cvCreateImage( cvGetSize( hsv ), 8, 3 );
    hue = cvCreateImage( cvGetSize(hsv), 8, 1 );
    cvCopy( hsv, tmp, NULL );
    cvSplit(tmp, hue, 0, 0, 0);

    //计算目标区域的直方图
    cvCalcHist(&hue,ObjectHist,0,NULL);

    cvResetImageROI( hsv );//free the ROI 

    //开始跟踪
    track_object = 1;

    //--------ConDens构造体的各抽样的初始化---------------------------
    CvMat* lowerBound;    //各次元的下限表示向量
    CvMat* upperBound;    // 各次元的上限表示向量
    lowerBound = cvCreateMat(2, 1, CV_32F);
    upperBound = cvCreateMat(2, 1, CV_32F);
    double Low_x = track_window.x - 60;
    double Upper_x = track_window.x + 60;
    double Low_y = track_window.y - 60;
    double Upper_y = track_window.y + 60;
    if (Low_x<0)
    {
     Low_x = 0.0;
    }
    if (Low_y < 0)
    {
     Low_y = 0.0;
    }
    if (Upper_x+selection.width>=image->width)
    {
     Upper_x = image->width - selection.width-1;

    }
    if (Upper_y + selection.height >= image->height)
    {
     Upper_y = image->height - selection.height -1;
    }
    cvmSet( lowerBound, 0, 0, Low_x ); cvmSet( upperBound, 0, 0,Upper_x );  //cvmSet(M,i,j,2.0); // Set M(i,j)
    cvmSet( lowerBound, 1, 0, Low_y); cvmSet( upperBound, 1, 0, Upper_y );

    cvConDensInitSampleSet(ConDens, lowerBound, upperBound);
    //-----------------------------------------------------------------------
    //状态转移方程---------------------------
    ConDens->DynamMatr[0]=1.0;ConDens->DynamMatr[1]=0.0;
    ConDens->DynamMatr[2]=0.0;ConDens->DynamMatr[3]=1.0;

  }
   

//   double weight[SamplesNum] ;
   double total_weight = 0.0;
   double leftx = 0.0;
   double lefty = 0.0;
   int X, Y;

   //计算权值
//   double big = 0.0;
//   int max_id;
   for(int i=0; i < SamplesNum; i++)
   {
    
    X=(int)ConDens->flSamples[i][0];
    Y=(int)ConDens->flSamples[i][1];
    if (X<0)
    {
     X = 0;
    }
    if (X+selection.width>=image->width)
    {
     X = image->width -selection.width -1;
    }
    if (Y<0)
    {
     Y = 0;
    }
    if (Y+selection.height>=image->height)
    {
     Y = image->height -selection.height -1;
    }
//    weight[i] = CalWeight(X,Y,hsv, ObjectHist);
    ConDens->flConfidence[i] = CalWeight(X,Y,hsv, ObjectHist);

/*    if (weight[i]>big)
    {
     big = weight[i];
     max_id = i;
    }*/
//    if (weight[i]>0.4)
//    {
//     ConDens->flConfidence[i]=1.0;
//    }
//    else
/*     ConDens->flConfidence[i]=0.1;*/

    total_weight += ConDens->flConfidence[i];
   }
   //权值归一化
   for (int i=0; i < SamplesNum; i++)
   {
//    weight[i] = weight[i]/total_weight;
//    cout< //    leftx += ConDens->flSamples[i][0]*weight[i];
//    lefty += ConDens->flSamples[i][1]*weight[i];
    leftx += ConDens->flSamples[i][0]* ConDens->flConfidence[i]/total_weight;
    lefty += ConDens->flSamples[i][1]* ConDens->flConfidence[i]/total_weight;
   }

   //估计当前的位置,更新
   track_window.x = (int)(leftx);
   track_window.y = (int)(lefty);
//   track_window.x = (int)ConDens->flSamples[max_id][0];
//   track_window.y = (int)ConDens->flSamples[max_id][1];
   track_window.width = selection.width;
   track_window.height = selection.height;
   if(track_window.x >=image->width||track_window.y>=image->height)
   {
    track_window.x = image->width-1;
    track_window.y =image->height-1;
   }

   if((track_window.x+track_window.width)>image->width ||(track_window.y+track_window.height)>image->height)
   {
    track_window.height = 0;
    track_window.width = 0;
   }
   CvPoint pt1 = cvPoint(track_window.x, track_window.y);

   CvPoint pt2 = cvPoint(track_window.x+track_window.width, track_window.y+track_window.height);

   cvRectangle(image,pt1,pt2,cvScalar(0,0,255),3);

   //定义均匀分布随机数
/*   CvRNG *rng_state =NULL;
   CvMat *locations = cvCreateMat(100, 1, CV_64FC1);
   cvRandArr(rng_state, locations, CV_RAND_UNI, cvRealScalar(0), cvRealScalar(1));
   double particle_x[SamplesNum],particle_y[SamplesNum];
   for (int i=0; i < SamplesNum; i++)
   {
    ConDens->flConfidence[i]=0.0;
    cout<     double u = cvGetReal2D(locations, i, 0);
    double wsum = 0.0;
    for (int j=0; j     {
     wsum += weight[j];
     if (wsum>=u)
     {
      particle_x[i] = ConDens->flSamples[j][0];
      particle_y[i] = ConDens->flSamples[j][1];
//      ConDens->flConfidence[j]=0.0;
     }
    }
    
   }*/
/*  for (int i=0; i < SamplesNum; i++)
  {
   if (weight[i]>0.4)
   {
    ConDens->flConfidence[i]=1.0;
   }
   else
    ConDens->flConfidence[i]=0.0;
  }*/
 cvConDensUpdateByTime(ConDens);
/*  for (int i=0; i < SamplesNum; i++)
  {
   ConDens->flSamples[i][0] = particle_x[i];
   ConDens->flSamples[i][1] = particle_y[i];
  }*/

  }
  int c;
  cvShowImage("Particle_tracking_object",image);
  c = cvWaitKey(100);
  if(c == 27)
   break;
 }
 delete ObjectHist;
 cvReleaseCapture( &capture );
 cvDestroyWindow("Particle_tracking_object");
 return 0;
}

 

你可能感兴趣的:(图像处理)