这期内容当中小编将会给大家带来有关OpenCV粒子滤波代码怎么写,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
OpenCV中实现了粒子滤波的代码,位置在c:\program
files\opencv\cv\src\cvcondens.cpp文件,通过分析这个文件,可以知道库函数中如何实现粒子滤波过程的。
首先是从手册上拷贝的粒子滤波跟踪器的数据结构:
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_IMPLCvConDensation*cvCreateConDensation(intDP,intMP,intSamplesNum
)
{
inti;
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__;
returnCD;
}
输入参数分别是系统状态向量维数、测量向量维数以及粒子个数,然后根据这些参数为滤波器相应结构分配空间。
CV_IMPLvoid
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_IMPLvoid
cvConDensInitSampleSet(CvConDensation
* conDens,CvMat *lowerBound,CvMat
*upperBound )
{
inti,j;
float *LBound;
float *UBound;
floatProb
= 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->da
UBound =upperBound->da
/* 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/5到1/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_IMPLvoid
cvConDensUpdateByTime(CvConDensation
* ConDens )
{
inti,j;
floatSum
= 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是内联函数,表示flConfidence乘flSamples,放到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__;
}
更新中用到的函数如下:
(1)
CV_INLINE void icvScaleVector_32f( const float* src, float* dst,
int len, double scale )
{
int i;
for( i = 0; i < len; i++ )
dst[i] = (float)(src[i]*scale);
icvCheckVector_32f( dst, len );
}
(2)
#define icvAddMatrix_32f( src1, src2, dst, w, h ) \
icvAddVector_32f( (src1), (src2), (dst), (w)*(h))
CV_INLINE void icvAddVector_32f( const float* src1, const float* src2,
float* dst, int len )
{
int i;
for( i = 0; i < len; i++ )
dst[i] = src1[i] + src2[i];
icvCheckVector_32f( dst, len );
}
(3)
#define icvTransformVector_32f( matr, src, dst, w, h ) \
icvMulMatrix_32f( matr, w, h, src, 1, w, dst )
CV_INLINE void icvMulMatrix_32f( const float* src1, int w1, int h2,
const float* src2, int w2, int h3,
float* dst )
{
int i, j, k;
if( w1 != h3 )
{
assert(0);
return;
}
for( i = 0; i < h2; i++, src1 += w1, dst += w2 )
for( j = 0; j < w2; j++ )
{
double s = 0;
for( k = 0; k < w1; k++ )
s += src1[k]*src2[j + k*w2];
dst[j] = (float)s;
}
icvCheckVector_32f( dst, h2*w2 );
}
(4)
#define icvCopyVector_32f( src, len, dst ) memcpy((dst),(src),(len)*sizeof(float))
(5)
CV_INLINE void cvbRand( CvRandState* state, float* dst, int len )
{
CvMat mat = cvMat( 1, len, CV_32F, (void*)dst );
cvRand( state, &mat );
}
CV_INLINE void cvRand( CvRandState* state, CvArr* arr )
{
if( !state )
{
cvError( CV_StsNullPtr, "cvRand", "Null pointer to RNG state", "cvcompat.h", 0 );
return;
}
cvRandArr( &state->state, arr, state->disttype, state->param[0], state->param[1] );
}
运行完上述函数之后,经重采样后的粒子保存在flSamples中,同时上次迭代的加权系统状态保存在State中
上述就是小编为大家分享的OpenCV粒子滤波代码怎么写了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。