You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
566 lines
18 KiB
566 lines
18 KiB
9 years ago
|
/*
|
||
|
************************** SLEDOVANIE OBJEKTU VO VIDEU *************************
|
||
|
********************************* Peter Betko **********************************
|
||
|
|
||
|
autor: Peter Betko
|
||
|
datum: 11.10.2011
|
||
|
|
||
|
Program na sledovanie objektu vo videu, s vyuzitim algoritmov zalozenych na baze
|
||
|
Casticoveho filtra (Particle filter).
|
||
|
|
||
|
subor cvparticle.h - systemovy model, praca s casticami
|
||
|
*/
|
||
|
/* The MIT License
|
||
|
*
|
||
|
* Copyright (c) 2008, Naotoshi Seo <sonots(at)sonots.com>
|
||
|
*
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
* of this software and associated documentation files (the "Software"), to deal
|
||
|
* in the Software without restriction, including without limitation the rights
|
||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
* copies of the Software, and to permit persons to whom the Software is
|
||
|
* furnished to do so, subject to the following conditions:
|
||
|
*
|
||
|
* The above copyright notice and this permission notice shall be included in
|
||
|
* all copies or substantial portions of the Software.
|
||
|
*/
|
||
|
#ifndef CV_PARTICLE_INCLUDED
|
||
|
#define CV_PARTICLE_INCLUDED
|
||
|
|
||
|
#include "cv.h"
|
||
|
#include "cvaux.h"
|
||
|
#include "cxcore.h"
|
||
|
|
||
|
#include <time.h>
|
||
|
#include "cvsetrow.h"
|
||
|
#include "cvsetcol.h"
|
||
|
#include "cvlogsum.h"
|
||
|
#include "cvanglemean.h"
|
||
|
#include "cvrandgauss.h"
|
||
|
|
||
|
/******************************* Structures **********************************/
|
||
|
/**
|
||
|
* Particle Filter structure
|
||
|
*/
|
||
|
typedef struct CvParticle {
|
||
|
// config
|
||
|
int num_states; /**< Number of tracking states, e.g.,
|
||
|
4 if x, y, width, height */
|
||
|
int num_particles; /**< Number of particles */
|
||
|
bool logweight; /**< log weights are stored in "weights". */
|
||
|
// transition
|
||
|
CvMat* dynamics; /**< num_states x num_states. Dynamics model. */
|
||
|
CvRNG rng; /**< Random seed */
|
||
|
CvMat* std; /**< num_states x 1. Standard deviation for gaussian noise
|
||
|
Set standard deviation == 0 for no noise */
|
||
|
CvMat* stds; /**< num_states x num_particles.
|
||
|
Std for each particle so that you could be varying
|
||
|
noise variance for each particle.
|
||
|
"std" is used if "stds" is not set. */
|
||
|
CvMat* bound; /**< num_states x 3 (lowerbound, upperbound,
|
||
|
wrap_around (like angle) flag 0 or 1)
|
||
|
Set lowerbound == upperbound to express no bound */
|
||
|
// particle states
|
||
|
CvMat* particles; /**< num_states x num_particles. The particles.
|
||
|
The transition states values of all particles. */
|
||
|
CvMat* weights; /**< 1 x num_particles. The weights of
|
||
|
each particle respect to the particle id in "particles".
|
||
|
"weights" are used to approximated the posterior pdf. */
|
||
|
} CvParticle;
|
||
|
|
||
|
/**************************** Function Prototypes ****************************/
|
||
|
|
||
|
#ifndef NO_DOXYGEN
|
||
|
CVAPI(CvParticle*) cvCreateParticle( int num_states, int num_particles, bool logweight );
|
||
|
CVAPI(void) cvReleaseParticle( CvParticle** p );
|
||
|
|
||
|
CVAPI(void) cvParticleSetDynamics( CvParticle* p, const CvMat* dynamics );
|
||
|
CVAPI(void) cvParticleSetNoise( CvParticle* p, CvRNG rng, const CvMat* std );
|
||
|
CVAPI(void) cvParticleSetBound( CvParticle* p, const CvMat* bound );
|
||
|
|
||
|
CVAPI(int) cvParticleGetMax( const CvParticle* p );
|
||
|
CVAPI(void) cvParticleGetMean( const CvParticle* p, CvMat* meanp );
|
||
|
CVAPI(void) cvParticlePrint( const CvParticle* p, int p_id );
|
||
|
|
||
|
CVAPI(void) cvParticleBound( CvParticle* p );
|
||
|
CVAPI(void) cvParticleNormalize( CvParticle* p );
|
||
|
|
||
|
CVAPI(void) cvParticleInit( CvParticle* p, const CvParticle* init );
|
||
|
CVAPI(void) cvParticleTransition( CvParticle* p );
|
||
|
CVAPI(void) cvParticleResample( CvParticle* p );
|
||
|
#endif
|
||
|
|
||
|
/*************************** Constructor / Destructor *************************/
|
||
|
|
||
|
/**
|
||
|
* Allocate Particle filter structure
|
||
|
*
|
||
|
* @param num_states Number of tracking states, e.g., 4 if x, y, width, height
|
||
|
* @param num_particles Number of particles
|
||
|
* @param logweight The weights parameter is log or not
|
||
|
* @return CvParticle*
|
||
|
*/
|
||
|
CVAPI(CvParticle*) cvCreateParticle( int num_states,
|
||
|
int num_particles,
|
||
|
bool logweight CV_DEFAULT(false) )
|
||
|
{
|
||
|
CvParticle *p = NULL;
|
||
|
CV_FUNCNAME( "cvCreateParticle" );
|
||
|
__CV_BEGIN__;
|
||
|
CV_ASSERT( num_states > 0 );
|
||
|
CV_ASSERT( num_particles > 0 );
|
||
|
p = (CvParticle *) cvAlloc( sizeof( CvParticle ) );
|
||
|
p->num_particles = num_particles;
|
||
|
p->num_states = num_states;
|
||
|
p->dynamics = cvCreateMat( num_states, num_states, CV_32FC1 );
|
||
|
p->rng = 1;
|
||
|
p->std = cvCreateMat( num_states, 1, CV_32FC1 );
|
||
|
p->bound = cvCreateMat( num_states, 3, CV_32FC1 );
|
||
|
p->particles = cvCreateMat( num_states, num_particles, CV_32FC1 );
|
||
|
p->weights = cvCreateMat( 1, num_particles, CV_64FC1 );
|
||
|
p->logweight = logweight;
|
||
|
p->stds = NULL;
|
||
|
|
||
|
// Default dynamics: next state = curr state + noise
|
||
|
cvSetIdentity( p->dynamics, cvScalar(1.0) );
|
||
|
cvSet( p->std, cvScalar(1.0) );
|
||
|
|
||
|
cvZero( p->bound );
|
||
|
|
||
|
__CV_END__;
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Release Particle filter structure
|
||
|
*
|
||
|
* @param particle
|
||
|
*/
|
||
|
CVAPI(void) cvReleaseParticle( CvParticle** particle )
|
||
|
{
|
||
|
CvParticle *p = NULL;
|
||
|
CV_FUNCNAME( "cvReleaseParticle" );
|
||
|
__CV_BEGIN__;
|
||
|
p = *particle;
|
||
|
if( !p ) __CV_EXIT__;
|
||
|
|
||
|
CV_CALL( cvReleaseMat( &p->dynamics ) );
|
||
|
CV_CALL( cvReleaseMat( &p->std ) );
|
||
|
CV_CALL( cvReleaseMat( &p->bound ) );
|
||
|
CV_CALL( cvReleaseMat( &p->particles ) );
|
||
|
CV_CALL( cvReleaseMat( &p->weights ) );
|
||
|
if( p->stds != NULL )
|
||
|
CV_CALL( cvReleaseMat( &p->stds ) );
|
||
|
|
||
|
CV_CALL( cvFree( &p ) );
|
||
|
__CV_END__;
|
||
|
}
|
||
|
|
||
|
/***************************** Setter ***************************************/
|
||
|
|
||
|
/**
|
||
|
* Set dynamics model
|
||
|
*
|
||
|
* @param particle
|
||
|
* @param dynamics (num_states) x (num_states). dynamics model
|
||
|
* new_state = dynamics * curr_state + noise
|
||
|
*/
|
||
|
CVAPI(void) cvParticleSetDynamics( CvParticle* p, const CvMat* dynamics )
|
||
|
{
|
||
|
CV_FUNCNAME( "cvParticleSetDynamics" );
|
||
|
__CV_BEGIN__;
|
||
|
CV_ASSERT( p->num_states == dynamics->rows );
|
||
|
CV_ASSERT( p->num_states == dynamics->cols );
|
||
|
//cvCopy( dynamics, p->dynamics );
|
||
|
cvConvert( dynamics, p->dynamics );
|
||
|
__CV_END__;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set noise model
|
||
|
*
|
||
|
* @param particle
|
||
|
* @param rng random seed. refer cvRNG(time(NULL))
|
||
|
* @param std num_states x 1. standard deviation for gaussian noise
|
||
|
* Set standard deviation == 0 for no noise
|
||
|
*/
|
||
|
CVAPI(void) cvParticleSetNoise( CvParticle* p, CvRNG rng, const CvMat* std )
|
||
|
{
|
||
|
CV_FUNCNAME( "cvParticleSetNoise" );
|
||
|
__CV_BEGIN__;
|
||
|
CV_ASSERT( p->num_states == std->rows );
|
||
|
p->rng = rng;
|
||
|
//cvCopy( std, p->std );
|
||
|
cvConvert( std, p->std );
|
||
|
__CV_END__;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set lowerbound and upperbound used for bounding tracking state transition
|
||
|
*
|
||
|
* @param particle
|
||
|
* @param bound num_states x 3 (lowerbound, upperbound, circular flag 0 or 1)
|
||
|
* Set lowerbound == upperbound to express no bound
|
||
|
*/
|
||
|
CVAPI(void) cvParticleSetBound( CvParticle* p, const CvMat* bound )
|
||
|
{
|
||
|
CV_FUNCNAME( "cvParticleSetBound" );
|
||
|
__CV_BEGIN__;
|
||
|
CV_ASSERT( p->num_states == bound->rows );
|
||
|
CV_ASSERT( 3 == bound->cols );
|
||
|
//cvCopy( bound, p->bound );
|
||
|
cvConvert( bound, p->bound );
|
||
|
__CV_END__;
|
||
|
}
|
||
|
|
||
|
/************************ Utility ******************************************/
|
||
|
|
||
|
/**
|
||
|
* Get id of the most probable particle
|
||
|
*
|
||
|
* @param particle
|
||
|
* @return int
|
||
|
*/
|
||
|
CVAPI(int) cvParticleGetMax( const CvParticle* p )
|
||
|
{
|
||
|
double minval, maxval;
|
||
|
CvPoint min_loc, max_loc;
|
||
|
cvMinMaxLoc( p->weights, &minval, &maxval, &min_loc, &max_loc );
|
||
|
return max_loc.x;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get evaluation of the most probable particle
|
||
|
*
|
||
|
* @param particle
|
||
|
* @return double
|
||
|
*/
|
||
|
CVAPI(double) cvParticleGetMaxVal( const CvParticle* p )
|
||
|
{
|
||
|
double minval, maxval;
|
||
|
CvPoint min_loc, max_loc;
|
||
|
cvMinMaxLoc( p->weights, &minval, &maxval, &min_loc, &max_loc );
|
||
|
return maxval;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the mean state (particle)
|
||
|
*
|
||
|
* @param particle
|
||
|
* @param meanp num_states x 1, CV_32FC1 or CV_64FC1
|
||
|
* @return CVAPI(void)
|
||
|
*/
|
||
|
CVAPI(void) cvParticleGetMean( const CvParticle* p, CvMat* meanp )
|
||
|
{
|
||
|
CvMat* weights = NULL;
|
||
|
CvMat* particles_i, hdr;
|
||
|
int i, j;
|
||
|
CV_FUNCNAME( "cvParticleGetMean" );
|
||
|
__CV_BEGIN__;
|
||
|
CV_ASSERT( meanp->rows == p->num_states && meanp->cols == 1 );
|
||
|
if( !p->logweight )
|
||
|
{
|
||
|
weights = p->weights;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
weights = cvCreateMat( 1, p->num_particles, p->weights->type );
|
||
|
cvExp( p->weights, weights );
|
||
|
}
|
||
|
|
||
|
for( i = 0; i < p->num_states; i++ )
|
||
|
{
|
||
|
int circular = (int) cvmGet( p->bound, i, 2 );
|
||
|
if( !circular ) // usual mean
|
||
|
{
|
||
|
particles_i = cvGetRow( p->particles, &hdr, i );
|
||
|
double mean = 0;
|
||
|
for( j = 0; j < p->num_particles; j++ )
|
||
|
{
|
||
|
mean += cvmGet( particles_i, 0, j ) * cvmGet( weights, 0, j );
|
||
|
}
|
||
|
cvmSet( meanp, i, 0, mean );
|
||
|
}
|
||
|
else // wrapped mean (angle)
|
||
|
{
|
||
|
double wrap = cvmGet( p->bound, i, 1 ) - cvmGet( p->bound, i, 0 );
|
||
|
particles_i = cvGetRow( p->particles, &hdr, i );
|
||
|
CvScalar mean = cvAngleMean( particles_i, weights, wrap );
|
||
|
cvmSet( meanp, i, 0, mean.val[0] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( weights != p->weights )
|
||
|
cvReleaseMat( &weights );
|
||
|
__CV_END__;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Print states of a particle
|
||
|
*
|
||
|
* @param particle
|
||
|
* @param p_id particle id
|
||
|
*/
|
||
|
CVAPI(void) cvParticlePrint( const CvParticle*p, int p_id CV_DEFAULT(-1) )
|
||
|
{
|
||
|
if( p_id == -1 ) // print all
|
||
|
{
|
||
|
int n;
|
||
|
for( n = 0; n < p->num_particles; n++ )
|
||
|
{
|
||
|
cvParticlePrint( p, n );
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
int i;
|
||
|
for( i = 0; i < p->num_states; i++ )
|
||
|
{
|
||
|
printf( "%6.1f ", cvmGet( p->particles, i, p_id ) );
|
||
|
}
|
||
|
printf( "\n" );
|
||
|
fflush( stdout );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/****************************** Helper functions ******************************/
|
||
|
/*
|
||
|
* Do normalization of weights
|
||
|
*
|
||
|
* @param particle
|
||
|
* @see cvParticleResample
|
||
|
*/
|
||
|
CVAPI(void) cvParticleNormalize( CvParticle* p )
|
||
|
{
|
||
|
if( !p->logweight )
|
||
|
{
|
||
|
CvScalar normterm = cvSum( p->weights );
|
||
|
cvScale( p->weights, p->weights, 1.0 / normterm.val[0] );
|
||
|
}
|
||
|
else // log version
|
||
|
{
|
||
|
CvScalar normterm = cvLogSum( p->weights );
|
||
|
//printf("%.3f %.3f %.3f %.3f\n", normterm.val[0],normterm.val[1],normterm.val[2],normterm.val[3]);
|
||
|
cvSubS( p->weights, normterm, p->weights );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Apply lower bound and upper bound for particle states.
|
||
|
*
|
||
|
* @param particle
|
||
|
* @note Used by See also functions
|
||
|
* @see cvParticleTransition
|
||
|
*/
|
||
|
CVAPI(void) cvParticleBound( CvParticle* p )
|
||
|
{
|
||
|
int row, col;
|
||
|
double lower, upper;
|
||
|
int circular;
|
||
|
CvMat* stateparticles, hdr;
|
||
|
float state;
|
||
|
// @todo: np.width = (double)MAX( 2.0, MIN( maxX - 1 - x, width ) );
|
||
|
for( row = 0; row < p->num_states; row++ )
|
||
|
{
|
||
|
lower = cvmGet( p->bound, row, 0 );
|
||
|
upper = cvmGet( p->bound, row, 1 );
|
||
|
circular = (int) cvmGet( p->bound, row, 2 );
|
||
|
if( lower == upper ) continue; // no bound flag
|
||
|
if( circular ) {
|
||
|
for( col = 0; col < p->num_particles; col++ ) {
|
||
|
state = cvmGet( p->particles, row, col );
|
||
|
state = state < lower ? state + upper : ( state >= upper ? state - upper : state );
|
||
|
cvmSet( p->particles, row, col, state );
|
||
|
}
|
||
|
} else {
|
||
|
stateparticles = cvGetRow( p->particles, &hdr, row );
|
||
|
cvMinS( stateparticles, upper, stateparticles );
|
||
|
cvMaxS( stateparticles, lower, stateparticles );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/******************* Main (Related to Algorithm) *****************************/
|
||
|
|
||
|
/**
|
||
|
* Initialize states
|
||
|
*
|
||
|
* If initial states are given, these states are uniformly copied.
|
||
|
* If not given, states are uniform randomly sampled within lowerbound
|
||
|
* and upperbound regions.
|
||
|
*
|
||
|
* @param particle
|
||
|
* @param init initial states.
|
||
|
*/
|
||
|
CVAPI(void) cvParticleInit( CvParticle* p, const CvParticle* init = NULL )
|
||
|
{
|
||
|
int i, c, n, s;
|
||
|
if( init ) // copy
|
||
|
{
|
||
|
int *num_copy;
|
||
|
CvMat init_particle;
|
||
|
|
||
|
int divide = p->num_particles / init->num_particles;
|
||
|
int remain = p->num_particles - divide * init->num_particles;
|
||
|
num_copy = (int*) malloc( init->num_particles * sizeof(int) );
|
||
|
for( i = 0; i < init->num_particles; i++ )
|
||
|
{
|
||
|
num_copy[i] = divide + ( i < remain ? 1 : 0 );
|
||
|
}
|
||
|
|
||
|
n = 0; // copy all states once
|
||
|
for( i = 0; i < init->num_particles; i++ )
|
||
|
{
|
||
|
cvGetCol( init->particles, &init_particle, i );
|
||
|
for( c = 0; c < num_copy[i]; c++ )
|
||
|
{
|
||
|
cvSetCol( &init_particle, p->particles, n++ );
|
||
|
}
|
||
|
}
|
||
|
// randomize partial states if necessary
|
||
|
for( s = 0; s < init->num_states; s++ )
|
||
|
{
|
||
|
n = 0;
|
||
|
for( i = 0; i < init->num_particles; i++ )
|
||
|
{
|
||
|
if( FLT_MAX - cvmGet( init->particles, s, i ) < FLT_EPSILON ) // randomize flag
|
||
|
{
|
||
|
CvScalar lower, upper;
|
||
|
CvMat* statenoiseT = cvCreateMat( num_copy[i], 1, p->particles->type );
|
||
|
lower = cvScalar( cvmGet( p->bound, s, 0 ) );
|
||
|
upper = cvScalar( cvmGet( p->bound, s, 1 ) );
|
||
|
cvRandArr( &p->rng, statenoiseT, CV_RAND_UNI, lower, upper );
|
||
|
for( c = 0; c < num_copy[i]; c++ )
|
||
|
{
|
||
|
cvmSet( p->particles, s, n++, cvmGet( statenoiseT, c, 0 ) );
|
||
|
}
|
||
|
cvReleaseMat( &statenoiseT );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
free( num_copy );
|
||
|
}
|
||
|
else // randomize all states
|
||
|
{
|
||
|
CvScalar lower, upper;
|
||
|
CvMat* statenoiseT = cvCreateMat( p->num_particles, 1, p->particles->type );
|
||
|
CvMat* statenoise = cvCreateMat( 1, p->num_particles, p->particles->type );
|
||
|
for( s = 0; s < p->num_states; s++ )
|
||
|
{
|
||
|
lower = cvScalar( cvmGet( p->bound, s, 0 ) );
|
||
|
upper = cvScalar( cvmGet( p->bound, s, 1 ) );
|
||
|
cvRandArr( &p->rng, statenoiseT, CV_RAND_UNI, lower, upper );
|
||
|
cvT( statenoiseT, statenoise );
|
||
|
cvSetRow( statenoise, p->particles, s );
|
||
|
}
|
||
|
cvReleaseMat( &statenoise );
|
||
|
cvReleaseMat( &statenoiseT );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Samples new particles from given particles
|
||
|
*
|
||
|
* Currently suppports only linear combination of states transition model.
|
||
|
* Write up a function by yourself to supports nonlinear dynamics
|
||
|
* such as Taylor series model and call your function instead of this function.
|
||
|
* Other functions should not necessary be modified.
|
||
|
*
|
||
|
* @param particle
|
||
|
* @note Uses See also functions inside.
|
||
|
* @see cvParticleBound
|
||
|
*/
|
||
|
CVAPI(void) cvParticleTransition( CvParticle* p )
|
||
|
{
|
||
|
int i, j;
|
||
|
CvMat* transits = cvCreateMat( p->num_states, p->num_particles, p->particles->type );
|
||
|
CvMat* noises = cvCreateMat( p->num_states, p->num_particles, p->particles->type );
|
||
|
CvMat* noise, noisehdr;
|
||
|
double std;
|
||
|
|
||
|
// dynamics
|
||
|
cvMatMul( p->dynamics, p->particles, transits );
|
||
|
|
||
|
// noise generation
|
||
|
if( p->stds == NULL ) //sum je pre vsetky particles rovnaky
|
||
|
{
|
||
|
for( i = 0; i < p->num_states; i++ ) //pre kazdy state (x,y,w,h,r)
|
||
|
{
|
||
|
std = cvmGet( p->std, i, 0 );
|
||
|
noise = cvGetRow( noises, &noisehdr, i );
|
||
|
if( std == 0.0 )
|
||
|
cvZero( noise );
|
||
|
else
|
||
|
cvRandArr( &p->rng, noise, CV_RAND_NORMAL, cvScalar(0), cvScalar( std ) );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for( i = 0; i < p->num_states; i++ )
|
||
|
{
|
||
|
for( j = 0; j < p->num_particles; j++ )
|
||
|
{
|
||
|
std = cvmGet( p->stds, i, j );
|
||
|
if( std == 0.0 )
|
||
|
cvmSet( noises, i, j, 0.0 );
|
||
|
else
|
||
|
cvmSet( noises, i, j, cvRandGauss( &p->rng, std ) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// dynamics + noise
|
||
|
cvAdd( transits, noises, p->particles );
|
||
|
|
||
|
cvReleaseMat( &transits );
|
||
|
cvReleaseMat( &noises );
|
||
|
|
||
|
cvParticleBound( p );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Re-samples a set of particles according to their weights to produce a
|
||
|
* new set of unweighted particles
|
||
|
*
|
||
|
* Simply copy, not uniform randomly selects
|
||
|
*
|
||
|
* @param particle
|
||
|
* @note Uses See also functions inside.
|
||
|
*/
|
||
|
CVAPI(void) cvParticleResample( CvParticle* p )
|
||
|
{
|
||
|
int i, j, np, k = 0;
|
||
|
CvMat* particle, hdr;
|
||
|
CvMat* new_particles = cvCreateMat( p->num_states, p->num_particles, p->particles->type );
|
||
|
double weight;
|
||
|
int max_loc;
|
||
|
|
||
|
k = 0;
|
||
|
for( i = 0; i < p->num_particles; i++ ) //weights su uz normalizovane (ich suma je 1)
|
||
|
{
|
||
|
particle = cvGetCol( p->particles, &hdr, i ); //ulozi sa x,y,w,h,r o particle
|
||
|
weight = cvmGet( p->weights, 0, i ); //ulozi sa weight particlu
|
||
|
weight = p->logweight ? exp( weight ) : weight; //ak su vahy ulozene vo weights -> weight = e^weight
|
||
|
np = cvRound( weight * p->num_particles ); //particle s vyssim ohodnotenim sa skopiruje do viacerych novych particles
|
||
|
for( j = 0; j < np; j++ )
|
||
|
{
|
||
|
cvSetCol( particle, new_particles, k++ );
|
||
|
if( k == p->num_particles )
|
||
|
goto exit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//pokial sme este neskopirovali vsekty particles, zvysne skopirujeme podla najlepsie ohodnotenej particle
|
||
|
max_loc = cvParticleGetMax( p );
|
||
|
particle = cvGetCol( p->particles, &hdr, max_loc );
|
||
|
while( k < p->num_particles ) //kym sa nenastavia vsetky particles
|
||
|
cvSetCol( particle, new_particles, k++ ); //nastav zostavajucim particles maximalne ohodnotenie?
|
||
|
|
||
|
exit:
|
||
|
cvReleaseMat( &p->particles );
|
||
|
p->particles = new_particles;
|
||
|
}
|
||
|
|
||
|
#endif
|