引用OpenCV粒子滤波代码学习- 追梦的日志- 网易博客

引用 OpenCV粒子滤波代码学习

2010-04-13 10:13:46 阅读10 评论0 字号:

 

引用


OpenCV中实现了粒子滤波的代码,位置在c:\program files\opencv\cv\src\cvcondens.cpp文件,通过分析这个文件,可以知道库函数中如何实现粒子滤波过程的。

首先是从手册上拷贝的粒子滤波xxx的数据结构:

typedef struct CvConDensation
{
int MP; //
测量向量的维数: Dimension of measurement vector
int DP; //
状态向量的维数: Dimension of state vector
float* DynamMatr; //
线性动态系统矩阵:Matrix of the linear Dynamics system
float* State; //
状态向量: Vector of State
int SamplesNum; //
粒子数: Number of the Samples
float** flSamples; //
粒子向量数组: array of the Sample Vectors
float** flNewSamples; //
粒子向量临时数组: temporary array of the Sample Vectors
float* flConfidence; //
每个粒子的置信度(译者注:也就是粒子的权值)Confidence for each Sample
float* flCumulative; //
权值的累计: Cumulative confidence
float* Temp; //
临时向量:Temporary vector
float* RandomSample; //
用来更新粒子集的随机向量: RandomVector to update sample set
CvRandState* RandS; //
产生随机向量的结构数组: Array of structures to generate random vectors
} CvConDensation;

与粒子滤波相关的几个函数:

cvCreateConDensation:用于构造上述滤波器数据结构

cvReleaseConDensation:释放滤波器

cvConDensInitSampleSet:初始化粒子集

cvConDensUpdateByTime:更新粒子集

下面着重对这几个函数进行分析。

CV_IMPL CvConDensation* cvCreateConDensation( int DP, int MP, int SamplesNum )

{

    int i;

    CvConDensation *CD = 0;

 

    CV_FUNCNAME( "cvCreateConDensation" );

    __BEGIN__;

   

    if( DP < 0 || MP < 0 || SamplesNum < 0 )

        CV_ERROR( CV_StsOutOfRange, "" );

   

    /* allocating memory for the structure */

    CV_CALL( CD = (CvConDensation *) cvAlloc( sizeof( CvConDensation )));

    /* setting structure params */

    CD->SamplesNum = SamplesNum;

    CD->DP = DP;

    CD->MP = MP;

    /* allocating memory for structure fields */

    CV_CALL( CD->flSamples = (float **) cvAlloc( sizeof( float * ) * SamplesNum ));

    CV_CALL( CD->flNewSamples = (float **) cvAlloc( sizeof( float * ) * SamplesNum ));

    CV_CALL( CD->flSamples[0] = (float *) cvAlloc( sizeof( float ) * SamplesNum * DP ));

    CV_CALL( CD->flNewSamples[0] = (float *) cvAlloc( sizeof( float ) * SamplesNum * DP ));

 

    /* setting pointers in pointer's arrays */

    for( i = 1; i < SamplesNum; i++ )

    {

        CD->flSamples[i] = CD->flSamples[i - 1] + DP;

        CD->flNewSamples[i] = CD->flNewSamples[i - 1] + DP;

    }

 

    CV_CALL( CD->State = (float *) cvAlloc( sizeof( float ) * DP ));

    CV_CALL( CD->DynamMatr = (float *) cvAlloc( sizeof( float ) * DP * DP ));

    CV_CALL( CD->flConfidence = (float *) cvAlloc( sizeof( float ) * SamplesNum ));

    CV_CALL( CD->flCumulative = (float *) cvAlloc( sizeof( float ) * SamplesNum ));

 

    CV_CALL( CD->RandS = (CvRandState *) cvAlloc( sizeof( CvRandState ) * DP ));

    CV_CALL( CD->Temp = (float *) cvAlloc( sizeof( float ) * DP ));

    CV_CALL( CD->RandomSample = (float *) cvAlloc( sizeof( float ) * DP ));

 

    /* Returning created structure */

    __END__;

 

    return CD;

}

 

输入参数分别是系统状态向量维数、测量向量维数以及粒子个数,然后根据这些参数为滤波器相应结构分配空间。

CV_IMPL void

cvReleaseConDensation( CvConDensation ** ConDensation )

{

    CV_FUNCNAME( "cvReleaseConDensation" );

    __BEGIN__;

   

    CvConDensation *CD = *ConDensation;

   

    if( !ConDensation )

        CV_ERROR( CV_StsNullPtr, "" );

 

    if( !CD )

        EXIT;

 

    /* freeing the memory */

     cvFree( &CD->State );

    cvFree( &CD->DynamMatr);

    cvFree( &CD->flConfidence );

    cvFree( &CD->flCumulative );

    cvFree( &CD->flSamples[0] );

    cvFree( &CD->flNewSamples[0] );

    cvFree( &CD->flSamples );

    cvFree( &CD->flNewSamples );

    cvFree( &CD->Temp );

    cvFree( &CD->RandS );

    cvFree( &CD->RandomSample );

    /* release structure */

    cvFree( ConDensation );

   

    __END__;

 

}

释放滤波器占用的空间,没什么好说的

CV_IMPL void

cvConDensInitSampleSet( CvConDensation * conDens, CvMat * lowerBound, CvMat * upperBound )

{

    int i, j;

    float *LBound;

    float *UBound;

    float Prob = 1.f / conDens->SamplesNum;

 

    CV_FUNCNAME( "cvConDensInitSampleSet" );

    __BEGIN__;

   

    if( !conDens || !lowerBound || !upperBound )

        CV_ERROR( CV_StsNullPtr, "" );

 

    if( CV_MAT_TYPE(lowerBound->type) != CV_32FC1 ||

        !CV_ARE_TYPES_EQ(lowerBound,upperBound) )

        CV_ERROR( CV_StsBadArg, "source  has not appropriate format" );

 

    if( (lowerBound->cols != 1) || (upperBound->cols != 1) )

        CV_ERROR( CV_StsBadArg, "source  has not appropriate size" );

 

    if( (lowerBound->rows != conDens->DP) || (upperBound->rows != conDens->DP) )

        CV_ERROR( CV_StsBadArg, "source  has not appropriate size" );

 

    LBound = lowerBound->data.fl;

    UBound = upperBound->data.fl;

/* Initializing the structures to create initial Sample set */

这里根据输入的动态范围给每个系统状态分配一个产生随即数的结构

    for( i = 0; i < conDens->DP; i++ )

    {

        cvRandInit( &(conDens->RandS[i]),

                    LBound[i],

                    UBound[i],

                    i );

    }

/* Generating the samples */

根据产生的随即数,为每个粒子的每个系统状态分配初始值,并将每个粒子的置信度设置为相同的1/n

    for( j = 0; j < conDens->SamplesNum; j++ )

    {

        for( i = 0; i < conDens->DP; i++ )

        {

            cvbRand( conDens->RandS + i, conDens->flSamples[j] + i, 1 );

        }

        conDens->flConfidence[j] = Prob;

    }

/* Reinitializes the structures to update samples randomly */

产生以后更新粒子系统状态的随即结构,采样范围为原来初始范围的-1/51/5

    for( i = 0; i < conDens->DP; i++ )

    {

        cvRandInit( &(conDens->RandS[i]),

                    (LBound[i] - UBound[i]) / 5,

                    (UBound[i] - LBound[i]) / 5,

                    i);

    }

 

    __END__;

}

 

CV_IMPL void

cvConDensUpdateByTime( CvConDensation * ConDens )

{

    int i, j;

    float Sum = 0;

 

    CV_FUNCNAME( "cvConDensUpdateByTime" );

    __BEGIN__;

   

    if( !ConDens )

        CV_ERROR( CV_StsNullPtr, "" );

 

    /* Sets Temp to Zero */

    icvSetZero_32f( ConDens->Temp, ConDens->DP, 1 );

 

/* Calculating the Mean */

icvScaleVector_32f是内联函数,表示flConfidenceflSamples,放到State里,即求系统状态的过程,系统状态保存在temp

    for( i = 0; i < ConDens->SamplesNum; i++ )

    {

        icvScaleVector_32f( ConDens->flSamples[i], ConDens->State, ConDens->DP,

                             ConDens->flConfidence[i] );

        icvAddVector_32f( ConDens->Temp, ConDens->State, ConDens->Temp, ConDens->DP );

        Sum += ConDens->flConfidence[i];

        ConDens->flCumulative[i] = Sum;

    }

 

    /* Taking the new vector from transformation of mean by dynamics matrix */

 

    icvScaleVector_32f( ConDens->Temp, ConDens->Temp, ConDens->DP, 1.f / Sum );

    icvTransformVector_32f( ConDens->DynamMatr, ConDens->Temp, ConDens->State, ConDens->DP,

                             ConDens->DP );

    Sum = Sum / ConDens->SamplesNum;

 

/* Updating the set of random samples */

重采样,将新采样出来的粒子保存在flNewSamples

    for( i = 0; i < ConDens->SamplesNum; i++ )

    {

        j = 0;

        while( (ConDens->flCumulative[j] <= (float) i * Sum)&&(j<ConDens->SamplesNum-1))

        {

            j++;

        }

        icvCopyVector_32f( ConDens->flSamples[j], ConDens->DP, ConDens->flNewSamples[i] );

    }

 

    /* Adding the random-generated vector to every vector in sample set */

    for( i = 0; i < ConDens->SamplesNum; i++ )

{

为每个新粒子产生一个随即量

        for( j = 0; j < ConDens->DP; j++ )

        {

            cvbRand( ConDens->RandS + j, ConDens->RandomSample + j, 1 );

        }

flNewSamples加一个随即量,保存入flSamples

        icvTransformVector_32f( ConDens->DynamMatr, ConDens->flNewSamples[i],

                                 ConDens->flSamples[i], ConDens->DP, ConDens->DP );

        icvAddVector_32f( ConDens->flSamples[i], ConDens->RandomSample, ConDens->flSamples[i],

                           ConDens->DP );

    }

 

    __END__;

}

运行完上述函数之后,经重采样后的粒子保存在flSamples中,同时上次迭代的加权系统状态保存在State

 

 

<#--{zx1}日志--> <#--推荐日志--> <#--引用记录--> <#--相关日志--> <#--推荐日志--> <#--推荐阅读--> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构-->
郑重声明:资讯 【引用OpenCV粒子滤波代码学习- 追梦的日志- 网易博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——