cvhmm.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,633 行 · 第 1/4 页
SVN-BASE
1,633 行
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"
#include <float.h>
#include "_cvutils.h"
#define LN2PI 1.837877f
#define BIG_FLT 1.e+10f
#define _CV_ERGODIC 1
#define _CV_CAUSAL 2
#define _CV_LAST_STATE 1
#define _CV_BEST_STATE 2
//*F///////////////////////////////////////////////////////////////////////////////////////
// Name: _cvCreateObsInfo
// Purpose: The function allocates memory for CvImgObsInfo structure
// and its inner stuff
// Context:
// Parameters: obs_info - addres of pointer to CvImgObsInfo structure
// num_hor_obs - number of horizontal observation vectors
// num_ver_obs - number of horizontal observation vectors
// obs_size - length of observation vector
//
// Returns: error status
//
// Notes:
//F*/
IPCVAPI_IMPL(CvStatus, icvCreateObsInfo, ( CvImgObsInfo** obs_info,
CvSize num_obs, int obs_size ))
{
int total = num_obs.height * num_obs.width;
CvImgObsInfo* obs = (CvImgObsInfo*)icvAlloc( sizeof( CvImgObsInfo) );
obs->obs_x = num_obs.width;
obs->obs_y = num_obs.height;
obs->obs = (float*)icvAlloc( total * obs_size * sizeof(float) );
obs->state = (int*)icvAlloc( 2 * total * sizeof(int) );
obs->mix = (int*)icvAlloc( total * sizeof(int) );
obs->obs_size = obs_size;
obs_info[0] = obs;
return CV_NO_ERR;
}
IPCVAPI_IMPL(CvStatus, icvReleaseObsInfo, ( CvImgObsInfo** p_obs_info ))
{
CvImgObsInfo* obs_info = p_obs_info[0];
icvFree( &(obs_info->obs) );
icvFree( &(obs_info->mix) );
icvFree( &(obs_info->state) );
icvFree( &(obs_info) );
p_obs_info[0] = NULL;
return CV_NO_ERR;
}
//*F///////////////////////////////////////////////////////////////////////////////////////
// Name: icvCreate2DHMM
// Purpose: The function allocates memory for 2-dimensional embedded HMM model
// and its inner stuff
// Context:
// Parameters: hmm - addres of pointer to CvEHMM structure
// state_number - array of hmm sizes (size of array == state_number[0]+1 )
// num_mix - number of gaussian mixtures in low-level HMM states
// size of array is defined by previous array values
// obs_size - length of observation vectors
//
// Returns: error status
//
// Notes: state_number[0] - number of states in external HMM.
// state_number[i] - number of states in embedded HMM
//
// example for face recognition: state_number = { 5 3 6 6 6 3 },
// length of num_mix array = 3+6+6+6+3 = 24//
//
//F*/
IPCVAPI_IMPL(CvStatus, icvCreate2DHMM, ( CvEHMM** this_hmm,
int* state_number, int* num_mix, int obs_size ))
{
int i;
int real_states = 0;
CvEHMMState* all_states;
CvEHMM* hmm;
int total_mix = 0;
float* pointers;
//compute total number of states of all level in 2d EHMM
for( i = 1; i <= state_number[0]; i++ )
{
real_states += state_number[i];
}
/* allocate memory for all hmms (from all levels) */
hmm = (CvEHMM*)icvAlloc( (state_number[0] + 1) * sizeof(CvEHMM) );
/* set number of superstates */
hmm[0].num_states = state_number[0];
hmm[0].level = 1;
/* allocate memory for all states */
all_states = (CvEHMMState *)icvAlloc( real_states * sizeof( CvEHMMState ) );
/* assign number of mixtures */
for( i = 0; i < real_states; i++ )
{
all_states[i].num_mix = num_mix[i];
}
/* compute size of inner of all real states */
for( i = 0; i < real_states; i++ )
{
total_mix += num_mix[i];
}
/* allocate memory for states stuff */
pointers = (float*)icvAlloc( total_mix * (2/*for mu invvar */ * obs_size +
2/*for weight and log_var_val*/ ) * sizeof( float) );
/* organize memory */
for( i = 0; i < real_states; i++ )
{
all_states[i].mu = pointers; pointers += num_mix[i] * obs_size;
all_states[i].inv_var = pointers; pointers += num_mix[i] * obs_size;
all_states[i].log_var_val = pointers; pointers += num_mix[i];
all_states[i].weight = pointers; pointers += num_mix[i];
}
/* set pointer to embedded hmm array */
hmm->u.ehmm = hmm + 1;
for( i = 0; i < hmm[0].num_states; i++ )
{
hmm[i+1].u.state = all_states;
all_states += state_number[i+1];
hmm[i+1].num_states = state_number[i+1];
}
for( i = 0; i <= state_number[0]; i++ )
{
hmm[i].transP = icvCreateMatrix_32f( hmm[i].num_states, hmm[i].num_states );
hmm[i].obsProb = NULL;
hmm[i].level = i ? 0 : 1;
}
/* if all ok - return pointer */
*this_hmm = hmm;
return CV_NO_ERR;
}
IPCVAPI_IMPL(CvStatus, icvRelease2DHMM, ( CvEHMM** phmm ))
{
CvEHMM* hmm = phmm[0];
int i;
for( i = 0; i < hmm[0].num_states + 1; i++ )
{
icvDeleteMatrix( hmm[i].transP );
}
if (hmm->obsProb != NULL)
{
int* tmp = ((int*)(hmm->obsProb)) - 3;
icvFree( &(tmp) );
}
icvFree( &(hmm->u.ehmm->u.state->mu) );
icvFree( &(hmm->u.ehmm->u.state) );
/* free hmm structures */
icvFree( phmm );
phmm[0] = NULL;
return CV_NO_ERR;
}
/* distance between 2 vectors */
IPCVAPI_IMPL( float, icvSquareDistance, ( CvVect32f v1, CvVect32f v2, int len ) )
{
int i;
double dist0 = 0;
double dist1 = 0;
for( i = 0; i <= len - 4; i += 4 )
{
double t0 = v1[i] - v2[i];
double t1 = v1[i+1] - v2[i+1];
dist0 += t0*t0;
dist1 += t1*t1;
t0 = v1[i+2] - v2[i+2];
t1 = v1[i+3] - v2[i+3];
dist0 += t0*t0;
dist1 += t1*t1;
}
for( ; i < len; i++ )
{
double t0 = v1[i] - v2[i];
dist0 += t0*t0;
}
return (float)(dist0 + dist1);
}
/*can be used in CHMM & DHMM */
IPCVAPI_IMPL(CvStatus, icvUniformImgSegm, ( CvImgObsInfo* obs_info, CvEHMM* hmm ))
{
#if 1
/* implementation is very bad */
int i, j, counter = 0;
CvEHMMState* first_state;
float inv_x = 1.f/obs_info->obs_x;
float inv_y = 1.f/obs_info->obs_y;
/* check arguments */
if ( !obs_info || !hmm ) return CV_NULLPTR_ERR;
first_state = hmm->u.ehmm->u.state;
for (i = 0; i < obs_info->obs_y; i++)
{
//bad line (division )
int superstate = (int)((i * hmm->num_states)*inv_y);/* /obs_info->obs_y; */
int index = hmm->u.ehmm[superstate].u.state - first_state;
for (j = 0; j < obs_info->obs_x; j++, counter++)
{
int state = (int)((j * hmm->u.ehmm[superstate].num_states)* inv_x); /* / obs_info->obs_x; */
obs_info->state[2 * counter] = superstate;
obs_info->state[2 * counter + 1] = state + index;
}
}
#else
//this is not ready yet
int i,j,k,m;
CvEHMMState* first_state = hmm->u.ehmm->u.state;
/* check bad arguments */
if ( hmm->num_states > obs_info->obs_y ) return CV_BADSIZE_ERR;
//compute vertical subdivision
float row_per_state = (float)obs_info->obs_y / hmm->num_states;
float col_per_state[1024]; /* maximum 1024 superstates */
//for every horizontal band compute subdivision
for( i = 0; i < hmm->num_states; i++ )
{
CvEHMM* ehmm = &(hmm->u.ehmm[i]);
col_per_state[i] = (float)obs_info->obs_x / ehmm->num_states;
}
//compute state bounds
int ss_bound[1024];
for( i = 0; i < hmm->num_states - 1; i++ )
{
ss_bound[i] = floor( row_per_state * ( i+1 ) );
}
ss_bound[hmm->num_states - 1] = obs_info->obs_y;
//work inside every superstate
int row = 0;
for( i = 0; i < hmm->num_states; i++ )
{
CvEHMM* ehmm = &(hmm->u.ehmm[i]);
int index = ehmm->u.state - first_state;
//calc distribution in superstate
int es_bound[1024];
for( j = 0; j < ehmm->num_states - 1; j++ )
{
es_bound[j] = floor( col_per_state[i] * ( j+1 ) );
}
es_bound[ehmm->num_states - 1] = obs_info->obs_x;
//assign states to first row of superstate
int col = 0;
for( j = 0; j < ehmm->num_states; j++ )
{
for( k = col; k < es_bound[j]; k++, col++ )
{
obs_info->state[row * obs_info->obs_x + 2 * k] = i;
obs_info->state[row * obs_info->obs_x + 2 * k + 1] = j + index;
}
col = es_bound[j];
}
//copy the same to other rows of superstate
for( m = row; m < ss_bound[i]; m++ )
{
memcpy( &(obs_info->state[m * obs_info->obs_x * 2]),
&(obs_info->state[row * obs_info->obs_x * 2]), obs_info->obs_x * 2 * sizeof(int) );
}
row = ss_bound[i];
}
#endif
return CV_NO_ERR;
}
/*F///////////////////////////////////////////////////////////////////////////////////////
// Name: InitMixSegm
// Purpose: The function implements the mixture segmentation of the states of the
// embedded HMM
// Context: used with the Viterbi training of the embedded HMM
// Function uses K-Means algorithm for clustering
//
// Parameters: obs_info_array - array of pointers to image observations
// num_img - length of above array
// hmm - pointer to HMM structure
//
// Returns: error status
//
// Notes:
//F*/
IPCVAPI_IMPL(CvStatus, icvInitMixSegm, (CvImgObsInfo** obs_info_array, int num_img,
CvEHMM* hmm))
{
int k, i, j;
int* num_samples; /* number of observations in every state */
int* counter; /* array of counters for every state */
int** a_class; /* for every state - characteristic array */
CvVect32f** samples; /* for every state - pointer to observation vectors */
int*** samples_mix; /* for every state - array of pointers to vectors mixtures */
CvTermCriteria criteria = cvTermCriteria( CV_TERMCRIT_EPS|CV_TERMCRIT_ITER,
1000, /* iter */
0.01f ); /* eps */
int total = 0;
CvEHMMState* first_state = hmm->u.ehmm->u.state;
for( i = 0 ; i < hmm->num_states; i++ )
{
total += hmm->u.ehmm[i].num_states;
}
/* for every state integer is allocated - number of vectors in state */
num_samples = (int*)icvAlloc( total * sizeof(int) );
/* integer counter is allocated for every state */
counter = (int*)icvAlloc( total * sizeof(int) );
samples = (CvVect32f**)icvAlloc( total * sizeof(CvVect32f*) );
samples_mix = (int***)icvAlloc( total * sizeof(int**) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?