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
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define LN2PI 1.837877f
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define BIG_FLT 1.e+10f
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_ERGODIC 1
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_CAUSAL 2
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_LAST_STATE 1
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define _CV_BEST_STATE 2
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//*F///////////////////////////////////////////////////////////////////////////////////////
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvForward1DHMM
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function performs baum-welsh algorithm
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters: obs_info - addres of pointer to CvImgObsInfo structure
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                num_hor_obs - number of horizontal observation vectors
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                num_ver_obs - number of horizontal observation vectors
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                obs_size - length of observation vector
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: error status
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvForward1DHMM( int num_states, int num_obs, CvMatr64d A,
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          CvMatr64d B,
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          double* scales)
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // assume that observation and transition
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // probabilities already computed
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int m_HMMType  = _CV_CAUSAL;
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double* m_pi = icvAlloc( num_states* sizeof( double) );
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* alpha is matrix
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn       rows throuhg states
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn       columns through time
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    */
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double* alpha = icvAlloc( num_states*num_obs * sizeof( double ) );
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* All calculations will be in non-logarithmic domain */
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* Initialization */
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* set initial state probabilities */
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m_pi[0] = 1;
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 1; i < num_states; i++)
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m_pi[i] = 0.0;
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for  (i = 0; i < num_states; i++)
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        alpha[i] = m_pi[i] * m_b[ i];
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /******************************************************************/
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*   Induction                                                    */
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( m_HMMType == _CV_ERGODIC )
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int t;
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (t = 1 ; t < num_obs; t++)
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for (j = 0; j < num_states; j++)
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               double sum = 0.0;
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               int i;
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for (i = 0; i < num_states; i++)
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     sum += alpha[(t - 1) * num_states + i] * A[i * num_states + j];
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                alpha[(t - 1) * num_states + j] = sum * B[t * num_states + j];
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* add computed alpha to scale factor */
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sum_alpha += alpha[(t - 1) * num_states + j];
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double scale = 1/sum_alpha;
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* scale alpha */
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for (j = 0; j < num_states; j++)
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                alpha[(t - 1) * num_states + j] *= scale;
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            scales[t] = scale;
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//*F///////////////////////////////////////////////////////////////////////////////////////
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvCreateObsInfo
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function allocates memory for CvImgObsInfo structure
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             and its inner stuff
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters: obs_info - addres of pointer to CvImgObsInfo structure
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                num_hor_obs - number of horizontal observation vectors
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                num_ver_obs - number of horizontal observation vectors
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                obs_size - length of observation vector
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: error status
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*CvStatus icvCreateObsInfo( CvImgObsInfo** obs_info,
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              CvSize num_obs, int obs_size )
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int total = num_obs.height * num_obs.width;
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvImgObsInfo* obs = (CvImgObsInfo*)icvAlloc( sizeof( CvImgObsInfo) );
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    obs->obs_x = num_obs.width;
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    obs->obs_y = num_obs.height;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    obs->obs = (float*)icvAlloc( total * obs_size * sizeof(float) );
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    obs->state = (int*)icvAlloc( 2 * total * sizeof(int) );
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    obs->mix = (int*)icvAlloc( total * sizeof(int) );
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    obs->obs_size = obs_size;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    obs_info[0] = obs;
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}*/
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*CvStatus icvReleaseObsInfo( CvImgObsInfo** p_obs_info )
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvImgObsInfo* obs_info = p_obs_info[0];
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &(obs_info->obs) );
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &(obs_info->mix) );
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &(obs_info->state) );
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &(obs_info) );
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    p_obs_info[0] = NULL;
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn} */
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//*F///////////////////////////////////////////////////////////////////////////////////////
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvCreate1DHMM
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function allocates memory for 1-dimensional HMM
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             and its inner stuff
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters: hmm - addres of pointer to CvEHMM structure
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                state_number - number of states in HMM
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                num_mix - number of gaussian mixtures in HMM states
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                          size of array is defined by previous parameter
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                obs_size - length of observation vectors
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: error status
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvCreate1DHMM( CvEHMM** this_hmm,
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         int state_number, int* num_mix, int obs_size )
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int real_states = state_number;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvEHMMState* all_states;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvEHMM* hmm;
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int total_mix = 0;
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float* pointers;
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* allocate memory for hmm */
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hmm = (CvEHMM*)icvAlloc( sizeof(CvEHMM) );
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* set number of superstates */
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hmm->num_states = state_number;
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hmm->level = 0;
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* allocate memory for all states */
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    all_states = (CvEHMMState *)icvAlloc( real_states * sizeof( CvEHMMState ) );
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* assign number of mixtures */
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < real_states; i++ )
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        all_states[i].num_mix = num_mix[i];
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* compute size of inner of all real states */
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < real_states; i++ )
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        total_mix += num_mix[i];
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* allocate memory for states stuff */
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    pointers = (float*)icvAlloc( total_mix * (2/*for mu invvar */ * obs_size +
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 2/*for weight and log_var_val*/ ) * sizeof( float) );
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* organize memory */
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < real_states; i++ )
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        all_states[i].mu      = pointers; pointers += num_mix[i] * obs_size;
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        all_states[i].inv_var = pointers; pointers += num_mix[i] * obs_size;
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        all_states[i].log_var_val = pointers; pointers += num_mix[i];
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        all_states[i].weight      = pointers; pointers += num_mix[i];
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hmm->u.state = all_states;
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hmm->transP = icvCreateMatrix_32f( hmm->num_states, hmm->num_states );
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    hmm->obsProb = NULL;
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* if all ok - return pointer */
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *this_hmm = hmm;
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvRelease1DHMM( CvEHMM** phmm )
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvEHMM* hmm = phmm[0];
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvDeleteMatrix( hmm->transP );
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (hmm->obsProb != NULL)
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int* tmp = ((int*)(hmm->obsProb)) - 3;
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvFree( &(tmp)  );
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &(hmm->u.state->mu) );
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &(hmm->u.state) );
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    phmm[0] = NULL;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*can be used in CHMM & DHMM */
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvUniform1DSegm( Cv1DObsInfo* obs_info, CvEHMM* hmm )
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* implementation is very bad */
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  i;
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvEHMMState* first_state;
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* check arguments */
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( !obs_info || !hmm ) return CV_NULLPTR_ERR;
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    first_state = hmm->u.state;
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < obs_info->obs_x; i++)
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //bad line (division )
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int state = (i * hmm->num_states)/obs_info->obs_x;
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        obs_info->state[i] = state;
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: InitMixSegm
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function implements the mixture segmentation of the states of the embedded HMM
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context: used with the Viterbi training of the embedded HMM
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             Function uses K-Means algorithm for clustering
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obs_info_array - array of pointers to image observations
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 num_img - length of above array
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 hmm - pointer to HMM structure
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: error status
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvInit1DMixSegm(Cv1DObsInfo** obs_info_array, int num_img, CvEHMM* hmm)
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int  k, i, j;
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* num_samples; /* number of observations in every state */
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* counter;     /* array of counters for every state */
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int**  a_class;   /* for every state - characteristic array */
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvVect32f** samples; /* for every state - pointer to observation vectors */
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int***  samples_mix;   /* for every state - array of pointers to vectors mixtures */
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvTermCriteria criteria = cvTermCriteria( CV_TERMCRIT_EPS|CV_TERMCRIT_ITER,
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              1000,    /* iter */
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              0.01f ); /* eps  */
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int total = hmm->num_states;
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvEHMMState* first_state = hmm->u.state;
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* for every state integer is allocated - number of vectors in state */
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    num_samples = (int*)icvAlloc( total * sizeof(int) );
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* integer counter is allocated for every state */
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    counter = (int*)icvAlloc( total * sizeof(int) );
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    samples = (CvVect32f**)icvAlloc( total * sizeof(CvVect32f*) );
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    samples_mix = (int***)icvAlloc( total * sizeof(int**) );
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* clear */
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( num_samples, 0 , total*sizeof(int) );
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( counter, 0 , total*sizeof(int) );
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* for every state the number of vectors which belong to it is computed (smth. like histogram) */
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (k = 0; k < num_img; k++)
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvImgObsInfo* obs = obs_info_array[k];
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (i = 0; i < obs->obs_x; i++)
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int state = obs->state[ i ];
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            num_samples[state] += 1;
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* for every state int* is allocated */
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    a_class = (int**)icvAlloc( total*sizeof(int*) );
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < total; i++)
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        a_class[i] = (int*)icvAlloc( num_samples[i] * sizeof(int) );
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples[i] = (CvVect32f*)icvAlloc( num_samples[i] * sizeof(CvVect32f) );
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        samples_mix[i] = (int**)icvAlloc( num_samples[i] * sizeof(int*) );
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* for every state vectors which belong to state are gathered */
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (k = 0; k < num_img; k++)
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvImgObsInfo* obs = obs_info_array[k];
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int num_obs = obs->obs_x;
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* vector = obs->obs;
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (i = 0; i < num_obs; i++, vector+=obs->obs_size )
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int state = obs->state[i];
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            samples[state][counter[state]] = vector;
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            samples_mix[state][counter[state]] = &(obs->mix[i]);
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            counter[state]++;
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* clear counters */
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( counter, 0, total*sizeof(int) );
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* do the actual clustering using the K Means algorithm */
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < total; i++)
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if ( first_state[i].num_mix == 1)
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for (k = 0; k < num_samples[i]; k++)
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* all vectors belong to one mixture */
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a_class[i][k] = 0;
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( num_samples[i] )
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* clusterize vectors  */
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvKMeans( first_state[i].num_mix, samples[i], num_samples[i],
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                obs_info_array[0]->obs_size, criteria, a_class[i] );
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* for every vector number of mixture is assigned */
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < total; i++ )
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (j = 0; j < num_samples[i]; j++)
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            samples_mix[i][j][0] = a_class[i][j];
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   for (i = 0; i < total; i++)
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvFree( &(a_class[i]) );
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvFree( &(samples[i]) );
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvFree( &(samples_mix[i]) );
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &a_class );
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &samples );
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &samples_mix );
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &counter );
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &num_samples );
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: ComputeUniModeGauss
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function computes the Gaussian pdf for a sample vector
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obsVeq - pointer to the sample vector
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 mu - pointer to the mean vector of the Gaussian pdf
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 var - pointer to the variance vector of the Gaussian pdf
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 VecSize - the size of sample vector
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: the pdf of the sample vector given the specified Gaussian
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*float icvComputeUniModeGauss(CvVect32f vect, CvVect32f mu,
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              CvVect32f inv_var, float log_var_val, int vect_size)
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n;
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double tmp;
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double prob;
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    prob = -log_var_val;
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (n = 0; n < vect_size; n++)
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        tmp = (vect[n] - mu[n]) * inv_var[n];
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prob = prob - tmp * tmp;
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   }
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   //prob *= 0.5f;
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   return (float)prob;
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}*/
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: ComputeGaussMixture
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function computes the mixture Gaussian pdf of a sample vector.
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obsVeq - pointer to the sample vector
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 mu  - two-dimensional pointer to the mean vector of the Gaussian pdf;
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                       the first dimension is indexed over the number of mixtures and
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                       the second dimension is indexed along the size of the mean vector
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 var - two-dimensional pointer to the variance vector of the Gaussian pdf;
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                       the first dimension is indexed over the number of mixtures and
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                       the second dimension is indexed along the size of the variance vector
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 VecSize - the size of sample vector
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 weight - pointer to the wights of the Gaussian mixture
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 NumMix - the number of Gaussian mixtures
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: the pdf of the sample vector given the specified Gaussian mixture.
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Calculate probability of observation at state in logarithmic scale*/
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*float icvComputeGaussMixture( CvVect32f vect, float* mu,
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                float* inv_var, float* log_var_val,
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                int vect_size, float* weight, int num_mix )
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double prob, l_prob;
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    prob = 0.0f;
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (num_mix == 1)
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return icvComputeUniModeGauss( vect, mu, inv_var, log_var_val[0], vect_size);
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int m;
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (m = 0; m < num_mix; m++)
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if ( weight[m] > 0.0)
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                l_prob = icvComputeUniModeGauss(vect, mu + m*vect_size,
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                        inv_var + m * vect_size,
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                        log_var_val[m],
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                        vect_size);
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                prob = prob + weight[m]*exp((double)l_prob);
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        prob = log(prob);
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return (float)prob;
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: EstimateObsProb
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function computes the probability of every observation in every state
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obs_info - observations
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 hmm      - hmm
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: error status
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvEstimate1DObsProb(CvImgObsInfo* obs_info, CvEHMM* hmm )
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j;
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int total_states = 0;
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* check if matrix exist and check current size
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn       if not sufficient - realloc */
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int status = 0; /* 1 - not allocated, 2 - allocated but small size,
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                       3 - size is enough, but distribution is bad, 0 - all ok */
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*for( j = 0; j < hmm->num_states; j++ )
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn       total_states += hmm->u.ehmm[j].num_states;
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }*/
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    total_states = hmm->num_states;
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( hmm->obsProb == NULL )
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* allocare memory */
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int need_size = ( obs_info->obs_x /* * obs_info->obs_y*/ * total_states * sizeof(float) /* +
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          obs_info->obs_y * hmm->num_states * sizeof( CvMatr32f) */);
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int* buffer = (int*)icvAlloc( need_size + 3 * sizeof(int) );
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer[0] = need_size;
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer[1] = obs_info->obs_y;
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer[2] = obs_info->obs_x;
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hmm->obsProb = (float**) (buffer + 3);
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        status = 3;
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* check current size */
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int* total= (int*)(((int*)(hmm->obsProb)) - 3);
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int need_size = ( obs_info->obs_x /* * obs_info->obs_y*/ * total_states * sizeof(float) /* +
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           obs_info->obs_y * hmm->num_states * sizeof( CvMatr32f(float*)  )*/ );
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( sizeof(float*) == sizeof(int) );
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if ( need_size > (*total) )
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int* buffer = ((int*)(hmm->obsProb)) - 3;
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvFree( &buffer);
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buffer = (int*)icvAlloc( need_size + 3);
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buffer[0] = need_size;
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buffer[1] = obs_info->obs_y;
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buffer[2] = obs_info->obs_x;
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            hmm->obsProb = (float**)(buffer + 3);
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            status = 3;
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if (!status)
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int* obsx = ((int*)(hmm->obsProb)) - 1;
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //int* obsy = ((int*)(hmm->obsProb)) - 2;
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( /*(*obsy > 0) &&*/ (*obsx > 0) );
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* is good distribution? */
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if ( (obs_info->obs_x > (*obsx) ) /* || (obs_info->obs_y > (*obsy) ) */ )
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            status = 3;
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( (status == 0) || (status == 3) );
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* if bad status - do reallocation actions */
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if ( status )
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float** tmp = hmm->obsProb;
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //float*  tmpf;
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* distribute pointers of ehmm->obsProb */
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*        for( i = 0; i < hmm->num_states; i++ )
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            hmm->u.ehmm[i].obsProb = tmp;
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            tmp += obs_info->obs_y;
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //tmpf = (float*)tmp;
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* distribute pointers of ehmm->obsProb[j] */
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*      for( i = 0; i < hmm->num_states; i++ )
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvEHMM* ehmm = &( hmm->u.ehmm[i] );
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < obs_info->obs_y; j++ )
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ehmm->obsProb[j] = tmpf;
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tmpf += ehmm->num_states * obs_info->obs_x;
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        hmm->obsProb = tmp;
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }/* end of pointer distribution */
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 1
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define MAX_BUF_SIZE  1200
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float  local_log_mix_prob[MAX_BUF_SIZE];
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double local_mix_prob[MAX_BUF_SIZE];
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int    vect_size = obs_info->obs_size;
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvStatus res = CV_NO_ERR;
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float*  log_mix_prob = local_log_mix_prob;
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double* mix_prob = local_mix_prob;
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int  max_size = 0;
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int  obs_x = obs_info->obs_x;
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* calculate temporary buffer size */
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //for( i = 0; i < hmm->num_states; i++ )
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //{
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //    CvEHMM* ehmm = &(hmm->u.ehmm[i]);
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvEHMMState* state = hmm->u.state;
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int max_mix = 0;
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < hmm->num_states; j++ )
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int t = state[j].num_mix;
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( max_mix < t ) max_mix = t;
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            max_mix *= hmm->num_states;
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /*if( max_size < max_mix )*/ max_size = max_mix;
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //}
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        max_size *= obs_x * vect_size;
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* allocate buffer */
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( max_size > MAX_BUF_SIZE )
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            log_mix_prob = (float*)icvAlloc( max_size*(sizeof(float) + sizeof(double)));
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !log_mix_prob ) return CV_OUTOFMEM_ERR;
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            mix_prob = (double*)(log_mix_prob + max_size);
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( log_mix_prob, 0, max_size*sizeof(float));
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /*****************computing probabilities***********************/
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* loop through external states */
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //for( i = 0; i < hmm->num_states; i++ )
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //    CvEHMM* ehmm = &(hmm->u.ehmm[i]);
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvEHMMState* state = hmm->u.state;
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int max_mix = 0;
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int n_states = hmm->num_states;
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* determine maximal number of mixtures (again) */
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < hmm->num_states; j++ )
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int t = state[j].num_mix;
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( max_mix < t ) max_mix = t;
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* loop through rows of the observation matrix */
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            //for( j = 0; j < obs_info->obs_y; j++ )
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int  m, n;
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float* obs = obs_info->obs;/* + j * obs_x * vect_size; */
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float* log_mp = max_mix > 1 ? log_mix_prob : (float*)(hmm->obsProb);
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double* mp = mix_prob;
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* several passes are done below */
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* 1. calculate logarithms of probabilities for each mixture */
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* loop through mixtures */
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*  !!!! */     for( m = 0; m < max_mix; m++ )
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* set pointer to first observation in the line */
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float* vect = obs;
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* cycles through obseravtions in the line */
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( n = 0; n < obs_x; n++, vect += vect_size, log_mp += n_states )
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int k, l;
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( l = 0; l < n_states; l++ )
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            if( state[l].num_mix > m )
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                float* mu = state[l].mu + m*vect_size;
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                float* inv_var = state[l].inv_var + m*vect_size;
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                double prob = -state[l].log_var_val[m];
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                for( k = 0; k < vect_size; k++ )
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                {
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    double t = (vect[k] - mu[k])*inv_var[k];
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    prob -= t*t;
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                }
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                log_mp[l] = MAX( (float)prob, -500 );
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* skip the rest if there is a single mixture */
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( max_mix != 1 )
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* 2. calculate exponent of log_mix_prob
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          (i.e. probability for each mixture) */
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    res = icvbExp_32f64f( log_mix_prob, mix_prob,
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            max_mix * obs_x * n_states );
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( res < 0 ) goto processing_exit;
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* 3. sum all mixtures with weights */
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* 3a. first mixture - simply scale by weight */
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( n = 0; n < obs_x; n++, mp += n_states )
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int l;
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( l = 0; l < n_states; l++ )
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            mp[l] *= state[l].weight[0];
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* 3b. add other mixtures */
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( m = 1; m < max_mix; m++ )
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int ofs = -m*obs_x*n_states;
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( n = 0; n < obs_x; n++, mp += n_states )
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int l;
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            for( l = 0; l < n_states; l++ )
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            {
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                if( m < state[l].num_mix )
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                {
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    mp[l + ofs] += mp[l] * state[l].weight[m];
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                }
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            }
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* 4. Put logarithms of summary probabilities to the destination matrix */
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    res = icvbLog_64f32f( mix_prob, (float*)(hmm->obsProb),//[j],
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            obs_x * n_states );
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( res < 0 ) goto processing_exit;
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennprocessing_exit:
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( log_mix_prob != local_log_mix_prob ) icvFree( &log_mix_prob );
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return res;
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef MAX_BUF_SIZE
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*    for( i = 0; i < hmm->num_states; i++ )
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvEHMM* ehmm = &(hmm->u.ehmm[i]);
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvEHMMState* state = ehmm->u.state;
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < obs_info->obs_y; j++ )
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int k,m;
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int obs_index = j * obs_info->obs_x;
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float* B = ehmm->obsProb[j];
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // cycles through obs and states
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < obs_info->obs_x; k++ )
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvVect32f vect = (obs_info->obs) + (obs_index + k) * vect_size;
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float* matr_line = B + k * ehmm->num_states;
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( m = 0; m < ehmm->num_states; m++ )
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    matr_line[m] = icvComputeGaussMixture( vect, state[m].mu, state[m].inv_var,
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                             state[m].log_var_val, vect_size, state[m].weight,
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                             state[m].num_mix );
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: EstimateTransProb
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates the state and super state transition probabilities
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             of the model given the images,
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             the state segmentation and the input parameters
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters: obs_info_array - array of pointers to image observations
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                num_img - length of above array
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                hmm - pointer to HMM structure
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: void
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvEstimate1DTransProb( Cv1DObsInfo** obs_info_array,
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 int num_seq,
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                 CvEHMM* hmm )
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int    i, j, k;
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* as a counter we will use transP matrix */
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* initialization */
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* clear transP */
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvSetZero_32f( hmm->transP, hmm->num_states, hmm->num_states );
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* compute the counters */
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < num_seq; i++)
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int counter = 0;
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Cv1DObsInfo* info = obs_info_array[i];
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (k = 0; k < info->obs_x; k++, counter++)
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* compute how many transitions from state to state
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               occured */
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int state;
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int nextstate;
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            state = info->state[counter];
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if (k < info->obs_x - 1)
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int transP_size = hmm->num_states;
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                nextstate = info->state[counter+1];
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                hmm->transP[ state * transP_size + nextstate] += 1;
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* estimate superstate matrix */
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < hmm->num_states; i++)
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float total = 0;
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float inv_total;
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < hmm->num_states; j++)
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            total += hmm->transP[i * hmm->num_states + j];
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //assert( total );
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inv_total = total ? 1.f/total : 0;
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < hmm->num_states; j++)
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            hmm->transP[i * hmm->num_states + j] =
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                hmm->transP[i * hmm->num_states + j] ?
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (float)log( hmm->transP[i * hmm->num_states + j] * inv_total ) : -BIG_FLT;
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: MixSegmL2
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function implements the mixture segmentation of the states of the embedded HMM
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context: used with the Viterbi training of the embedded HMM
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             obs_info_array
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             num_img
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             hmm
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: void
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icv1DMixSegmL2(CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm )
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int     k, i, m;
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvEHMMState* state = hmm->u.state;
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (k = 0; k < num_img; k++)
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        //int counter = 0;
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvImgObsInfo* info = obs_info_array[k];
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (i = 0; i < info->obs_x; i++)
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int e_state = info->state[i];
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float min_dist;
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            min_dist = icvSquareDistance((info->obs) + (i * info->obs_size),
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                               state[e_state].mu, info->obs_size);
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            info->mix[i] = 0;
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for (m = 1; m < state[e_state].num_mix; m++)
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float dist=icvSquareDistance( (info->obs) + (i * info->obs_size),
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                               state[e_state].mu + m * info->obs_size,
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                               info->obs_size);
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if (dist < min_dist)
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    min_dist = dist;
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /* assign mixture with smallest distance */
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    info->mix[i] = m;
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvEViterbi
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates the embedded Viterbi algorithm
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             for 1 image
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             obs_info - observations
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             hmm      - HMM
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: the Embedded Viterbi probability (float)
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             and do state segmentation of observations
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfloat icvViterbi(Cv1DObsInfo* obs_info, CvEHMM* hmm)
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int    i, counter;
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float  log_likelihood;
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //CvEHMMState* first_state = hmm->u.state;
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* memory allocation for superB */
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*CvMatr32f superB = picvCreateMatrix_32f(hmm->num_states, obs_info->obs_x );*/
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* memory allocation for q */
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* super_q = (int*)icvAlloc( obs_info->obs_x * sizeof(int) );
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* perform Viterbi segmentation (process 1D HMM) */
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvViterbiSegmentation( hmm->num_states, obs_info->obs_x,
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            hmm->transP, (float*)(hmm->obsProb), 0,
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            _CV_LAST_STATE, &super_q, obs_info->obs_x,
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             obs_info->obs_x, &log_likelihood );
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    log_likelihood /= obs_info->obs_x ;
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    counter = 0;
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* assign new state to observation vectors */
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < obs_info->obs_x; i++)
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         int state = super_q[i];
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn         obs_info->state[i] = state;
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* memory deallocation for superB */
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*picvDeleteMatrix( superB );*/
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvFree( &super_q );
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return log_likelihood;
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus icvEstimate1DHMMStateParams(CvImgObsInfo** obs_info_array, int num_img, CvEHMM* hmm)
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* compute gamma, weights, means, vars */
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int k, i, j, m;
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int counter = 0;
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int total = 0;
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int vect_len = obs_info_array[0]->obs_size;
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float start_log_var_val = LN2PI * vect_len;
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvVect32f tmp_vect = icvCreateVector_32f( vect_len );
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvEHMMState* first_state = hmm->u.state;
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( sizeof(float) == sizeof(int) );
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    total+= hmm->num_states;
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /***************Gamma***********************/
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* initialize gamma */
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < total; i++ )
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (m = 0; m < first_state[i].num_mix; m++)
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ((int*)(first_state[i].weight))[m] = 0;
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* maybe gamma must be computed in mixsegm process ?? */
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* compute gamma */
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    counter = 0;
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (k = 0; k < num_img; k++)
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvImgObsInfo* info = obs_info_array[k];
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int num_obs = info->obs_y * info->obs_x;
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (i = 0; i < num_obs; i++)
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int state, mixture;
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            state = info->state[i];
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            mixture = info->mix[i];
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* computes gamma - number of observations corresponding
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               to every mixture of every state */
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ((int*)(first_state[state].weight))[mixture] += 1;
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /***************Mean and Var***********************/
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* compute means and variances of every item */
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* initially variance placed to inv_var */
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* zero mean and variance */
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < total; i++)
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( (void*)first_state[i].mu, 0, first_state[i].num_mix * vect_len *
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                         sizeof(float) );
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( (void*)first_state[i].inv_var, 0, first_state[i].num_mix * vect_len *
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                         sizeof(float) );
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* compute sums */
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < num_img; i++)
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvImgObsInfo* info = obs_info_array[i];
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int total_obs = info->obs_x;// * info->obs_y;
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* vector = info->obs;
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (j = 0; j < total_obs; j++, vector+=vect_len )
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int state = info->state[j];
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int mixture = info->mix[j];
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvVect32f mean  = first_state[state].mu + mixture * vect_len;
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvVect32f mean2 = first_state[state].inv_var + mixture * vect_len;
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvAddVector_32f( mean, vector, mean, vect_len );
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvAddSquare_32f_C1IR( vector, vect_len * sizeof(float),
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    mean2, vect_len * sizeof(float), cvSize(vect_len, 1) );
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*compute the means and variances */
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* assume gamma already computed */
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    counter = 0;
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < total; i++)
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvEHMMState* state = &(first_state[i]);
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (m = 0; m < state->num_mix; m++)
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int k;
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvVect32f mu  = state->mu + m * vect_len;
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvVect32f invar = state->inv_var + m * vect_len;
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if ( ((int*)state->weight)[m] > 1)
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float inv_gamma = 1.f/((int*)(state->weight))[m];
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvScaleVector_32f( mu, mu, vect_len, inv_gamma);
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvScaleVector_32f( invar, invar, vect_len, inv_gamma);
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvMulVectors_32f(mu, mu, tmp_vect, vect_len);
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvSubVector_32f( invar, tmp_vect, invar, vect_len);
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* low bound of variance - 0.01 (Ara's experimental result) */
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < vect_len; k++ )
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                invar[k] = (invar[k] > 0.01f) ? invar[k] : 0.01f;
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* compute log_var */
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            state->log_var_val[m] = start_log_var_val;
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < vect_len; k++ )
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                state->log_var_val[m] += (float)log( invar[k] );
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            state->log_var_val[m] *= 0.5;
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* compute inv_var = 1/sqrt(2*variance) */
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvScaleVector_32f(invar, invar, vect_len, 2.f );
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvbInvSqrt_32f(invar, invar, vect_len );
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /***************Weights***********************/
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* normilize gammas - i.e. compute mixture weights */
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //compute weights
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for (i = 0; i < total; i++)
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int gamma_total = 0;
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float norm;
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (m = 0; m < first_state[i].num_mix; m++)
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            gamma_total += ((int*)(first_state[i].weight))[m];
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        norm = gamma_total ? (1.f/(float)gamma_total) : 0.f;
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for (m = 0; m < first_state[i].num_mix; m++)
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            first_state[i].weight[m] = ((int*)(first_state[i].weight))[m] * norm;
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvDeleteVector( tmp_vect);
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1152