Update the changelog
[opencv] / apps / HMMDemo / HMMDemo.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*/// HMMDemo.cpp : Defines the class behaviors for the application.
41 //
42 #include "stdafx.h"
43 #include "HMMDemo.h"
44
45 #include "MainFrm.h"
46 #include "HMMDemoDoc.h"
47 #include "HMMDemoView.h"
48
49 #include "FaceBase.h"
50 #include "ContEHMM.h"
51
52 #ifdef _DEBUG
53 #define new DEBUG_NEW
54 #undef THIS_FILE
55 static char THIS_FILE[] = __FILE__;
56 #endif
57
58 /////////////////////////////////////////////////////////////////////////////
59 // CHMMDemoApp
60
61 BEGIN_MESSAGE_MAP(CHMMDemoApp, CWinApp)
62         //{{AFX_MSG_MAP(CHMMDemoApp)
63         ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
64         ON_COMMAND(ID_SAVE_CONFIG, OnSaveConfig)
65         ON_COMMAND(ID_LOAD_CONFIG, OnLoadConfig)
66         //}}AFX_MSG_MAP
67         // Standard file based document commands
68         ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
69         ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
70 END_MESSAGE_MAP()
71
72 /////////////////////////////////////////////////////////////////////////////
73 // CHMMDemoApp construction
74
75 CHMMDemoApp::CHMMDemoApp()
76 {
77 }
78
79 /////////////////////////////////////////////////////////////////////////////
80 // The one and only CHMMDemoApp object
81
82 CHMMDemoApp theApp;
83
84 /////////////////////////////////////////////////////////////////////////////
85 // CHMMDemoApp initialization
86
87 BOOL CHMMDemoApp::InitInstance()
88 {
89         AfxEnableControlContainer();
90
91         // Standard initialization
92         // If you are not using these features and wish to reduce the size
93         //  of your final executable, you should remove from the following
94         //  the specific initialization routines you do not need.
95
96 #ifdef _AFXDLL
97         Enable3dControls();                     // Call this when using MFC in a shared DLL
98 #else
99         Enable3dControlsStatic();       // Call this when linking to MFC statically
100 #endif
101
102         // Change the registry key under which our settings are stored.
103         // TODO: You should modify this string to be something appropriate
104         // such as the name of your company or organization.
105         SetRegistryKey(_T("Local AppWizard-Generated Applications"));
106
107         LoadStdProfileSettings();  // Load standard INI file options (including MRU)
108
109         // Register the application's document templates.  Document templates
110         //  serve as the connection between documents, frame windows and views.
111
112         CSingleDocTemplate* pDocTemplate;
113         pDocTemplate = new CSingleDocTemplate(
114                 IDR_MAINFRAME,
115                 RUNTIME_CLASS(CHMMDemoDoc),
116                 RUNTIME_CLASS(CMainFrame),       // main SDI frame window
117                 RUNTIME_CLASS(CHMMDemoView));
118         AddDocTemplate(pDocTemplate);
119
120         // Parse command line for standard shell commands, DDE, file open
121         CCommandLineInfo cmdInfo;
122         ParseCommandLine(cmdInfo);
123
124         // Dispatch commands specified on the command line
125         if (!ProcessShellCommand(cmdInfo))
126                 return FALSE;
127     
128         // The one and only window has been initialized, so show and update it.
129         m_pMainWnd->ShowWindow(SW_SHOW);
130         m_pMainWnd->UpdateWindow();
131     
132     m_dlgHMMParams = new CHMMParams;
133     m_dlgSamplingParams = new CSamplingParams;
134     m_dlgMiscParams = new CMiscParams;
135
136     //****************Load Settings (stored in registry)*************************************/
137     CString states_string;  
138     
139     int numbers[8]; //maximum superstates is 7
140
141     //read number of HMM states
142     states_string = GetProfileString( "Settings\\HMM", "NumStates", "5 3 6 6 6 3" );
143     
144     //parse string
145     sscanf( states_string, "%d %d %d %d %d %d %d %d", 
146            &numbers[0], &numbers[1], &numbers[2], &numbers[3],
147            &numbers[4], &numbers[5], &numbers[6], &numbers[7] );
148             
149         
150     m_dlgHMMParams->m_States[0]  = numbers[0];
151     for( int i = 0 ; i < m_dlgHMMParams->m_States[0] ; i++ )
152     {
153         m_dlgHMMParams->m_States[ i + 1 ] = numbers[i+1] ;
154     }
155     
156     //read number of mixtures
157     m_dlgHMMParams->m_NumMix = GetProfileInt("Settings\\HMM", "NumMix", 3 );
158     
159     //read sampling parameters (dctSize, obsSize, delta)
160     
161     m_dlgSamplingParams->m_dctSize.width = GetProfileInt("Settings\\Sampling", "WindowWidth", 12 );
162     m_dlgSamplingParams->m_dctSize.height = GetProfileInt("Settings\\Sampling", "WindowHeight", 12 );
163
164     m_dlgSamplingParams->m_obsSize.width = GetProfileInt("Settings\\Sampling", "DCTCoeffX", 3 );
165     m_dlgSamplingParams->m_obsSize.height = GetProfileInt("Settings\\Sampling", "DCTCoeffY", 3 );
166
167     m_dlgSamplingParams->m_delta.width = GetProfileInt("Settings\\Sampling", "DeltaX", 4 );
168     m_dlgSamplingParams->m_delta.height = GetProfileInt("Settings\\Sampling", "DeltaY", 4 );
169     
170     //read scaling params
171     m_dlgMiscParams->m_useWidth    = GetProfileInt("Settings\\Scaling", "UseFixedWidth", 0 );
172     m_dlgMiscParams->m_FixedWidth  = GetProfileInt("Settings\\Scaling", "FixedWidth", 0 );
173     m_dlgMiscParams->m_useHeight   = GetProfileInt("Settings\\Scaling", "UseFixedHeight", 0 );
174     m_dlgMiscParams->m_FixedHeight = GetProfileInt("Settings\\Scaling", "FixedHeight", 0 );
175    
176     m_dlgMiscParams->m_SuppressIntensity = GetProfileInt("Settings\\Scaling", "SuppressIntensity", 1 );
177    
178     //*******************************End Loading Settings *************************************/
179         
180         return TRUE;
181 }
182
183 void CHMMDemoApp::SaveSettings()
184 {
185     //****************Save Settings into registry)*************************************/
186     CString states_string;
187     
188     //write number of states 
189     states_string.Format("%d",  m_dlgHMMParams->m_States[0] );
190     for( int i = 0 ; i < m_dlgHMMParams->m_States[0] ; i++ )
191     {
192         CString add;
193         add.Format(" %d", m_dlgHMMParams->m_States[ i + 1 ] );
194         states_string+= add;
195     }
196     //write number of HMM states
197     WriteProfileString( "Settings\\HMM", "NumStates", states_string );
198     
199     //write number of mixtures
200     WriteProfileInt("Settings\\HMM", "NumMix", m_dlgHMMParams->m_NumMix );
201     
202     //write sampling parameters (dctSize, obsSize, delta)
203     WriteProfileInt("Settings\\Sampling", "WindowWidth" , m_dlgSamplingParams->m_dctSize.width );
204     WriteProfileInt("Settings\\Sampling", "WindowHeight", m_dlgSamplingParams->m_dctSize.height );
205
206     WriteProfileInt("Settings\\Sampling", "DCTCoeffX", m_dlgSamplingParams->m_obsSize.width );
207     WriteProfileInt("Settings\\Sampling", "DCTCoeffY", m_dlgSamplingParams->m_obsSize.height );
208
209     WriteProfileInt("Settings\\Sampling", "DeltaX", m_dlgSamplingParams->m_delta.width );
210     WriteProfileInt("Settings\\Sampling", "DeltaY", m_dlgSamplingParams->m_delta.height );
211     //*******************************End saving Settings *************************************/
212
213     //write scaling params
214     WriteProfileInt("Settings\\Scaling", "UseFixedWidth" , m_dlgMiscParams->m_useWidth );
215     WriteProfileInt("Settings\\Scaling", "FixedWidth", m_dlgMiscParams->m_FixedWidth );
216
217     WriteProfileInt("Settings\\Scaling", "UseFixedHeight", m_dlgMiscParams->m_useHeight);
218     WriteProfileInt("Settings\\Scaling", "FixedHeight", m_dlgMiscParams->m_FixedHeight );
219
220     WriteProfileInt("Settings\\Scaling", "SuppressIntensity", m_dlgMiscParams->m_SuppressIntensity );
221
222 }
223     
224
225
226
227 /////////////////////////////////////////////////////////////////////////////
228 // CAboutDlg dialog used for App About
229
230 class CAboutDlg : public CDialog
231 {
232 public:
233         CAboutDlg();
234
235 // Dialog Data
236         //{{AFX_DATA(CAboutDlg)
237         enum { IDD = IDD_ABOUTBOX };
238         //}}AFX_DATA
239
240         // ClassWizard generated virtual function overrides
241         //{{AFX_VIRTUAL(CAboutDlg)
242         protected:
243         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
244         //}}AFX_VIRTUAL
245
246 // Implementation
247 protected:
248         //{{AFX_MSG(CAboutDlg)
249                 // No message handlers
250         //}}AFX_MSG
251         DECLARE_MESSAGE_MAP()
252 };
253
254 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
255 {
256         //{{AFX_DATA_INIT(CAboutDlg)
257         //}}AFX_DATA_INIT
258 }
259
260 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
261 {
262         CDialog::DoDataExchange(pDX);
263         //{{AFX_DATA_MAP(CAboutDlg)
264         //}}AFX_DATA_MAP
265 }
266
267 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
268         //{{AFX_MSG_MAP(CAboutDlg)
269                 // No message handlers
270         //}}AFX_MSG_MAP
271 END_MESSAGE_MAP()
272
273 // App command to run the dialog
274 void CHMMDemoApp::OnAppAbout()
275 {
276         CAboutDlg aboutDlg;
277         aboutDlg.DoModal();
278 }
279
280 /////////////////////////////////////////////////////////////////////////////
281 // CHMMDemoApp message handlers
282 // App command to run the dialog
283 void CHMMDemoApp::OnFileOpen()
284 {
285         CFileDialog dlg( TRUE, 0, 0, OFN_ALLOWMULTISELECT | OFN_ENABLESIZING |
286                      OFN_EXPLORER | OFN_FILEMUSTEXIST,
287                      "Face Base Files (*.txt)|*.txt|"
288                      "Image Files (*.bmp;*.jpg;*.jpeg)|*.bmp;*.jpg;*.jpeg|"
289                      "All Files (*.*)|*.*||", 0 );
290     int   buf_size = 1 << 15;
291     char* buffer = (char*)malloc(buf_size + 100);
292
293     dlg.m_ofn.lpstrFile = buffer;
294     buffer[0] = '\0';
295     dlg.m_ofn.nMaxFile = buf_size;
296     int result = dlg.DoModal();
297
298     if( result == IDOK )
299     {
300         POSITION pos = dlg.GetStartPosition();
301
302         if( pos ) /* at least one image in the list */
303         {
304             CHMMDemoView* view = GetCameraView();
305             
306             view->SetImageList(0);          
307             
308             CStringList* imageList = new CStringList;
309
310             while( pos )
311             {
312                 imageList->AddTail( dlg.GetNextPathName(pos));
313             }
314
315             view->SetImageList( imageList );
316             
317             CWinApp::OpenDocumentFile( imageList->GetHead() );
318         }
319     }
320
321     free( buffer );
322 }
323
324
325 void CHMMDemoApp::OnSettings() 
326 {
327         CPropertySheet sheet;
328     sheet.AddPage( m_dlgHMMParams );
329     sheet.AddPage( m_dlgSamplingParams );
330     sheet.AddPage( m_dlgMiscParams );     
331     
332     if(sheet.DoModal() == IDOK)
333     {
334         CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
335         CHMMDemoDoc* doc = mainframe->GetCameraView()->GetDocument();
336         CFaceBase& base = doc->GetFaceBase();
337
338         base.SetParams( m_dlgSamplingParams->m_dctSize, 
339                         m_dlgSamplingParams->m_obsSize,
340                         m_dlgSamplingParams->m_delta,         
341                         m_dlgHMMParams->m_States, 
342                         m_dlgHMMParams->m_NumMix,
343                         m_dlgMiscParams->m_useWidth,
344                         m_dlgMiscParams->m_FixedWidth,
345                         m_dlgMiscParams->m_useHeight, 
346                         m_dlgMiscParams->m_FixedHeight,
347                         m_dlgMiscParams->m_SuppressIntensity);                
348     }
349
350        
351 }
352
353 void CHMMDemoApp::OnSaveConfig() 
354 {
355     CFileDialog dlg( FALSE, 0, 0, /*OFN_ALLOWMULTISELECT | */OFN_ENABLESIZING |
356                      OFN_EXPLORER,
357                      "Config file (*.txt) |*.txt|", 0 );
358     
359
360     if ( dlg.DoModal() == IDOK )
361     {     
362         int res = SaveConfig( dlg.GetFileName()  );
363         ASSERT(res);
364     }         
365 }
366 void CHMMDemoApp::OnLoadConfig() 
367 {
368     CFileDialog dlg( TRUE, 0, 0, /*OFN_ALLOWMULTISELECT | */OFN_ENABLESIZING |
369         OFN_EXPLORER,
370         "Config file (*.txt) |*.txt|", 0 );
371     
372     
373     if ( dlg.DoModal() == IDOK )
374     {   
375         int res = LoadConfig( dlg.GetFileName(), true ); 
376         ASSERT( res );
377         
378     } 
379 }
380
381 int CHMMDemoApp::ExitInstance() 
382 {        
383     SaveSettings();     
384     return CWinApp::ExitInstance();
385 }
386
387 //loads config file without clearing base info
388 int CHMMDemoApp::LoadConfig(const char *filename, bool synchronize_base)
389 {
390     CvSize dctSize, delta, obsSize;
391     char str[128];
392     int value;
393     
394     FILE* file = fopen( filename, "r" );
395     if ( !file ) return 0; 
396     
397     //set initial values
398      m_dlgMiscParams->m_useWidth = FALSE;
399      m_dlgMiscParams->m_FixedWidth = 0;
400      m_dlgMiscParams->m_useHeight = FALSE;
401      m_dlgMiscParams->m_FixedHeight = 0;
402      m_dlgMiscParams->m_SuppressIntensity = FALSE;
403     
404     while ( !feof(file) )
405     {
406         fscanf( file, "%s %d", str, &value );
407         
408         //here we allow config file to be not hard defined
409         //Is it useful? - I don't know
410         if ( strcmp( "WindowWidth", str ) == 0 )
411         {
412             dctSize.width = value;                
413         }
414         else if ( strcmp( "WindowHeight", str ) == 0 )
415         {
416             dctSize.height = value;
417         }
418         else if ( strcmp( "DeltaX", str ) == 0 )
419         {
420             delta.width = value;
421         }
422         else if ( strcmp( "DeltaY", str ) == 0 )
423         {
424             delta.height = value;
425         }
426         else if ( strcmp( "DCTcoeffX", str ) == 0 )
427         {
428             obsSize.width = value;
429         }
430         else if ( strcmp( "DCTcoeffY", str ) == 0 )
431         {
432             obsSize.height = value;
433         }   
434         else if ( strcmp( "SuperStates", str ) == 0 )
435         {
436             m_dlgHMMParams->m_States[0] = value;
437         } 
438         else if ( strcmp( "States", str ) == 0 )
439         {
440             //scan states
441             ASSERT( m_dlgHMMParams->m_States[0] );//superstates must be already loaded
442             m_dlgHMMParams->m_States[1] = value;
443             for(int i = 1; i < m_dlgHMMParams->m_States[0]; i++ )
444             {
445                 fscanf(file, "%d", &m_dlgHMMParams->m_States[i+1] );
446             }
447         }
448         else if ( strcmp( "NumMixtures", str ) == 0 )
449         {
450             m_dlgHMMParams->m_NumMix = value;
451         }               
452         else if ( strcmp( "FIXED_WIDTH", str ) == 0 )
453         {
454             m_dlgMiscParams->m_useWidth = TRUE;
455             m_dlgMiscParams->m_FixedWidth = value;
456         }   
457         else if ( strcmp( "FIXED_HEIGHT", str ) == 0 )
458         {
459             m_dlgMiscParams->m_useHeight = TRUE;
460             m_dlgMiscParams->m_FixedHeight = value;
461         }
462         else if ( strcmp( "SUPPRESS_INTENSITY", str ) == 0 )
463         {
464             m_dlgMiscParams->m_SuppressIntensity = TRUE;
465         }   
466         else
467         {
468             //do nothing
469         }
470     }
471     
472     //check correctness of loaded file
473     if ( (dctSize.width < obsSize.width)||
474         (dctSize.height < obsSize.height) )
475     {
476         //error message 
477         DoMessageBox( "Wrong parameters in config file\nNew parameters were not loaded", MB_OK|MB_ICONSTOP, 0 );
478     }
479     
480     //initialize application variables
481     m_dlgSamplingParams->m_dctSize = dctSize;
482     m_dlgSamplingParams->m_obsSize = obsSize;
483     m_dlgSamplingParams->m_delta = delta;  
484     
485     fclose( file ); 
486     
487     if (synchronize_base)
488     {
489         CMainFrame* mainframe = (CMainFrame*)AfxGetMainWnd();
490         CHMMDemoDoc* doc = mainframe->GetCameraView()->GetDocument();
491         CFaceBase& base = doc->GetFaceBase();
492
493         return base.SetParams( //sampling params
494                                 m_dlgSamplingParams->m_dctSize, 
495                                 m_dlgSamplingParams->m_obsSize, 
496                                 m_dlgSamplingParams->m_delta,
497                                 //HMM params
498                                 m_dlgHMMParams->m_States, 
499                                 m_dlgHMMParams->m_NumMix,
500                                 //image scaling params
501                                 m_dlgMiscParams->m_useWidth,
502                                 m_dlgMiscParams->m_FixedWidth,
503                                 m_dlgMiscParams->m_useHeight, 
504                                 m_dlgMiscParams->m_FixedHeight,
505                                 //intensity suppression
506                                 m_dlgMiscParams->m_SuppressIntensity, 1 );
507     }
508     return 1;
509 }
510 int CHMMDemoApp::SaveConfig(const char* filename) 
511 {
512         FILE* file = fopen( filename, "wt" );
513         if (!file) { ASSERT(0); return 0; }
514
515         fprintf( file, "***********Sampling params************\n" );
516         fprintf( file, "WindowWidth  %d\n" ,  m_dlgSamplingParams->m_dctSize.width );
517         fprintf( file, "WindowHeight %d\n",  m_dlgSamplingParams->m_dctSize.height );
518         fprintf( file, "DeltaX %d\n" , m_dlgSamplingParams->m_delta.width );
519         fprintf( file, "DeltaY %d\n",    m_dlgSamplingParams->m_delta.height );
520         fprintf( file, "DCTcoeffX %d\n" , m_dlgSamplingParams->m_obsSize.width );
521         fprintf( file, "DCTcoeffY %d\n",  m_dlgSamplingParams->m_obsSize.height ); 
522
523         fprintf( file, "***************HMM params*************\n" );
524         fprintf( file, "SuperStates %d\n",    m_dlgHMMParams->m_States[0] );
525         fprintf( file, "States");
526         for( int i = 0; i < m_dlgHMMParams->m_States[0]; i++ )
527         {
528             fprintf( file, " %d", m_dlgHMMParams->m_States[i+1] );
529         }
530         fprintf( file, "\n" );
531         fprintf( file, "NumMixtures %d\n", m_dlgHMMParams->m_NumMix );
532
533         fprintf( file, "***************Misc. params*************\n" );
534         if( m_dlgMiscParams->m_useWidth )
535             fprintf( file, "FIXED_WIDTH %d\n", m_dlgMiscParams->m_FixedWidth );
536         if( m_dlgMiscParams->m_useHeight )
537             fprintf( file, "FIXED_HEIGHT %d\n", m_dlgMiscParams->m_FixedHeight );
538         if( m_dlgMiscParams->m_SuppressIntensity )
539             fprintf( file, "SUPPRESS_INTENSITY %d\n", m_dlgMiscParams->m_SuppressIntensity );
540         
541         fclose( file );
542    return 1;
543 }