Move the sources to trunk
[opencv] / apps / HMMDemo / ContEHMM.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/// ContEHMM.cpp: implementation of the CContEHMM class.
41 //
42 //////////////////////////////////////////////////////////////////////
43
44 #include "stdafx.h"
45 #include "HMMDemo.h"
46 #include "ContEHMM.h"
47 #include <assert.h>
48
49 #ifdef _DEBUG
50 #undef THIS_FILE
51 static char THIS_FILE[]=__FILE__;
52 #define new DEBUG_NEW
53 #endif
54
55 //////////////////////////////////////////////////////////////////////
56 // Construction/Destruction
57 //////////////////////////////////////////////////////////////////////
58
59 CContEHMM::CContEHMM()
60 {
61     m_hmm = NULL;
62     m_vectSize = 0;
63 }
64
65 CContEHMM::~CContEHMM()
66 {
67     if (m_hmm) cvRelease2DHMM( &m_hmm );  
68     m_vectSize = 0;
69
70 }
71
72 bool CContEHMM::CreateHMM( int* num_states, int* num_mix, int vect_size )
73 {
74     if (m_hmm) cvRelease2DHMM( &m_hmm );
75     m_hmm = 0;
76
77     m_hmm = cvCreate2DHMM( num_states, num_mix, vect_size ); 
78     
79     m_vectSize = vect_size;
80     return true;
81     
82     //else return false;
83 }
84
85
86 bool CContEHMM::Save( const char* filename )
87 {
88     FILE* file;
89
90     if (!m_hmm) return false;
91
92     file = fopen( filename, "wt" );
93
94     if (!file) return false;
95
96
97     // write topology
98     fprintf(file, "%s %d\n", "<NumSuperStates>", m_hmm->num_states );
99     fprintf(file, "%s ", "<NumStates>");
100     for( int i = 0; i < m_hmm->num_states; i++ )
101     {
102         fprintf(file, "%d ", m_hmm->u.ehmm[i].num_states );
103     }
104     fprintf(file, "\n");
105
106     fprintf(file, "%s ", "<NumMixtures>");
107     for( i = 0; i < m_hmm->num_states; i++ )
108     {
109         CvEHMM* ehmm = &(m_hmm->u.ehmm[i]);
110
111         for( int j = 0; j < ehmm->num_states; j++ )
112         {
113             fprintf(file, "%d ", ehmm->u.state[j].num_mix );
114         }
115     }
116     fprintf(file, "\n");
117
118     fprintf(file, "%s %d\n", "<VecSize>", m_vectSize);
119
120     //consequently write all hmms
121     CvEHMM* hmm = m_hmm;
122     for( i = 0; i < m_hmm->num_states + 1; i++ )
123     {
124         if (hmm->level == 0 )
125             fprintf(file, "%s\n", "<BeginEmbeddedHMM>");
126         else
127             fprintf(file, "%s\n", "<BeginExternalHMM>");
128
129         fprintf(file, "%s %d\n", "<NumStates>", hmm->num_states);
130
131         if (hmm->level == 0 )
132         {
133             for ( int j = 0; j < hmm->num_states; j++)
134             {
135                 CvEHMMState* state = &(hmm->u.state[j]);
136
137                 fprintf(file, "%s %d\n", "<State>", j);
138                 fprintf(file, "%s %d\n", "<NumMixes>", state->num_mix);
139
140                 float* mu = state->mu;
141                 float* inv_var = state->inv_var;
142
143                 for( int m = 0; m < state->num_mix; m++)
144                 {
145                     fprintf(file, "%s %d %s %f\n", "<Mixture>", m, "<Weight>", state->weight[m] );
146                     fprintf(file, "%s\n", "<Mean>");
147
148                     for (int k = 0; k < m_vectSize; k++)
149                     {  
150                         fprintf(file, "%f ", mu[0]); 
151                         mu++;
152                     }            
153                     
154                     fprintf(file, "\n");
155                     fprintf(file, "%s\n", "<Inverted_Deviation>");
156                     
157                     for (k = 0; k < m_vectSize; k++)
158                     {
159                         fprintf(file, "%f ", inv_var[0]);
160                         inv_var++;
161                     }
162                     fprintf(file, "\n");
163
164                     fprintf(file, "%s %f\n", "<LogVarVal>", state->log_var_val[m] );
165                     
166
167                 }
168             }
169         }
170
171         //write the transition probability matrix
172         fprintf(file, "%s\n", "<TransP>" ); 
173         float* prob = hmm->transP;
174
175         for (int j = 0; j < hmm->num_states; j++)
176         {
177             for (int k = 0; k < hmm->num_states; k++)
178             {
179                 fprintf(file, "%f ", *prob);
180                 prob++;
181             }            
182             fprintf(file, "\n");
183         }
184
185         if( hmm->level == 0 )
186             fprintf(file, "%s\n", "<EndEmbeddedHMM>");
187         else
188             fprintf(file, "%s\n", "<EndExternalHMM>");
189
190         hmm = &(m_hmm->u.ehmm[i]);
191     }            
192     fclose(file);
193     return true;
194
195
196 bool CContEHMM::Load( const char* filename )
197 {
198     FILE* file;
199     int num_states[128];
200     int num_mix[128];
201     char temp_char[128];
202
203     if (m_hmm) cvRelease2DHMM( &m_hmm);
204
205     file = fopen( filename, "rt" );
206
207     if (!file) return false;
208
209     // read topology
210     fscanf(file, "%s %d\n", temp_char, num_states);
211     fscanf(file, "%s ", temp_char); 
212     for( int i = 0; i < num_states[0]; i++ )
213     {
214         fscanf(file, "%d ", num_states + i + 1 );
215     }
216     fscanf(file, "\n");
217     
218     //compute total number of internal states
219     int total_states = 0;
220     for( i = 0; i < num_states[0]; i++ )
221     {
222         total_states += num_states[i+1];
223     }
224     
225     //read number of mixtures
226     fscanf(file, "%s ", temp_char);
227     for( i = 0; i < total_states; i++ )
228     {
229         fscanf(file, "%d ", &num_mix[i] );
230     }
231     fscanf(file, "\n");
232
233     fscanf(file, "%s %d\n", temp_char, &m_vectSize);
234
235     m_hmm = cvCreate2DHMM( num_states, num_mix, m_vectSize);
236
237  
238     //create HMM with known parameters
239 //!!!    cvCreate2DHMM( &m_hmm, num_states, num_mix, m_vectSize);
240     if (!m_hmm ) return false;
241
242     //consequently read all hmms
243     CvEHMM* hmm = m_hmm;
244     for( i = 0; i < num_states[0]+1; i++ )
245     {
246         fscanf(file, "%s\n", temp_char);
247         int temp_int;
248         fscanf(file, "%s %d\n", temp_char , &temp_int);  assert(temp_int==num_states[i]); 
249
250         if ( i!= 0 )
251         {
252             for (int j = 0; j < num_states[i]; j++)
253             {
254                 CvEHMMState* state = &(hmm->u.state[j]);
255
256                 fscanf(file, "%s %d\n", temp_char, &temp_int); assert(temp_int == j);
257
258                 fscanf(file, "%s %d\n", temp_char, &temp_int); assert(temp_int == state->num_mix);
259
260                 float* mu = state->mu;
261                 float* inv_var = state->inv_var;
262
263                 for( int m = 0; m < state->num_mix; m++)
264                 {
265                     int temp_int;
266                     fscanf(file, "%s %d %s %f\n", temp_char, &temp_int, temp_char, &(state->weight[m]) );
267                     assert( temp_int == m );
268                     fscanf(file, "%s\n", temp_char );
269
270                     for (int k = 0; k < m_vectSize; k++)
271                     {  
272                         fscanf(file, "%f ", mu); 
273                         mu++;
274                     }            
275                     
276                     fscanf(file, "\n");
277                     fscanf(file, "%s\n", temp_char);
278                     
279                     for (k = 0; k < m_vectSize; k++)
280                     {
281                         fscanf(file, "%f ", inv_var);
282                         inv_var++;
283                     }
284                     fscanf(file, "\n");
285
286                     fscanf(file, "%s %f\n", temp_char, &(state->log_var_val[m]) );
287                     
288                 }
289             }
290         }
291
292         //read the transition probability matrix
293         fscanf(file, "%s\n", temp_char ); 
294         float* prob = hmm->transP;
295
296         for (int j = 0; j < hmm->num_states; j++)
297         {
298             for (int k = 0; k < hmm->num_states; k++)
299             {
300                 fscanf(file, "%f ", prob);
301                 prob++;
302             }            
303             fscanf(file, "\n");
304         }
305
306         fscanf( file, "%s\n", temp_char );
307
308         hmm = &(m_hmm->u.ehmm[i]);
309     }
310     fclose(file); 
311     return true;
312 }
313     
314 BOOL CContEHMM::Release()
315 {
316     if (m_hmm)
317     {
318         cvRelease2DHMM( &m_hmm ); 
319         m_hmm = 0;
320     }
321
322     return TRUE;
323 }