16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M/////////////////////////////////////////////////////////////////////////////////////// 26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// By downloading, copying, installing or using the software you agree to this license. 66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// If you do not agree to this license, do not download, install, 76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// copy or use the software. 86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Intel License Agreement 116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// For Open Source Computer Vision Library 126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved. 146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners. 156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification, 176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met: 186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's of source code must retain the above copyright notice, 206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer. 216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * Redistribution's in binary form must reproduce the above copyright notice, 236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// this list of conditions and the following disclaimer in the documentation 246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and/or other materials provided with the distribution. 256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// * The name of Intel Corporation may not be used to endorse or promote products 276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// derived from this software without specific prior written permission. 286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and 306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied 316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed. 326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct, 336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages 346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services; 356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused 366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability, 376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of 386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage. 396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/ 416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h" 436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define LN2PI 1.837877f 456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define BIG_FLT 1.e+10f 466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_ERGODIC 1 496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_CAUSAL 2 506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_LAST_STATE 1 526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_BEST_STATE 2 536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//*F/////////////////////////////////////////////////////////////////////////////////////// 566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: _cvCreateObsInfo 576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function allocates memory for CvImgObsInfo structure 586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and its inner stuff 596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: obs_info - addres of pointer to CvImgObsInfo structure 616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// num_hor_obs - number of horizontal observation vectors 626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// num_ver_obs - number of horizontal observation vectors 636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// obs_size - length of observation vector 646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: error status 666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL icvCreateObsInfo( CvImgObsInfo** obs_info, 706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize num_obs, int obs_size ) 716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total = num_obs.height * num_obs.width; 736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* obs = (CvImgObsInfo*)cvAlloc( sizeof( CvImgObsInfo) ); 756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs->obs_x = num_obs.width; 776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs->obs_y = num_obs.height; 786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs->obs = (float*)cvAlloc( total * obs_size * sizeof(float) ); 806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs->state = (int*)cvAlloc( 2 * total * sizeof(int) ); 826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs->mix = (int*)cvAlloc( total * sizeof(int) ); 836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs->obs_size = obs_size; 856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info[0] = obs; 876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL icvReleaseObsInfo( CvImgObsInfo** p_obs_info ) 926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* obs_info = p_obs_info[0]; 946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(obs_info->obs) ); 966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(obs_info->mix) ); 976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(obs_info->state) ); 986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(obs_info) ); 996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn p_obs_info[0] = NULL; 1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//*F/////////////////////////////////////////////////////////////////////////////////////// 1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: icvCreate2DHMM 1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function allocates memory for 2-dimensional embedded HMM model 1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and its inner stuff 1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: hmm - addres of pointer to CvEHMM structure 1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// state_number - array of hmm sizes (size of array == state_number[0]+1 ) 1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// num_mix - number of gaussian mixtures in low-level HMM states 1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// size of array is defined by previous array values 1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// obs_size - length of observation vectors 1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: error status 1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: state_number[0] - number of states in external HMM. 1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// state_number[i] - number of states in embedded HMM 1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// example for face recognition: state_number = { 5 3 6 6 6 3 }, 1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// length of num_mix array = 3+6+6+6+3 = 24// 1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL icvCreate2DHMM( CvEHMM** this_hmm, 1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* state_number, int* num_mix, int obs_size ) 1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int real_states = 0; 1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* all_states; 1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* hmm; 1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total_mix = 0; 1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* pointers; 1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //compute total number of states of all level in 2d EHMM 1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 1; i <= state_number[0]; i++ ) 1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn real_states += state_number[i]; 1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* allocate memory for all hmms (from all levels) */ 1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm = (CvEHMM*)cvAlloc( (state_number[0] + 1) * sizeof(CvEHMM) ); 1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* set number of superstates */ 1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm[0].num_states = state_number[0]; 1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm[0].level = 1; 1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* allocate memory for all states */ 1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn all_states = (CvEHMMState *)cvAlloc( real_states * sizeof( CvEHMMState ) ); 1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* assign number of mixtures */ 1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < real_states; i++ ) 1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn all_states[i].num_mix = num_mix[i]; 1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute size of inner of all real states */ 1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < real_states; i++ ) 1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total_mix += num_mix[i]; 1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* allocate memory for states stuff */ 1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn pointers = (float*)cvAlloc( total_mix * (2/*for mu invvar */ * obs_size + 1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2/*for weight and log_var_val*/ ) * sizeof( float) ); 1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* organize memory */ 1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < real_states; i++ ) 1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn all_states[i].mu = pointers; pointers += num_mix[i] * obs_size; 1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn all_states[i].inv_var = pointers; pointers += num_mix[i] * obs_size; 1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn all_states[i].log_var_val = pointers; pointers += num_mix[i]; 1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn all_states[i].weight = pointers; pointers += num_mix[i]; 1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* set pointer to embedded hmm array */ 1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->u.ehmm = hmm + 1; 1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm[0].num_states; i++ ) 1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm[i+1].u.state = all_states; 1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn all_states += state_number[i+1]; 1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm[i+1].num_states = state_number[i+1]; 1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i <= state_number[0]; i++ ) 1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm[i].transP = icvCreateMatrix_32f( hmm[i].num_states, hmm[i].num_states ); 1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm[i].obsProb = NULL; 1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm[i].level = i ? 0 : 1; 1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* if all ok - return pointer */ 1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn *this_hmm = hmm; 1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL icvRelease2DHMM( CvEHMM** phmm ) 2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* hmm = phmm[0]; 2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm[0].num_states + 1; i++ ) 2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDeleteMatrix( hmm[i].transP ); 2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (hmm->obsProb != NULL) 2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* tmp = ((int*)(hmm->obsProb)) - 3; 2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(tmp) ); 2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(hmm->u.ehmm->u.state->mu) ); 2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(hmm->u.ehmm->u.state) ); 2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* free hmm structures */ 2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( phmm ); 2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn phmm[0] = NULL; 2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* distance between 2 vectors */ 2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic float icvSquareDistance( CvVect32f v1, CvVect32f v2, int len ) 2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double dist0 = 0; 2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double dist1 = 0; 2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i <= len - 4; i += 4 ) 2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t0 = v1[i] - v2[i]; 2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t1 = v1[i+1] - v2[i+1]; 2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist0 += t0*t0; 2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist1 += t1*t1; 2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t0 = v1[i+2] - v2[i+2]; 2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn t1 = v1[i+3] - v2[i+3]; 2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist0 += t0*t0; 2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist1 += t1*t1; 2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( ; i < len; i++ ) 2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t0 = v1[i] - v2[i]; 2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn dist0 += t0*t0; 2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return (float)(dist0 + dist1); 2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*can be used in CHMM & DHMM */ 2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvUniformImgSegm( CvImgObsInfo* obs_info, CvEHMM* hmm ) 2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 1 2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* implementation is very bad */ 2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, counter = 0; 2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* first_state; 2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float inv_x = 1.f/obs_info->obs_x; 2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float inv_y = 1.f/obs_info->obs_y; 2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* check arguments */ 2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( !obs_info || !hmm ) return CV_NULLPTR_ERR; 2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn first_state = hmm->u.ehmm->u.state; 2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < obs_info->obs_y; i++) 2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //bad line (division ) 2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int superstate = (int)((i * hmm->num_states)*inv_y);/* /obs_info->obs_y; */ 2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int index = (int)(hmm->u.ehmm[superstate].u.state - first_state); 2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < obs_info->obs_x; j++, counter++) 2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int state = (int)((j * hmm->u.ehmm[superstate].num_states)* inv_x); /* / obs_info->obs_x; */ 2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->state[2 * counter] = superstate; 2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->state[2 * counter + 1] = state + index; 2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else 2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //this is not ready yet 2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i,j,k,m; 2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* first_state = hmm->u.ehmm->u.state; 2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* check bad arguments */ 2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( hmm->num_states > obs_info->obs_y ) return CV_BADSIZE_ERR; 2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //compute vertical subdivision 2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float row_per_state = (float)obs_info->obs_y / hmm->num_states; 2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float col_per_state[1024]; /* maximum 1024 superstates */ 2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //for every horizontal band compute subdivision 3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++ ) 3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &(hmm->u.ehmm[i]); 3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn col_per_state[i] = (float)obs_info->obs_x / ehmm->num_states; 3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //compute state bounds 3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int ss_bound[1024]; 3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states - 1; i++ ) 3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ss_bound[i] = floor( row_per_state * ( i+1 ) ); 3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ss_bound[hmm->num_states - 1] = obs_info->obs_y; 3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //work inside every superstate 3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int row = 0; 3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++ ) 3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &(hmm->u.ehmm[i]); 3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int index = ehmm->u.state - first_state; 3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //calc distribution in superstate 3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int es_bound[1024]; 3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < ehmm->num_states - 1; j++ ) 3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn es_bound[j] = floor( col_per_state[i] * ( j+1 ) ); 3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn es_bound[ehmm->num_states - 1] = obs_info->obs_x; 3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //assign states to first row of superstate 3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int col = 0; 3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < ehmm->num_states; j++ ) 3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = col; k < es_bound[j]; k++, col++ ) 3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->state[row * obs_info->obs_x + 2 * k] = i; 3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->state[row * obs_info->obs_x + 2 * k + 1] = j + index; 3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn col = es_bound[j]; 3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //copy the same to other rows of superstate 3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( m = row; m < ss_bound[i]; m++ ) 3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memcpy( &(obs_info->state[m * obs_info->obs_x * 2]), 3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn &(obs_info->state[row * obs_info->obs_x * 2]), obs_info->obs_x * 2 * sizeof(int) ); 3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn row = ss_bound[i]; 3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: InitMixSegm 3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function implements the mixture segmentation of the states of the 3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// embedded HMM 3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: used with the Viterbi training of the embedded HMM 3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Function uses K-Means algorithm for clustering 3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: obs_info_array - array of pointers to image observations 3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// num_img - length of above array 3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// hmm - pointer to HMM structure 3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: error status 3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvInitMixSegm( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm ) 3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, i, j; 3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* num_samples; /* number of observations in every state */ 3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* counter; /* array of counters for every state */ 3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int** a_class; /* for every state - characteristic array */ 3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f** samples; /* for every state - pointer to observation vectors */ 3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int*** samples_mix; /* for every state - array of pointers to vectors mixtures */ 3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvTermCriteria criteria = cvTermCriteria( CV_TERMCRIT_EPS|CV_TERMCRIT_ITER, 3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1000, /* iter */ 3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 0.01f ); /* eps */ 3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total = 0; 3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* first_state = hmm->u.ehmm->u.state; 3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0 ; i < hmm->num_states; i++ ) 3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total += hmm->u.ehmm[i].num_states; 3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* for every state integer is allocated - number of vectors in state */ 4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn num_samples = (int*)cvAlloc( total * sizeof(int) ); 4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* integer counter is allocated for every state */ 4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn counter = (int*)cvAlloc( total * sizeof(int) ); 4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples = (CvVect32f**)cvAlloc( total * sizeof(CvVect32f*) ); 4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples_mix = (int***)cvAlloc( total * sizeof(int**) ); 4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* clear */ 4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( num_samples, 0 , total*sizeof(int) ); 4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( counter, 0 , total*sizeof(int) ); 4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* for every state the number of vectors which belong to it is computed (smth. like histogram) */ 4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (k = 0; k < num_img; k++) 4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* obs = obs_info_array[k]; 4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int count = 0; 4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < obs->obs_y; i++) 4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < obs->obs_x; j++, count++) 4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int state = obs->state[ 2 * count + 1]; 4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn num_samples[state] += 1; 4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* for every state int* is allocated */ 4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a_class = (int**)cvAlloc( total*sizeof(int*) ); 4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < total; i++) 4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a_class[i] = (int*)cvAlloc( num_samples[i] * sizeof(int) ); 4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples[i] = (CvVect32f*)cvAlloc( num_samples[i] * sizeof(CvVect32f) ); 4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples_mix[i] = (int**)cvAlloc( num_samples[i] * sizeof(int*) ); 4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* for every state vectors which belong to state are gathered */ 4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (k = 0; k < num_img; k++) 4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* obs = obs_info_array[k]; 4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int num_obs = ( obs->obs_x ) * ( obs->obs_y ); 4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* vector = obs->obs; 4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < num_obs; i++, vector+=obs->obs_size ) 4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int state = obs->state[2*i+1]; 4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples[state][counter[state]] = vector; 4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples_mix[state][counter[state]] = &(obs->mix[i]); 4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn counter[state]++; 4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* clear counters */ 4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( counter, 0, total*sizeof(int) ); 4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* do the actual clustering using the K Means algorithm */ 4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < total; i++) 4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( first_state[i].num_mix == 1) 4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (k = 0; k < num_samples[i]; k++) 4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* all vectors belong to one mixture */ 4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a_class[i][k] = 0; 4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( num_samples[i] ) 4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* clusterize vectors */ 4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvKMeans( first_state[i].num_mix, samples[i], num_samples[i], 4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info_array[0]->obs_size, criteria, a_class[i] ); 4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* for every vector number of mixture is assigned */ 4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < total; i++ ) 4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < num_samples[i]; j++) 4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn samples_mix[i][j][0] = a_class[i][j]; 4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < total; i++) 4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(a_class[i]) ); 4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(samples[i]) ); 4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &(samples_mix[i]) ); 4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &a_class ); 4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &samples ); 4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &samples_mix ); 4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &counter ); 4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &num_samples ); 5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: ComputeUniModeGauss 5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function computes the Gaussian pdf for a sample vector 5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: obsVeq - pointer to the sample vector 5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// mu - pointer to the mean vector of the Gaussian pdf 5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// var - pointer to the variance vector of the Gaussian pdf 5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// VecSize - the size of sample vector 5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: the pdf of the sample vector given the specified Gaussian 5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*static float icvComputeUniModeGauss(CvVect32f vect, CvVect32f mu, 5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f inv_var, float log_var_val, int vect_size) 5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int n; 5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double tmp; 5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double prob; 5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prob = -log_var_val; 5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (n = 0; n < vect_size; n++) 5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp = (vect[n] - mu[n]) * inv_var[n]; 5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prob = prob - tmp * tmp; 5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //prob *= 0.5f; 5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return (float)prob; 5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}*/ 5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: ComputeGaussMixture 5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function computes the mixture Gaussian pdf of a sample vector. 5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: obsVeq - pointer to the sample vector 5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// mu - two-dimensional pointer to the mean vector of the Gaussian pdf; 5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the first dimension is indexed over the number of mixtures and 5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the second dimension is indexed along the size of the mean vector 5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// var - two-dimensional pointer to the variance vector of the Gaussian pdf; 5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the first dimension is indexed over the number of mixtures and 5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the second dimension is indexed along the size of the variance vector 5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// VecSize - the size of sample vector 5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// weight - pointer to the wights of the Gaussian mixture 5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// NumMix - the number of Gaussian mixtures 5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: the pdf of the sample vector given the specified Gaussian mixture. 5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Calculate probability of observation at state in logarithmic scale*/ 5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*static float 5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvComputeGaussMixture( CvVect32f vect, float* mu, 5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* inv_var, float* log_var_val, 5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vect_size, float* weight, int num_mix ) 5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double prob, l_prob; 5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prob = 0.0f; 5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (num_mix == 1) 5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return icvComputeUniModeGauss( vect, mu, inv_var, log_var_val[0], vect_size); 5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int m; 5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (m = 0; m < num_mix; m++) 5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( weight[m] > 0.0) 5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn l_prob = icvComputeUniModeGauss(vect, mu + m*vect_size, 5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inv_var + m * vect_size, 5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn log_var_val[m], 5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn vect_size); 5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prob = prob + weight[m]*exp((double)l_prob); 5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prob = log(prob); 5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return (float)prob; 5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}*/ 5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: EstimateObsProb 5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function computes the probability of every observation in every state 5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: obs_info - observations 5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// hmm - hmm 5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: error status 5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL icvEstimateObsProb( CvImgObsInfo* obs_info, CvEHMM* hmm ) 6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j; 6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total_states = 0; 6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* check if matrix exist and check current size 6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if not sufficient - realloc */ 6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int status = 0; /* 1 - not allocated, 2 - allocated but small size, 6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 3 - size is enough, but distribution is bad, 0 - all ok */ 6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < hmm->num_states; j++ ) 6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total_states += hmm->u.ehmm[j].num_states; 6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( hmm->obsProb == NULL ) 6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* allocare memory */ 6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int need_size = ( obs_info->obs_x * obs_info->obs_y * total_states * sizeof(float) + 6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->obs_y * hmm->num_states * sizeof( CvMatr32f) ); 6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* buffer = (int*)cvAlloc( need_size + 3 * sizeof(int) ); 6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[0] = need_size; 6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[1] = obs_info->obs_y; 6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[2] = obs_info->obs_x; 6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->obsProb = (float**) (buffer + 3); 6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn status = 3; 6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* check current size */ 6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* total= (int*)(((int*)(hmm->obsProb)) - 3); 6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int need_size = ( obs_info->obs_x * obs_info->obs_y * total_states * sizeof(float) + 6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->obs_y * hmm->num_states * sizeof( CvMatr32f/*(float*)*/ ) ); 6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( sizeof(float*) == sizeof(int) ); 6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( need_size > (*total) ) 6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* buffer = ((int*)(hmm->obsProb)) - 3; 6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &buffer); 6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer = (int*)cvAlloc( need_size + 3 * sizeof(int)); 6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[0] = need_size; 6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[1] = obs_info->obs_y; 6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn buffer[2] = obs_info->obs_x; 6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->obsProb = (float**)(buffer + 3); 6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn status = 3; 6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (!status) 6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* obsx = ((int*)(hmm->obsProb)) - 1; 6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* obsy = ((int*)(hmm->obsProb)) - 2; 6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( (*obsx > 0) && (*obsy > 0) ); 6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* is good distribution? */ 6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( (obs_info->obs_x > (*obsx) ) || (obs_info->obs_y > (*obsy) ) ) 6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn status = 3; 6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* if bad status - do reallocation actions */ 6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( (status == 0) || (status == 3) ); 6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( status ) 6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float** tmp = hmm->obsProb; 6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* tmpf; 6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* distribute pointers of ehmm->obsProb */ 6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++ ) 6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->u.ehmm[i].obsProb = tmp; 6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmp += obs_info->obs_y; 6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmpf = (float*)tmp; 6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* distribute pointers of ehmm->obsProb[j] */ 6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++ ) 6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &( hmm->u.ehmm[i] ); 6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < obs_info->obs_y; j++ ) 6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ehmm->obsProb[j] = tmpf; 6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn tmpf += ehmm->num_states * obs_info->obs_x; 6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn }/* end of pointer distribution */ 6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 1 6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define MAX_BUF_SIZE 1200 6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float local_log_mix_prob[MAX_BUF_SIZE]; 6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double local_mix_prob[MAX_BUF_SIZE]; 6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vect_size = obs_info->obs_size; 7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvStatus res = CV_NO_ERR; 7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* log_mix_prob = local_log_mix_prob; 7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double* mix_prob = local_mix_prob; 7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int max_size = 0; 7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int obs_x = obs_info->obs_x; 7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* calculate temporary buffer size */ 7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++ ) 7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &(hmm->u.ehmm[i]); 7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* state = ehmm->u.state; 7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int max_mix = 0; 7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < ehmm->num_states; j++ ) 7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = state[j].num_mix; 7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( max_mix < t ) max_mix = t; 7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn max_mix *= ehmm->num_states; 7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( max_size < max_mix ) max_size = max_mix; 7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn max_size *= obs_x * vect_size; 7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* allocate buffer */ 7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( max_size > MAX_BUF_SIZE ) 7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn log_mix_prob = (float*)cvAlloc( max_size*(sizeof(float) + sizeof(double))); 7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( !log_mix_prob ) return CV_OUTOFMEM_ERR; 7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mix_prob = (double*)(log_mix_prob + max_size); 7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( log_mix_prob, 0, max_size*sizeof(float)); 7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*****************computing probabilities***********************/ 7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* loop through external states */ 7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++ ) 7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &(hmm->u.ehmm[i]); 7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* state = ehmm->u.state; 7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int max_mix = 0; 7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int n_states = ehmm->num_states; 7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* determine maximal number of mixtures (again) */ 7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < ehmm->num_states; j++ ) 7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t = state[j].num_mix; 7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( max_mix < t ) max_mix = t; 7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* loop through rows of the observation matrix */ 7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < obs_info->obs_y; j++ ) 7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int m, n; 7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* obs = obs_info->obs + j * obs_x * vect_size; 7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* log_mp = max_mix > 1 ? log_mix_prob : ehmm->obsProb[j]; 7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double* mp = mix_prob; 7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* several passes are done below */ 7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 1. calculate logarithms of probabilities for each mixture */ 7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* loop through mixtures */ 7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( m = 0; m < max_mix; m++ ) 7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* set pointer to first observation in the line */ 7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* vect = obs; 7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* cycles through obseravtions in the line */ 7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( n = 0; n < obs_x; n++, vect += vect_size, log_mp += n_states ) 7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, l; 7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( l = 0; l < n_states; l++ ) 7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( state[l].num_mix > m ) 7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* mu = state[l].mu + m*vect_size; 7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* inv_var = state[l].inv_var + m*vect_size; 7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double prob = -state[l].log_var_val[m]; 7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < vect_size; k++ ) 7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn double t = (vect[k] - mu[k])*inv_var[k]; 7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn prob -= t*t; 7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn log_mp[l] = MAX( (float)prob, -500 ); 7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* skip the rest if there is a single mixture */ 7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( max_mix == 1 ) continue; 7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 2. calculate exponent of log_mix_prob 7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (i.e. probability for each mixture) */ 8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvbFastExp( log_mix_prob, mix_prob, max_mix * obs_x * n_states ); 8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 3. sum all mixtures with weights */ 8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 3a. first mixture - simply scale by weight */ 8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( n = 0; n < obs_x; n++, mp += n_states ) 8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int l; 8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( l = 0; l < n_states; l++ ) 8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mp[l] *= state[l].weight[0]; 8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 3b. add other mixtures */ 8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( m = 1; m < max_mix; m++ ) 8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int ofs = -m*obs_x*n_states; 8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( n = 0; n < obs_x; n++, mp += n_states ) 8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int l; 8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( l = 0; l < n_states; l++ ) 8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( m < state[l].num_mix ) 8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mp[l + ofs] += mp[l] * state[l].weight[m]; 8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 4. Put logarithms of summary probabilities to the destination matrix */ 8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvbFastLog( mix_prob, ehmm->obsProb[j], obs_x * n_states ); 8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( log_mix_prob != local_log_mix_prob ) cvFree( &log_mix_prob ); 8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return res; 8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef MAX_BUF_SIZE 8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else 8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++ ) 8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &(hmm->u.ehmm[i]); 8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* state = ehmm->u.state; 8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < obs_info->obs_y; j++ ) 8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k,m; 8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int obs_index = j * obs_info->obs_x; 8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* B = ehmm->obsProb[j]; 8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* cycles through obs and states */ 8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < obs_info->obs_x; k++ ) 8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f vect = (obs_info->obs) + (obs_index + k) * vect_size; 8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* matr_line = B + k * ehmm->num_states; 8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( m = 0; m < ehmm->num_states; m++ ) 8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn matr_line[m] = icvComputeGaussMixture( vect, state[m].mu, state[m].inv_var, 8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[m].log_var_val, vect_size, state[m].weight, 8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[m].num_mix ); 8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif 8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: EstimateTransProb 8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function calculates the state and super state transition probabilities 8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// of the model given the images, 8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the state segmentation and the input parameters 8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: obs_info_array - array of pointers to image observations 8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// num_img - length of above array 8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// hmm - pointer to HMM structure 8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: void 8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvEstimateTransProb( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm ) 8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, k; 8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* first_state = hmm->u.ehmm->u.state; 8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* as a counter we will use transP matrix */ 8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* initialization */ 8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* clear transP */ 8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvSetZero_32f( hmm->transP, hmm->num_states, hmm->num_states ); 8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < hmm->num_states; i++ ) 8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvSetZero_32f( hmm->u.ehmm[i].transP , hmm->u.ehmm[i].num_states, hmm->u.ehmm[i].num_states ); 9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute the counters */ 9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < num_img; i++) 9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int counter = 0; 9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* info = obs_info_array[i]; 9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < info->obs_y; j++) 9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (k = 0; k < info->obs_x; k++, counter++) 9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute how many transitions from state to state 9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn occured both in horizontal and vertical direction */ 9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int superstate, state; 9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int nextsuperstate, nextstate; 9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int begin_ind; 9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn superstate = info->state[2 * counter]; 9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn begin_ind = (int)(hmm->u.ehmm[superstate].u.state - first_state); 9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state = info->state[ 2 * counter + 1] - begin_ind; 9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (j < info->obs_y - 1) 9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int transP_size = hmm->num_states; 9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nextsuperstate = info->state[ 2*(counter + info->obs_x) ]; 9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->transP[superstate * transP_size + nextsuperstate] += 1; 9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (k < info->obs_x - 1) 9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int transP_size = hmm->u.ehmm[superstate].num_states; 9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn nextstate = info->state[2*(counter+1) + 1] - begin_ind; 9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->u.ehmm[superstate].transP[ state * transP_size + nextstate] += 1; 9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* estimate superstate matrix */ 9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < hmm->num_states; i++) 9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float total = 0; 9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float inv_total; 9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < hmm->num_states; j++) 9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total += hmm->transP[i * hmm->num_states + j]; 9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //assert( total ); 9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inv_total = total ? 1.f/total : 0; 9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < hmm->num_states; j++) 9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->transP[i * hmm->num_states + j] = 9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->transP[i * hmm->num_states + j] ? 9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (float)log( hmm->transP[i * hmm->num_states + j] * inv_total ) : -BIG_FLT; 9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* estimate other matrices */ 9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < hmm->num_states; k++ ) 9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &(hmm->u.ehmm[k]); 9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < ehmm->num_states; i++) 9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float total = 0; 9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float inv_total; 9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < ehmm->num_states; j++) 9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total += ehmm->transP[i*ehmm->num_states + j]; 9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //assert( total ); 9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn inv_total = total ? 1.f/total : 0; 9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( j = 0; j < ehmm->num_states; j++) 9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ehmm->transP[i * ehmm->num_states + j] = 9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (ehmm->transP[i * ehmm->num_states + j]) ? 9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (float)log( ehmm->transP[i * ehmm->num_states + j] * inv_total) : -BIG_FLT ; 9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: MixSegmL2 9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function implements the mixture segmentation of the states of the 9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// embedded HMM 9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: used with the Viterbi training of the embedded HMM 9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: 9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// obs_info_array 9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// num_img 10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// hmm 10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: void 10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvMixSegmL2( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm ) 10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, i, j, m; 10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* state = hmm->u.ehmm[0].u.state; 10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (k = 0; k < num_img; k++) 10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int counter = 0; 10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* info = obs_info_array[k]; 10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < info->obs_y; i++) 10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < info->obs_x; j++, counter++) 10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int e_state = info->state[2 * counter + 1]; 10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float min_dist; 10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn min_dist = icvSquareDistance((info->obs) + (counter * info->obs_size), 10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[e_state].mu, info->obs_size); 10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info->mix[counter] = 0; 10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (m = 1; m < state[e_state].num_mix; m++) 10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float dist=icvSquareDistance( (info->obs) + (counter * info->obs_size), 10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[e_state].mu + m * info->obs_size, 10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info->obs_size); 10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (dist < min_dist) 10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn min_dist = dist; 10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* assign mixture with smallest distance */ 10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info->mix[counter] = m; 10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvMixSegmProb(CvImgObsInfo* obs_info, int num_img, CvEHMM* hmm ) 10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, i, j, m; 10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* state = hmm->ehmm[0].state_info; 10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (k = 0; k < num_img; k++) 10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int counter = 0; 10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* info = obs_info + k; 10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < info->obs_y; i++) 10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < info->obs_x; j++, counter++) 10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int e_state = info->in_state[counter]; 10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float max_prob; 10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn max_prob = icvComputeUniModeGauss( info->obs[counter], state[e_state].mu[0], 10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[e_state].inv_var[0], 10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[e_state].log_var[0], 10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info->obs_size ); 10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info->mix[counter] = 0; 10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (m = 1; m < state[e_state].num_mix; m++) 10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float prob=icvComputeUniModeGauss(info->obs[counter], state[e_state].mu[m], 10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[e_state].inv_var[m], 10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state[e_state].log_var[m], 10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info->obs_size); 10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (prob > max_prob) 10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn max_prob = prob; 10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // assign mixture with greatest probability. 10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn info->mix[counter] = m; 10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/ 10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvViterbiSegmentation( int num_states, int /*num_obs*/, CvMatr32f transP, 10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMatr32f B, int start_obs, int prob_type, 10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int** q, int min_num_obs, int max_num_obs, 10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* prob ) 10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // memory allocation 11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, last_obs; 11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int m_HMMType = _CV_ERGODIC; /* _CV_CAUSAL or _CV_ERGODIC */ 11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int m_ProbType = prob_type; /* _CV_LAST_STATE or _CV_BEST_STATE */ 11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int m_minNumObs = min_num_obs; /*??*/ 11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int m_maxNumObs = max_num_obs; /*??*/ 11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int m_numStates = num_states; 11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* m_pi = (float*)cvAlloc( num_states* sizeof(float) ); 11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMatr32f m_a = transP; 11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // offset brobability matrix to starting observation 11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMatr32f m_b = B + start_obs * num_states; 11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //so m_xl will not be used more 11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //m_xl = start_obs; 11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* if (muDur != NULL){ 11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_d = new int[m_numStates]; 11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_l = new double[m_numStates]; 11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < m_numStates; i++){ 11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_l[i] = muDur[i]; 11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else{ 11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_d = NULL; 11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_l = NULL; 11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMatr32f m_Gamma = icvCreateMatrix_32f( num_states, m_maxNumObs ); 11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* m_csi = (int*)cvAlloc( num_states * m_maxNumObs * sizeof(int) ); 11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //stores maximal result for every ending observation */ 11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f m_MaxGamma = prob; 11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// assert( m_xl + max_num_obs <= num_obs ); 11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*??m_q = new int*[m_maxNumObs - m_minNumObs]; 11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ??for (i = 0; i < m_maxNumObs - m_minNumObs; i++) 11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ?? m_q[i] = new int[m_minNumObs + i + 1]; 11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn */ 11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /******************************************************************/ 11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Viterbi initialization */ 11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* set initial state probabilities, in logarithmic scale */ 11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < m_numStates; i++) 11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_pi[i] = -BIG_FLT; 11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_pi[0] = 0.0f; 11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < num_states; i++) 11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[0 * num_states + i] = m_pi[i] + m_b[0 * num_states + i]; 11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_csi[0 * num_states + i] = 0; 11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /******************************************************************/ 11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Viterbi recursion */ 11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( m_HMMType == _CV_CAUSAL ) //causal model 11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t,j; 11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (t = 1 ; t < m_maxNumObs; t++) 11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // evaluate self-to-self transition for state 0 11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[t * num_states + 0] = m_Gamma[(t-1) * num_states + 0] + m_a[0]; 11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_csi[t * num_states + 0] = 0; 11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 1; j < num_states; j++) 11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float self = m_Gamma[ (t-1) * num_states + j] + m_a[ j * num_states + j]; 11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float prev = m_Gamma[ (t-1) * num_states +(j-1)] + m_a[ (j-1) * num_states + j]; 11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( prev > self ) 11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_csi[t * num_states + j] = j-1; 11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[t * num_states + j] = prev; 11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_csi[t * num_states + j] = j; 11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[t * num_states + j] = self; 11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[t * num_states + j] = m_Gamma[t * num_states + j] + m_b[t * num_states + j]; 11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if ( m_HMMType == _CV_ERGODIC ) //ergodic model 11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t; 11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (t = 1 ; t < m_maxNumObs; t++) 11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < num_states; j++) 12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i; 12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[ t*num_states + j] = m_Gamma[(t-1) * num_states + 0] + m_a[0*num_states+j]; 12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_csi[t *num_states + j] = 0; 12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 1; i < num_states; i++) 12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float currGamma = m_Gamma[(t-1) *num_states + i] + m_a[i *num_states + j]; 12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (currGamma > m_Gamma[t *num_states + j]) 12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[t * num_states + j] = currGamma; 12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_csi[t * num_states + j] = i; 12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_Gamma[t *num_states + j] = m_Gamma[t *num_states + j] + m_b[t * num_states + j]; 12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( last_obs = m_minNumObs-1, i = 0; last_obs < m_maxNumObs; last_obs++, i++ ) 12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int t; 12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /******************************************************************/ 12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Viterbi termination */ 12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( m_ProbType == _CV_LAST_STATE ) 12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_MaxGamma[i] = m_Gamma[last_obs * num_states + num_states - 1]; 12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn q[i][last_obs] = num_states - 1; 12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else if( m_ProbType == _CV_BEST_STATE ) 12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k; 12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn q[i][last_obs] = 0; 12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_MaxGamma[i] = m_Gamma[last_obs * num_states + 0]; 12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(k = 1; k < num_states; k++) 12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( m_Gamma[last_obs * num_states + k] > m_MaxGamma[i] ) 12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn m_MaxGamma[i] = m_Gamma[last_obs * num_states + k]; 12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn q[i][last_obs] = k; 12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /******************************************************************/ 12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* Viterbi backtracking */ 12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (t = last_obs-1; t >= 0; t--) 12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn q[i][t] = m_csi[(t+1) * num_states + q[i][t+1] ]; 12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* memory free */ 12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &m_pi ); 12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &m_csi ); 12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDeleteMatrix( m_Gamma ); 12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F/////////////////////////////////////////////////////////////////////////////////////// 12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Name: icvEViterbi 12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Purpose: The function calculates the embedded Viterbi algorithm 12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// for 1 image 12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Context: 12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Parameters: 12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// obs_info - observations 12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// hmm - HMM 12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Returns: the Embedded Viterbi probability (float) 12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and do state segmentation of observations 12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// 12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Notes: 12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/ 12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic float CV_STDCALL icvEViterbi( CvImgObsInfo* obs_info, CvEHMM* hmm ) 12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j, counter; 12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float log_likelihood; 12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float inv_obs_x = 1.f / obs_info->obs_x; 12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* first_state = hmm->u.ehmm->u.state; 12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* memory allocation for superB */ 12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvMatr32f superB = icvCreateMatrix_32f(hmm->num_states, obs_info->obs_y ); 12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* memory allocation for q */ 12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int*** q = (int***)cvAlloc( hmm->num_states * sizeof(int**) ); 12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int* super_q = (int*)cvAlloc( obs_info->obs_y * sizeof(int) ); 12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < hmm->num_states; i++) 12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn q[i] = (int**)cvAlloc( obs_info->obs_y * sizeof(int*) ); 12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < obs_info->obs_y ; j++) 12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn q[i][j] = (int*)cvAlloc( obs_info->obs_x * sizeof(int) ); 13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* start Viterbi segmentation */ 13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < hmm->num_states; i++) 13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* ehmm = &(hmm->u.ehmm[i]); 13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < obs_info->obs_y; j++) 13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float max_gamma; 13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* 1D HMM Viterbi segmentation */ 13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvViterbiSegmentation( ehmm->num_states, obs_info->obs_x, 13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ehmm->transP, ehmm->obsProb[j], 0, 13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _CV_LAST_STATE, &q[i][j], obs_info->obs_x, 13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->obs_x, &max_gamma); 13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn superB[j * hmm->num_states + i] = max_gamma * inv_obs_x; 13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* perform global Viterbi segmentation (i.e. process higher-level HMM) */ 13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvViterbiSegmentation( hmm->num_states, obs_info->obs_y, 13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn hmm->transP, superB, 0, 13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn _CV_LAST_STATE, &super_q, obs_info->obs_y, 13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->obs_y, &log_likelihood ); 13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn log_likelihood /= obs_info->obs_y ; 13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn counter = 0; 13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* assign new state to observation vectors */ 13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < obs_info->obs_y; i++) 13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < obs_info->obs_x; j++, counter++) 13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int superstate = super_q[i]; 13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int state = (int)(hmm->u.ehmm[superstate].u.state - first_state); 13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->state[2 * counter] = superstate; 13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn obs_info->state[2 * counter + 1] = state + q[superstate][i][j]; 13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* memory deallocation for superB */ 13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDeleteMatrix( superB ); 13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*memory deallocation for q */ 13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < hmm->num_states; i++) 13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < obs_info->obs_y ; j++) 13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &q[i][j] ); 13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &q[i] ); 13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &q ); 13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &super_q ); 13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return log_likelihood; 13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL 13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvEstimateHMMStateParams( CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm ) 13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute gamma, weights, means, vars */ 13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k, i, j, m; 13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total = 0; 13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int vect_len = obs_info_array[0]->obs_size; 13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float start_log_var_val = LN2PI * vect_len; 13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f tmp_vect = icvCreateVector_32f( vect_len ); 13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* first_state = hmm->u.ehmm[0].u.state; 13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn assert( sizeof(float) == sizeof(int) ); 13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for(i = 0; i < hmm->num_states; i++ ) 13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn total+= hmm->u.ehmm[i].num_states; 13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /***************Gamma***********************/ 13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* initialize gamma */ 13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( i = 0; i < total; i++ ) 13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (m = 0; m < first_state[i].num_mix; m++) 13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((int*)(first_state[i].weight))[m] = 0; 13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* maybe gamma must be computed in mixsegm process ?? */ 13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute gamma */ 13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (k = 0; k < num_img; k++) 14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* info = obs_info_array[k]; 14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int num_obs = info->obs_y * info->obs_x; 14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < num_obs; i++) 14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int state, mixture; 14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state = info->state[2*i + 1]; 14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mixture = info->mix[i]; 14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* computes gamma - number of observations corresponding 14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn to every mixture of every state */ 14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn ((int*)(first_state[state].weight))[mixture] += 1; 14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /***************Mean and Var***********************/ 14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute means and variances of every item */ 14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* initially variance placed to inv_var */ 14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* zero mean and variance */ 14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < total; i++) 14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( (void*)first_state[i].mu, 0, first_state[i].num_mix * vect_len * 14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(float) ); 14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn memset( (void*)first_state[i].inv_var, 0, first_state[i].num_mix * vect_len * 14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn sizeof(float) ); 14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute sums */ 14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < num_img; i++) 14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo* info = obs_info_array[i]; 14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int total_obs = info->obs_x * info->obs_y; 14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* vector = info->obs; 14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < total_obs; j++, vector+=vect_len ) 14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int state = info->state[2 * j + 1]; 14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int mixture = info->mix[j]; 14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f mean = first_state[state].mu + mixture * vect_len; 14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f mean2 = first_state[state].inv_var + mixture * vect_len; 14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvAddVector_32f( mean, vector, mean, vect_len ); 14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < vect_len; k++ ) 14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn mean2[k] += vector[k]*vector[k]; 14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /*compute the means and variances */ 14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* assume gamma already computed */ 14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < total; i++) 14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMMState* state = &(first_state[i]); 14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (m = 0; m < state->num_mix; m++) 14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int k; 14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f mu = state->mu + m * vect_len; 14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvVect32f invar = state->inv_var + m * vect_len; 14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( ((int*)state->weight)[m] > 1) 14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float inv_gamma = 1.f/((int*)(state->weight))[m]; 14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvScaleVector_32f( mu, mu, vect_len, inv_gamma); 14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvScaleVector_32f( invar, invar, vect_len, inv_gamma); 14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvMulVectors_32f(mu, mu, tmp_vect, vect_len); 14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvSubVector_32f( invar, tmp_vect, invar, vect_len); 14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* low bound of variance - 100 (Ara's experimental result) */ 14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < vect_len; k++ ) 14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn invar[k] = (invar[k] > 100.f) ? invar[k] : 100.f; 14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute log_var */ 14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state->log_var_val[m] = start_log_var_val; 14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for( k = 0; k < vect_len; k++ ) 14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state->log_var_val[m] += (float)log( invar[k] ); 14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* SMOLI 27.10.2000 */ 14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn state->log_var_val[m] *= 0.5; 14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* compute inv_var = 1/sqrt(2*variance) */ 14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvScaleVector_32f(invar, invar, vect_len, 2.f ); 14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvbInvSqrt( invar, invar, vect_len ); 14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /***************Weights***********************/ 14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn /* normilize gammas - i.e. compute mixture weights */ 14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //compute weights 14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < total; i++) 14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int gamma_total = 0; 15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float norm; 15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (m = 0; m < first_state[i].num_mix; m++) 15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn gamma_total += ((int*)(first_state[i].weight))[m]; 15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn norm = gamma_total ? (1.f/(float)gamma_total) : 0.f; 15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (m = 0; m < first_state[i].num_mix; m++) 15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn first_state[i].weight[m] = ((int*)(first_state[i].weight))[m] * norm; 15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn icvDeleteVector( tmp_vect); 15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* 15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvLightingCorrection8uC1R( uchar* img, CvSize roi, int src_step ) 15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int i, j; 15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int width = roi.width; 15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int height = roi.height; 15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float x1, x2, y1, y2; 15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int f[3] = {0, 0, 0}; 15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float a[3] = {0, 0, 0}; 15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float h1; 15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float h2; 15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float c1,c2; 15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float min = FLT_MAX; 15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float max = -FLT_MAX; 15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float correction; 15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float* float_img = icvAlloc( width * height * sizeof(float) ); 15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x1 = width * (width + 1) / 2.0f; // Sum (1, ... , width) 15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn x2 = width * (width + 1 ) * (2 * width + 1) / 6.0f; // Sum (1^2, ... , width^2) 15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y1 = height * (height + 1)/2.0f; // Sum (1, ... , width) 15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn y2 = height * (height + 1 ) * (2 * height + 1) / 6.0f; // Sum (1^2, ... , width^2) 15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn // extract grayvalues 15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < height; i++) 15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < width; j++) 15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn f[2] = f[2] + j * img[i*src_step + j]; 15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn f[1] = f[1] + i * img[i*src_step + j]; 15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn f[0] = f[0] + img[i*src_step + j]; 15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn h1 = (float)f[0] * (float)x1 / (float)width; 15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn h2 = (float)f[0] * (float)y1 / (float)height; 15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a[2] = ((float)f[2] - h1) / (float)(x2*height - x1*x1*height/(float)width); 15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a[1] = ((float)f[1] - h2) / (float)(y2*width - y1*y1*width/(float)height); 15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn a[0] = (float)f[0]/(float)(width*height) - (float)y1*a[1]/(float)height - 15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn (float)x1*a[2]/(float)width; 15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < height; i++) 15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < width; j++) 15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn correction = a[0] + a[1]*(float)i + a[2]*(float)j; 15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float_img[i*width + j] = img[i*src_step + j] - correction; 15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (float_img[i*width + j] < min) min = float_img[i*width+j]; 15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (float_img[i*width + j] > max) max = float_img[i*width+j]; 15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn //rescaling to the range 0:255 15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn c2 = 0; 15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (max == min) 15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn c2 = 255.0f; 15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn else 15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn c2 = 255.0f/(float)(max - min); 15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn c1 = (-(float)min)*c2; 15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (i = 0; i < height; i++) 15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn for (j = 0; j < width; j++) 15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn { 15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn int value = (int)floor(c2*float_img[i*width + j] + c1); 15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (value < 0) value = 0; 15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if (value > 255) value = 255; 15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn img[i*src_step + j] = (uchar)value; 15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn } 16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn cvFree( &float_img ); 16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_NO_ERR; 16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvLightingCorrection( icvImage* img ) 16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvSize roi; 16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if ( img->type != IPL_DEPTH_8U || img->channels != 1 ) 16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return CV_BADFACTOR_ERR; 16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn roi = _cvSize( img->roi.width, img->roi.height ); 16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return _cvLightingCorrection8uC1R( img->data + img->roi.y * img->step + img->roi.x, 16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn roi, img->step ); 16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/ 16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvEHMM* 16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreate2DHMM( int *state_number, int *num_mix, int obs_size ) 16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvEHMM* hmm = 0; 16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCreate2DHMM" ); 16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvCreate2DHMM( &hmm, state_number, num_mix, obs_size )); 16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return hmm; 16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvRelease2DHMM( CvEHMM ** hmm ) 16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvRelease2DHMM" ); 16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvRelease2DHMM( hmm )); 16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL CvImgObsInfo* 16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCreateObsInfo( CvSize num_obs, int obs_size ) 16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CvImgObsInfo *obs_info = 0; 16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvCreateObsInfo" ); 16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvCreateObsInfo( &obs_info, num_obs, obs_size )); 16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return obs_info; 16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvReleaseObsInfo( CvImgObsInfo ** obs_info ) 16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvReleaseObsInfo" ); 16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvReleaseObsInfo( obs_info )); 16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvUniformImgSegm( CvImgObsInfo * obs_info, CvEHMM * hmm ) 16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvUniformImgSegm" ); 16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvUniformImgSegm( obs_info, hmm )); 16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __CLEANUP__; 16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvInitMixSegm( CvImgObsInfo ** obs_info_array, int num_img, CvEHMM * hmm ) 16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvInitMixSegm" ); 16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvInitMixSegm( obs_info_array, num_img, hmm )); 16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEstimateHMMStateParams( CvImgObsInfo ** obs_info_array, int num_img, CvEHMM * hmm ) 17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvEstimateHMMStateParams" ); 17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvEstimateHMMStateParams( obs_info_array, num_img, hmm )); 17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEstimateTransProb( CvImgObsInfo ** obs_info_array, int num_img, CvEHMM * hmm ) 17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvEstimateTransProb" ); 17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvEstimateTransProb( obs_info_array, num_img, hmm )); 17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEstimateObsProb( CvImgObsInfo * obs_info, CvEHMM * hmm ) 17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvEstimateObsProb" ); 17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvEstimateObsProb( obs_info, hmm )); 17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL float 17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEViterbi( CvImgObsInfo * obs_info, CvEHMM * hmm ) 17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn float result = FLT_MAX; 17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvEViterbi" ); 17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn if( (obs_info == NULL) || (hmm == NULL) ) 17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_ERROR( CV_BadDataPtr, "Null pointer." ); 17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn result = icvEViterbi( obs_info, hmm ); 17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn return result; 17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void 17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvMixSegmL2( CvImgObsInfo ** obs_info_array, int num_img, CvEHMM * hmm ) 17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn CV_FUNCNAME( "cvMixSegmL2" ); 17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __BEGIN__; 17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn IPPI_CALL( icvMixSegmL2( obs_info_array, num_img, hmm )); 17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn __END__; 17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} 17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file */ 17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn 1771