Update the changelog
[opencv] / apps / HMMDemo / MainFrm.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*/// MainFrm.cpp : implementation of the CMainFrame class
41 //
42
43 #include "stdafx.h"
44 #include "HMMDemo.h"
45
46 #include "MainFrm.h"
47 #include "HMMDemoDoc.h"
48
49 #ifdef _DEBUG
50 #define new DEBUG_NEW
51 #undef THIS_FILE
52 static char THIS_FILE[] = __FILE__;
53 #endif
54
55 /////////////////////////////////////////////////////////////////////////////
56 // CMainFrame
57
58 IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
59
60 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
61     //{{AFX_MSG_MAP(CMainFrame)
62     ON_WM_CREATE()
63     ON_UPDATE_COMMAND_UI(ID_CAPTURE, OnUpdateCapture)
64     ON_COMMAND(ID_CAPTURE, OnCapture)
65     ON_UPDATE_COMMAND_UI(ID_CAPOPTIONS, OnUpdateCapOptions)
66     ON_COMMAND(ID_CAPOPTIONS, OnCapOptions)
67     ON_UPDATE_COMMAND_UI(ID_CAPFORMAT, OnUpdateCapFormat)
68     ON_COMMAND(ID_CAPFORMAT, OnCapFormat)
69     ON_COMMAND(ID_ADD_OBJ, OnAddObj)
70     ON_UPDATE_COMMAND_UI(ID_ADD_OBJ, OnUpdateAddObj)
71     ON_COMMAND(ID_REMOVE_OBJ, OnRemoveObj)
72     ON_UPDATE_COMMAND_UI(ID_REMOVE_OBJ, OnUpdateRemoveObj)
73         ON_COMMAND(ID_ZOOMIN, OnZoomIn)
74     ON_COMMAND(ID_ZOOMOUT, OnZoomOut)
75         ON_COMMAND(ID_SETINFO, OnChangeBaseParams)
76         ON_COMMAND(ID_TRAIN, OnTrain)
77     ON_UPDATE_COMMAND_UI(ID_TRAIN, OnUpdateTrain)
78         ON_COMMAND(ID_RECOG, OnRecognize)
79         ON_UPDATE_COMMAND_UI(ID_RECOG, OnUpdateRecog)
80         ON_COMMAND(ID_SELECTALL, OnSelectAll)
81         ON_COMMAND(ID_DEL_HMM, OnDelHmm)
82         ON_COMMAND(ID_ADD_TEST, OnAddTest)
83         ON_UPDATE_COMMAND_UI(ID_ADD_TEST, OnUpdateAddTest)
84         ON_COMMAND(ID_TEST_FOLDER, OnTestFolder)
85         ON_COMMAND(ID_RECOBASE, OnRecobase)
86         ON_UPDATE_COMMAND_UI(ID_RECOBASE, OnUpdateRecobase)
87         ON_COMMAND(ID_SETTINGS, OnSettings)
88         //}}AFX_MSG_MAP
89 END_MESSAGE_MAP()
90
91 static UINT indicators[] =
92 {
93         ID_SEPARATOR,           // status line indicator
94         ID_INDICATOR_CAPS,
95         ID_INDICATOR_NUM,
96         ID_INDICATOR_SCRL,
97 };
98
99 /////////////////////////////////////////////////////////////////////////////
100 // CMainFrame construction/destruction
101
102 CMainFrame::CMainFrame()
103 {
104     m_busy = FALSE;
105 }
106
107 CMainFrame::~CMainFrame()
108 {
109 }
110
111 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
112 {
113     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
114         return -1;
115
116     if( !m_wndToolBar.CreateEx(this) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
117         return -1;
118
119     if( !m_wndReBar.Create(this) ||
120         !m_wndReBar.AddBar(&m_wndToolBar))
121         return -1;
122
123     if (!m_wndStatusBar.Create(this) ||
124         !m_wndStatusBar.SetIndicators(indicators,
125         sizeof(indicators)/sizeof(UINT)))
126         return -1;
127     
128     m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
129         CBRS_TOOLTIPS | CBRS_FLYBY);
130
131     return 0;
132 }
133
134
135 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
136                                 CCreateContext* pContext)
137 {
138     m_wndSplitter.CreateStatic(this,1,2);
139     
140     m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CImageBaseView),CSize(300,100),pContext);
141     m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CHMMDemoView),CSize(300,100),pContext);
142 //    m_wndSplitter.CreateView(0,2,RUNTIME_CLASS(CTestImageBaseView),CSize(300,100),pContext);
143    
144     return TRUE;
145 }
146
147 BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
148 {
149         if( !CFrameWnd::PreCreateWindow(cs) )
150                 return FALSE;
151
152         return TRUE;
153 }
154
155 CImageBaseView* CMainFrame::GetImageBaseView()
156 {
157     return (CImageBaseView*)m_wndSplitter.GetPane(0,0);
158 }
159
160 CHMMDemoView* CMainFrame::GetCameraView()
161 {
162     return (CHMMDemoView*)m_wndSplitter.GetPane(0,1);
163 }
164
165
166 void CMainFrame::OnUpdateCapture(CCmdUI* pCmdUI) 
167 {
168     CHMMDemoView* view = GetCameraView();
169     bool enable = false;
170     bool press = false;
171
172     if( view )
173     {
174         enable = view->Camera().IsInitialized();
175         press = view->Camera().IsRunning();
176     }
177
178     pCmdUI->Enable( enable );
179     pCmdUI->SetCheck( press );
180 }
181
182 void CMainFrame::OnCapture() 
183 {
184     CHMMDemoView* view = GetCameraView();
185
186     if( view && view->Camera().IsInitialized())
187     {
188         if( view->Camera().IsRunning())
189         {
190             view->Camera().Stop();
191         }
192         else
193         {
194             view->SetImageList(0);
195             view->Camera().Start();
196         }
197     }    
198 }
199
200 void CMainFrame::OnUpdateCapOptions(CCmdUI* pCmdUI) 
201 {
202     CHMMDemoView* view = GetCameraView();
203     pCmdUI->Enable( view != 0 );
204 }
205
206 void CMainFrame::OnCapOptions() 
207 {
208     CHMMDemoView* view = GetCameraView();
209
210     if( view )
211     {
212         view->Camera().VideoSourceDlg();
213         view->InvalidateRect(0);
214     }
215 }
216
217 void CMainFrame::OnUpdateCapFormat(CCmdUI* pCmdUI) 
218 {
219     CHMMDemoView* view = GetCameraView();
220     pCmdUI->Enable( view != 0 );
221 }
222
223 void CMainFrame::OnCapFormat() 
224 {
225         CHMMDemoView* view = GetCameraView();
226
227     if( view )
228     {
229         view->Camera().VideoFormatDlg();
230         view->InvalidateRect(0);
231     }
232 }
233
234
235 void CMainFrame::OnUpdateAddObj(CCmdUI* pCmdUI) 
236 {
237     CHMMDemoView* view = GetCameraView();
238     bool enable = false;
239
240     if( view )
241     {
242         enable = !view->GetSelection().IsRectEmpty();
243     }
244     pCmdUI->Enable( enable );
245 }
246
247
248 void CMainFrame::OnAddObj() 
249 {
250     CHMMDemoView* view = GetCameraView();
251     CHMMDemoDoc* doc = GetHMMDoc();
252
253     if( view && doc )
254     {
255         CCamera& camera = view->Camera();
256         camera.Stop();
257         doc->AddObj( camera.GetFrame(), view->GetSelection(), view->GetImageList() );
258         camera.Start();
259     }
260 }
261
262 //try to write new file to directory 
263 CString GetFreeFilename( CString folder, CString base_name )
264 {   
265     int i = 0;
266     CString full_name;
267     
268     for(;;)
269     {
270         FILE* f = 0;
271         for( ; i < 10000; i++ )
272         {     
273             
274             //GetPersonFullImageName( m_folder, m_folder.GetLength(), filename, path );
275             full_name.Format( "%s\\%s%04d.bmp", folder, base_name, i );
276             f = fopen( full_name, "rb" );
277             if( !f ) break;
278             fclose(f);
279         }
280         if( i == 10000 )
281         {
282             ASSERT(0); //so many images already exist
283             return CString("");
284         }
285         
286         // try to open for writing. If success, output name
287         f = fopen( full_name, "wb" );
288         if( !f ) continue;
289         
290         fclose(f);
291         remove( full_name );
292         break;
293     }
294     
295     return full_name;
296 }
297
298
299 void CMainFrame::OnAddTest() 
300 {       
301     CHMMDemoView* camera_view = GetCameraView();
302     CImageBaseView* view = GetImageBaseView();
303     CHMMDemoDoc* doc = GetHMMDoc();
304
305     if( view && doc )
306     {
307         CRect m_sel = camera_view->GetSelection();
308         CCamera& camera = camera_view->Camera();
309
310         camera.Stop();
311         
312         //get selected person name
313         CPerson* person = doc->GetFaceBase().GetPerson( view->GetPersonIndex() );
314         CString name = person->GetName();
315
316         //add image which is in view
317         CString filename = GetFreeFilename( camera_view->GetTestPath(), name );
318         CImage new_img;
319         new_img.CopyOf( camera.GetFrame() );
320         IplImage* iplimage = new_img.GetImage();
321
322         if( !iplimage )
323         {
324             MessageBox("No image was selected!");
325             return;
326         }
327         
328         cvSetImageROI( iplimage, RectToCvRect( m_sel ));
329         CImage tofile;
330         tofile.CopyOf( iplimage );
331         tofile.Save( filename );
332         
333         //add other images
334         CStringList* imageList = camera_view->GetImageList();
335
336         if ( imageList && (imageList->GetCount() > 1) )
337         {
338             //add batch
339             POSITION pos = imageList->GetHeadPosition();
340             imageList->GetNext( pos );
341                         
342             while (pos)
343             {
344                 CImage img;
345                 img.Load( imageList->GetNext( pos ), 1 );
346                 
347                 
348                 img.Save( GetFreeFilename( camera_view->GetTestPath(), name ) );
349             }
350         }
351         MessageBox("Images were added to test base");
352
353         camera.Start();
354
355     }
356     return;
357
358 }
359
360
361 void CMainFrame::OnUpdateRemoveObj(CCmdUI* pCmdUI) 
362 {
363     CImageBaseView* view = GetImageBaseView();
364     bool enable = false;
365
366     if( view )
367     {
368         enable = view->GetActive() >= 0;
369     }
370     pCmdUI->Enable( enable );
371 }
372
373 void CMainFrame::OnRemoveObj() 
374 {
375     CImageBaseView* view = GetImageBaseView();
376     CHMMDemoDoc* doc = GetHMMDoc();
377
378     if( doc && view )
379     {
380         int active = view->GetActive();
381         int person_index = view->GetPersonIndex();
382
383         if( active >= 0 )
384         {
385             if( doc->RemoveObj( person_index, active ))
386             {
387                 view->ResetActive();
388                 view->RefreshView();
389             }
390         }
391     }
392 }
393
394
395 void CMainFrame::OnZoomIn() 
396 {
397     CImageBaseView* view = GetImageBaseView();
398     view->Zoom();
399 }
400
401
402 void CMainFrame::OnZoomOut() 
403 {
404     CImageBaseView* view = GetImageBaseView();
405     view->Zoom( false );
406 }
407
408
409 void CMainFrame::OnChangeBaseParams() 
410 {
411     CHMMDemoDoc* doc = GetHMMDoc();
412
413     if( doc )
414     {
415         doc->ChangeBaseParams();
416     }
417 }
418
419 void CMainFrame::OnTrain() 
420 {
421     CWaitCursor wait;
422         //if 1 person selected - train its HMM
423     //if all base in view - train all untrained persons
424     CHMMDemoDoc* doc = GetHMMDoc();
425     CImageBaseView* base_view = GetImageBaseView();
426                                
427     if( doc && base_view )
428     {
429         //int view_mode = base_view->GetMode();
430         CFaceBase& base = doc->GetFaceBase();
431         
432         if( base_view->GetPersonIndex() >= 0 )
433         {
434             base.TrainPerson( base_view->GetPersonIndex(), true );
435         }
436         else
437             base.TrainAll( TRAIN_UNTRAINED ); 
438     } 
439 }
440
441 void CMainFrame::OnRecognize() 
442 {         
443     CWaitCursor wait;
444         CHMMDemoView* view = GetCameraView();
445     CHMMDemoDoc* doc = GetHMMDoc();
446     CImageBaseView* baseview = GetImageBaseView();
447     
448     if( doc && view && baseview )
449     {
450         CFaceBase& base = doc->GetFaceBase();
451         CCamera& camera = view->Camera();
452         camera.Stop();
453         
454         if (view->GetSelection().IsRectEmpty() )
455         {
456             MessageBox( "Specify face region", NULL, MB_ICONERROR );
457             return;  
458         }            
459
460         //decide if single recognition or batch mode
461         CStringList* image_list = view->GetImageList();
462         if ( image_list && (image_list->GetCount() > 1) )
463         {   
464             //perform batch recognition
465             int result = base.RecognizeBatch( image_list );
466         }
467         else
468         {
469             int ranged[3];
470             int result = base.RecognizePerson( camera.GetFrame(), view->GetSelection(), 
471                                                ranged );
472
473             if( result == 0 ) 
474             {
475                  MessageBox( "Not all persons are trained", NULL, MB_ICONERROR );
476             }
477             else
478             {   
479                 CString message = "";
480                 for( int i = 0 ; i < result; i++ )
481                 {
482                     CPerson* person = base.GetPerson( ranged[i]);
483                     message += person->GetName() + "\n";
484                 }
485
486                 baseview->SwitchMode(ranged[0], false);
487                 MessageBox( (LPCTSTR)message, NULL, MB_ICONEXCLAMATION  );
488              
489             }
490         }
491     }                                      
492 }
493
494 void CMainFrame::OnUpdateRecog(CCmdUI* pCmdUI) 
495 {
496     CHMMDemoView* view = GetCameraView();
497     CRect rect = view->GetSelection();
498     
499         pCmdUI->Enable( rect.Width() && rect.Height() );
500     
501 }
502
503 void CMainFrame::OnUpdateTrain(CCmdUI* pCmdUI) 
504 {
505     CImageBaseView* view = GetImageBaseView();
506     bool enable = false;
507
508     if( view )
509     {
510         //int person_index = view->GetPersonIndex();
511         CHMMDemoDoc* doc = GetHMMDoc();
512         int num_person = doc->GetFaceBase().GetPersonList().GetCount();
513         if( doc && num_person >= 0 )
514         {
515             enable = true;
516             //CFaceBase& base = doc->GetFaceBase();
517             //CPerson* person = base.GetPerson(person_index);
518             //enable = person && person->GetImgList().GetCount() > 0;
519         }
520     }
521
522     pCmdUI->Enable( enable );
523 }
524
525
526 void CMainFrame::OnSelectAll() 
527 {
528     CHMMDemoView* view = GetCameraView();
529     
530     if( view )
531     {
532         view->SetSelection(0);
533     }
534 }
535
536 void CMainFrame::OnDelHmm() 
537 {
538     CHMMDemoDoc* doc = GetHMMDoc();
539     CImageBaseView* view = GetImageBaseView();
540
541     if( doc && view )
542     {
543         int person_index = view->GetPersonIndex();
544         int result = MessageBox( person_index >= 0 ? "Delete HMM info for current person?" :
545                                  "Delete HMM info for the whole base?", "",
546                                  MB_YESNO | MB_ICONQUESTION );    
547         if( result == IDYES ) doc->DeleteHMMInfo( person_index );
548     }
549 }
550
551
552 void CMainFrame::OnUpdateAddTest(CCmdUI* pCmdUI) 
553 {
554     CImageBaseView* view = GetImageBaseView();
555     CHMMDemoView* camera_view = GetCameraView();
556     
557     if( view )
558     {
559         int person_index = view->GetPersonIndex();
560         CString path = camera_view->GetTestPath();
561
562         pCmdUI->Enable( (person_index >= 0) && (!path.IsEmpty()) );        
563     }
564 }
565
566 void CMainFrame::OnTestFolder() 
567 {
568          CHMMDemoView* view = GetCameraView();
569     
570     char buffer[1024];
571
572     BROWSEINFO bi;
573     bi.hwndOwner = NULL; 
574     bi.pidlRoot =NULL; 
575     bi.pszDisplayName = buffer; 
576     bi.lpszTitle = "Choose directory for test images" ; 
577     bi.ulFlags = 0; 
578     bi.lpfn = NULL; 
579     bi.lParam = 0; 
580     
581     LPITEMIDLIST il = SHBrowseForFolder( &bi );
582
583     char path[1024];
584
585     if ( SHGetPathFromIDList( il, path ) )    
586     if( view )
587     {
588         view->SetTestPath( path );
589     }   
590 }
591
592 void CMainFrame::OnRecobase() 
593 {
594     CImageBaseView* base_view = GetImageBaseView();
595     CFaceBase& original_base = base_view->GetDocument()->GetFaceBase();
596
597     CFileDialog dlg( TRUE, 0, 0, OFN_ENABLESIZING |
598                      OFN_EXPLORER | OFN_FILEMUSTEXIST,
599                      "Face Base Files (*.txt)|*.txt|", 0 );
600     int   buf_size = 1 << 15;
601     char* buffer = (char*)malloc(buf_size + 100);
602
603     dlg.m_ofn.lpstrFile = buffer;
604     buffer[0] = '\0';
605     dlg.m_ofn.nMaxFile = buf_size;
606     int result = dlg.DoModal();
607
608     if( result == IDOK )
609     {
610         CWaitCursor wait;
611         CFaceBase base;
612         base.SetFileName( dlg.GetFileName() );
613         base.Load();
614     
615         //recognize 
616
617         original_base.RecognizeOtherBase( &base );
618     }
619 }
620
621 void CMainFrame::OnUpdateRecobase(CCmdUI* pCmdUI) 
622 {
623         // TODO: Add your command update UI handler code here
624     CImageBaseView* base_view = GetImageBaseView();
625     CFaceBase& base = base_view->GetDocument()->GetFaceBase();
626     POSITION pos = base.GetPersonList().GetHeadPosition();
627     while( pos )
628     {
629         CPerson* pers = base.GetPersonList().GetNext(pos);
630         if( !pers->IsTrained() ) { pCmdUI->Enable(FALSE); return; }
631     }
632     pCmdUI->Enable(TRUE);       
633 }
634
635 void CMainFrame::OnSettings() 
636 {
637         CHMMDemoApp* app = (CHMMDemoApp*)AfxGetApp();
638     app->OnSettings();// TODO: Add your command handler code here
639         
640 }