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