Update the changelog
[opencv] / apps / StereoGR / StereoGR.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.\r
4 //\r
5 //  By downloading, copying, installing or using the software you agree to this license.\r
6 //  If you do not agree to this license, do not download, install,\r
7 //  copy or use the software.\r
8 //\r
9 //\r
10 //                        Intel License Agreement\r
11 //                For Open Source Computer Vision Library\r
12 //\r
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.\r
14 // Third party copyrights are property of their respective owners.\r
15 //\r
16 // Redistribution and use in source and binary forms, with or without modification,\r
17 // are permitted provided that the following conditions are met:\r
18 //\r
19 //   * Redistribution's of source code must retain the above copyright notice,\r
20 //     this list of conditions and the following disclaimer.\r
21 //\r
22 //   * Redistribution's in binary form must reproduce the above copyright notice,\r
23 //     this list of conditions and the following disclaimer in the documentation\r
24 //     and/or other materials provided with the distribution.\r
25 //\r
26 //   * The name of Intel Corporation may not be used to endorse or promote products\r
27 //     derived from this software without specific prior written permission.\r
28 //\r
29 // This software is provided by the copyright holders and contributors "as is" and\r
30 // any express or implied warranties, including, but not limited to, the implied\r
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.\r
32 // In no event shall the Intel Corporation or contributors be liable for any direct,\r
33 // indirect, incidental, special, exemplary, or consequential damages\r
34 // (including, but not limited to, procurement of substitute goods or services;\r
35 // loss of use, data, or profits; or business interruption) however caused\r
36 // and on any theory of liability, whether in contract, strict liability,\r
37 // or tort (including negligence or otherwise) arising in any way out of\r
38 // the use of this software, even if advised of the possibility of such damage.\r
39 //\r
40 //M*/// StereoGR.cpp : Defines the class behaviors for the application.\r
41 //\r
42 \r
43 #include "stdafx.h"\r
44 #include "StereoGR.h"\r
45 \r
46 #include "MainFrm.h"\r
47 #include "ChildFrm.h"\r
48 #include "StereoGRDoc.h"\r
49 #include "StereoGRView.h"\r
50 #include "PTOffline.h"\r
51 #include "PTOptions.h"\r
52 #include "HMMParams.h" \r
53 #include "float.h"\r
54 #include "direct.h"\r
55 #include <io.h>\r
56 \r
57 #include <digiclops.h>\r
58 #include <triclops.h>\r
59 #include "PGControl.h"\r
60 \r
61 \r
62 #ifdef _DEBUG\r
63 #define new DEBUG_NEW\r
64 #undef THIS_FILE\r
65 static char THIS_FILE[] = __FILE__;\r
66 #endif\r
67 \r
68 /////////////////////////////////////////////////////////////////////////////\r
69 // CStereoGRApp\r
70 \r
71 BEGIN_MESSAGE_MAP(CStereoGRApp, CWinApp)\r
72         //{{AFX_MSG_MAP(CStereoGRApp)\r
73         ON_COMMAND(ID_APP_ABOUT, OnAppAbout)\r
74         ON_COMMAND(ID_FILE_NEW, OnFileNew)\r
75         ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateFileNew)\r
76         ON_COMMAND(ID_PT_PROP, OnPtProp)\r
77         ON_COMMAND(ID_PT_WHITEBALANCE, OnPtWhitebalance)\r
78         ON_COMMAND(ID_PTOFFLINE, OnPtoffline)\r
79         ON_COMMAND(ID_CAPTURE_BACK, OnCaptureBack)\r
80         ON_COMMAND(ID_RUNGESTREC, OnRungestrec)\r
81         ON_COMMAND(ID_SETTINGS, OnSettings)\r
82         ON_COMMAND(ID_TRAIN, OnTrain)\r
83         ON_COMMAND(ID_SAVE_DGPARAMS, OnSaveDynamicGestures)\r
84         ON_COMMAND(ID_LOAD_DGPARAMS, OnLoadDynamicGestures)\r
85         ON_COMMAND(ID_SAVE_BASE, OnSaveBase)\r
86         ON_COMMAND(ID_LOAD_BASE, OnLoadBase)\r
87         ON_COMMAND(ID_RECOG_FILE_DG, OnRecogFileDg)\r
88         ON_COMMAND(ID_DELETE_HMM, OnDeleteHmm)\r
89         ON_COMMAND(ID_REMOVE_ALL_DG, OnRemoveAllDg)\r
90         ON_UPDATE_COMMAND_UI(ID_RUNGESTREC, OnUpdateRungestrec)\r
91         //}}AFX_MSG_MAP\r
92         // Standard file based document commands\r
93         ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)\r
94         ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)\r
95         // Standard print setup command\r
96         ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)\r
97 END_MESSAGE_MAP()\r
98 \r
99 IPLStatus __stdcall _iplErrorHandler(IPLStatus status, const char* func, const char* context, \r
100                             const char* file, int line);\r
101 \r
102 /////////////////////////////////////////////////////////////////////////////\r
103 // CStereoGRApp construction\r
104 \r
105 CStereoGRApp::CStereoGRApp()\r
106 {\r
107     InitModulePath();\r
108     memset(m_viewIds, 0, sizeof(m_viewIds));\r
109     memset(m_views, 0, sizeof(m_viewIds));\r
110 \r
111     // Initialize IPL\r
112     iplRedirectError(_iplErrorHandler);\r
113 \r
114    \r
115     m_findHand.m_dynamicGesture = 0;//m_dgProp->IsSaveToFile();\r
116     m_findHand.m_path = m_modulePath;\r
117     m_findHand.m_dGestureName = "";//m_dgProp->GetGestureName();\r
118 \r
119     m_ptOptions = 0;\r
120     m_grOptions = 0;\r
121     m_hmmParams = 0;\r
122     m_dgStat    = 0;\r
123 \r
124     m_doRecog = FALSE;\r
125 \r
126         POINT p = {-1, -1};\r
127         for(int i = 0; i < VIEWS_COUNT; i++)\r
128         {\r
129                 m_TopLefts.push_back(p);\r
130                 m_TopLefts3D.push_back(p);\r
131         }\r
132 \r
133         m_isClosingView = FALSE;        \r
134 }\r
135 \r
136 CStereoGRApp::~CStereoGRApp()\r
137 {\r
138     delete m_ptOptions;\r
139     delete m_grOptions;\r
140     delete m_hmmParams;\r
141     delete m_dgStat;\r
142         delete m_dgProp;\r
143 }\r
144 \r
145 /////////////////////////////////////////////////////////////////////////////\r
146 // The one and only CStereoGRApp object\r
147 \r
148 CStereoGRApp theApp;\r
149 \r
150 /////////////////////////////////////////////////////////////////////////////\r
151 // CStereoGRApp initialization\r
152 \r
153 BOOL CStereoGRApp::InitInstance()\r
154 {\r
155         AfxEnableControlContainer();\r
156 \r
157         // Standard initialization\r
158         // If you are not using these features and wish to reduce the size\r
159         //  of your final executable, you should remove from the following\r
160         //  the specific initialization routines you do not need.\r
161 \r
162 #ifdef _AFXDLL\r
163         Enable3dControls();                     // Call this when using MFC in a shared DLL\r
164 #else\r
165         Enable3dControlsStatic();       // Call this when linking to MFC statically\r
166 #endif\r
167 \r
168         // Change the registry key under which our settings are stored.\r
169         // TODO: You should modify this string to be something appropriate\r
170         // such as the name of your company or organization.\r
171         SetRegistryKey(_T("Local AppWizard-Generated Applications"));\r
172 \r
173         LoadStdProfileSettings();  // Load standard INI file options (including MRU)\r
174 \r
175         // Register the application's document templates.  Document templates\r
176         //  serve as the connection between documents, frame windows and views.\r
177 \r
178         CMultiDocTemplate* pDocTemplate;\r
179         pDocTemplate = new CMultiDocTemplate(\r
180                 IDR_STEREOTYPE,\r
181                 RUNTIME_CLASS(CStereoGRDoc),\r
182                 RUNTIME_CLASS(CChildFrame), // custom MDI child frame\r
183                 RUNTIME_CLASS(CStereoGRView));\r
184         AddDocTemplate(pDocTemplate);\r
185 \r
186         // create main MDI Frame window\r
187         CMainFrame* pMainFrame = new CMainFrame;\r
188         if (!pMainFrame->LoadFrame(IDR_MAINFRAME))\r
189                 return FALSE;\r
190         m_pMainWnd = pMainFrame;\r
191 \r
192         // The main window has been initialized, so show and update it.\r
193         pMainFrame->ShowWindow(m_nCmdShow);\r
194         pMainFrame->UpdateWindow();\r
195 \r
196     CStatusBar* bar = pMainFrame->GetStatusBar();\r
197     bar->SetPaneText(0, "Initializing the camera...");\r
198     // Initialize the camera\r
199         CString config;\r
200         while(1)\r
201         {\r
202                 config = GetProfileString("Settings\\PTGrey", "Config");\r
203                 _finddata_t filedata;\r
204                 if(config.IsEmpty() || _findfirst(LPCTSTR(config), &filedata) == -1)\r
205                 {\r
206                         CFileDialog dlg(TRUE, "", "config");\r
207                         AfxMessageBox("For the first run please enter the name of \nthe configuration file of your PointGrey camera.");\r
208                         if(dlg.DoModal() != IDOK)\r
209                         {\r
210                                 AfxMessageBox("The configuration file is required for stereo processing.\nPlease contact your camera supplier to obtain the file for your camera.");\r
211                                 return FALSE;\r
212                         }\r
213 \r
214                         WriteProfileString("Settings\\PTGrey", "Config", LPCTSTR(dlg.GetPathName()));\r
215                 }\r
216                 else\r
217                 {\r
218                         break;\r
219                 }\r
220         }\r
221         PTGreySetConfigFileName(LPCTSTR(config));\r
222         \r
223     int rawres = 0, stereores = 0;\r
224     rawres = GetProfileInt("Settings\\PTGrey", "Raw resolution", rawres);\r
225     PTGreySetProperty("RawResolution", &rawres);\r
226     stereores = GetProfileInt("Settings\\PTGrey", "Stereo resolution", stereores);\r
227     PTGreySetProperty("StereoResolution", &stereores);\r
228     BOOL ret = PTGreyInitCamera();\r
229     if(!ret)\r
230     {\r
231         AfxMessageBox(PTGreyGetErrorMessage());\r
232                 return FALSE;\r
233     }\r
234     else\r
235         {\r
236                 // Load camera and application settings\r
237         LoadSettings();\r
238         }\r
239 \r
240         // Automatically capture background\r
241         OnCaptureBack();\r
242 \r
243     //set hmm parameters \r
244     m_dgServer.SetHMMParams( m_hmmParams->m_num_states, m_hmmParams->m_num_mix );\r
245 \r
246         // Assign an affinity mask to the current thread\r
247     int e = SetThreadAffinityMask(GetCurrentThread(), 1);\r
248 \r
249     bar->SetPaneText(0, "Ready");\r
250     return TRUE;\r
251 }\r
252 \r
253 \r
254 /////////////////////////////////////////////////////////////////////////////\r
255 // CAboutDlg dialog used for App About\r
256 \r
257 class CAboutDlg : public CDialog\r
258 {\r
259 public:\r
260         CAboutDlg();\r
261 \r
262 // Dialog Data\r
263         //{{AFX_DATA(CAboutDlg)\r
264         enum { IDD = IDD_ABOUTBOX };\r
265         //}}AFX_DATA\r
266 \r
267         // ClassWizard generated virtual function overrides\r
268         //{{AFX_VIRTUAL(CAboutDlg)\r
269         protected:\r
270         virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support\r
271         //}}AFX_VIRTUAL\r
272 \r
273 // Implementation\r
274 protected:\r
275         //{{AFX_MSG(CAboutDlg)\r
276                 // No message handlers\r
277         //}}AFX_MSG\r
278         DECLARE_MESSAGE_MAP()\r
279 };\r
280 \r
281 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)\r
282 {\r
283         //{{AFX_DATA_INIT(CAboutDlg)\r
284         //}}AFX_DATA_INIT\r
285 }\r
286 \r
287 void CAboutDlg::DoDataExchange(CDataExchange* pDX)\r
288 {\r
289         CDialog::DoDataExchange(pDX);\r
290         //{{AFX_DATA_MAP(CAboutDlg)\r
291         //}}AFX_DATA_MAP\r
292 }\r
293 \r
294 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)\r
295         //{{AFX_MSG_MAP(CAboutDlg)\r
296                 // No message handlers\r
297         //}}AFX_MSG_MAP\r
298 END_MESSAGE_MAP()\r
299 \r
300 // App command to run the dialog\r
301 void CStereoGRApp::OnAppAbout()\r
302 {\r
303         CAboutDlg aboutDlg;\r
304         aboutDlg.DoModal();\r
305 }\r
306 \r
307 /////////////////////////////////////////////////////////////////////////////\r
308 // CStereoGRApp message handlers\r
309 \r
310 \r
311 int CStereoGRApp::GetDocType()\r
312 {\r
313     return m_docType;\r
314 }\r
315 \r
316 void CStereoGRApp::OnFileNew() \r
317 {\r
318     if(m_docType >= VIEWS_COUNT)\r
319         return;\r
320     \r
321     CWinApp::OnFileNew();\r
322     m_docType++;\r
323 }\r
324 \r
325 void CStereoGRApp::OnUpdateFileNew(CCmdUI* pCmdUI) \r
326 {\r
327     pCmdUI->Enable(m_docType < PG_IMAGE_MAX);   \r
328 }\r
329 \r
330 void CStereoGRApp::SetDocType(int docType)\r
331 {\r
332     m_docType = docType;\r
333 }\r
334 \r
335 void CStereoGRApp::OnPtProp() \r
336 {\r
337     PTGreyShowPropertyPage();\r
338 }\r
339 \r
340 void CStereoGRApp::OnPtWhitebalance() \r
341 {\r
342     PTGreyShowWhiteBalance();\r
343 }\r
344 \r
345 void CStereoGRApp::OnPtoffline() \r
346 {\r
347     CStatusBar* bar = ((CMainFrame*)AfxGetMainWnd())->GetStatusBar();\r
348     CPTOffline dlg;\r
349     dlg.m_strSaveFile = m_modulePath;\r
350     dlg.SetFramesCount(30);\r
351     if(dlg.DoModal() == IDOK)\r
352     {\r
353         int framesCount = dlg.GetFrameCount();\r
354         // Start collecting frames...\r
355         PTGreySetTriclopsInputBuffer(framesCount);\r
356         while(1)\r
357         {\r
358             int count = PTGreyGetFrameNumber();\r
359             if(count < 0)\r
360                 // Finished collecting frames\r
361                 break;\r
362 \r
363             CString str;\r
364             str.Format("Collected frame %d of %d...", count, framesCount);\r
365             bar->SetPaneText(0, str);\r
366             Sleep(10);\r
367         }\r
368         TriclopsInput* buffer = (TriclopsInput*)PTGreyGetTriclopsBuffer();\r
369 \r
370         // Process the frames...\r
371         PTGreyFreezeData(INFINITE);\r
372         bar->SetPaneText(0, "Processing the frames...");\r
373         PTGreyProcessFrames(PTGreyGetTriclopsBuffer(), framesCount, dlg.m_strSaveFile);\r
374         bar->SetPaneText(0, "Ready");\r
375         PTGreyUnFreezeData();\r
376 \r
377         // Freeing the memory...\r
378         PTGreySetTriclopsInputBuffer(0);\r
379     }\r
380 }\r
381 \r
382 void CStereoGRApp::InitModulePath()\r
383 {\r
384     char buffer[_MAX_PATH];\r
385     char drive[_MAX_DRIVE];\r
386     char path[_MAX_PATH];\r
387     GetModuleFileName(0, buffer, _MAX_PATH);\r
388 \r
389     _splitpath(buffer, drive, path, 0, 0);\r
390     m_modulePath = CString(drive) + path;\r
391 }\r
392 \r
393 \r
394 void CStereoGRApp::OnCaptureBack() \r
395 {\r
396     PTGreySelectDataType(PT_BACKGROUND_IMAGE, 1);       \r
397 }\r
398 \r
399 void CStereoGRApp::Process()\r
400 {\r
401     ASSERT(iplGetErrStatus() >= 0);\r
402     ValidateData();\r
403     // Lock the data\r
404     PTGreyFreezeData(INFINITE);\r
405 \r
406     if(!m_viewIds[PT_POINTCLOUD_IMAGE])\r
407     {\r
408         PTGreyUnFreezeData();\r
409         return; // Do not run the algorithm\r
410     }\r
411     \r
412     // Set FindHand object properties\r
413         m_findHand.m_dGestureName = m_dgProp->GetGestureName();\r
414         m_findHand.m_dynamicGesture = m_dgProp->IsCollectGesture();\r
415     m_findHand.SetPointBuffer((CvPoint3D32f*)PTGreyGetDataPointer(PT_POINTCLOUD_IMAGE));\r
416     m_findHand.m_pointCount = PTGreyGetPointCount();\r
417         TRACE("\n%d", m_findHand.m_pointCount);\r
418     m_findHand.m_inputImage = GetImage(PT_RIGHT_RAW_IMAGE);\r
419     iplDeallocate(m_findHand.m_disparityImage, IPL_IMAGE_ALL);\r
420     m_findHand.m_disparityImage = iplCloneImage(GetView(PT_DISPARITY_OBJ_IMAGE)->GetRecipient());\r
421         iplCopy(GetView(PT_DISPARITY_IMAGE)->GetRecipient(), m_findHand.m_disparityImage);\r
422 \r
423     if(m_findHand.m_outputImage)\r
424     {\r
425         m_findHand.m_outputImage->roi = 0;\r
426         cvReleaseImage(&m_findHand.m_outputImage); // Release and null it.\r
427     }\r
428     BOOL ret = m_findHand.FitLine();\r
429     ASSERT(iplGetErrStatus() >= 0);\r
430     if(ret)\r
431         {\r
432         //if all ok with finding hand increase hand sequence size\r
433         if(m_findHand.m_dynamicGesture) m_findHand.m_dgFrameFound = TRUE;  \r
434                 m_findHand.StoreDynGesture(0, PTGreyGetTime());\r
435 //              m_findHand.FindHand(FALSE);\r
436         }        \r
437     // Use output image as a mask to the right raw image\r
438     IplImage* image = m_findHand.m_outputImage;\r
439         CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();\r
440         frame->GetStatusBar()->SetPaneText(1, "");\r
441     IplImage* srcImage = GetImage(PT_RIGHT_RAW_IMAGE);\r
442         int width = PTGreyGetWidth(PT_RIGHT_RAW_IMAGE);\r
443         int height = PTGreyGetHeight(PT_RIGHT_RAW_IMAGE);\r
444         int swidth = PTGreyGetWidth(PT_DISPARITY_IMAGE);\r
445         int sheight = PTGreyGetHeight(PT_DISPARITY_IMAGE);\r
446         int maxdisp;\r
447         PTGreyGetProperty("MaxDisparity", &maxdisp);\r
448 \r
449         CvPoint valid_size = cvPoint(width*(swidth - maxdisp/2)/swidth,\r
450                         height*(sheight - maxdisp/2)/sheight);\r
451 \r
452 //    Segment();\r
453     if(!ret/*!image*/)\r
454         {\r
455         ValidateData(FALSE);\r
456                 cvRectangle(srcImage, cvPoint(0, 0), valid_size, CV_RGB(255, 0, 0), 1);\r
457         }\r
458         else\r
459     {\r
460         ValidateData(FALSE);\r
461                 cvRectangle(srcImage, cvPoint(0, 0), valid_size, CV_RGB(0, 255, 0), 1);\r
462 /*        iplThreshold(image, image, 1);\r
463         if(srcImage)\r
464         {\r
465             srcImage->roi = iplCreateROI(0, 0, 0, image->width, image->height);\r
466             image->roi = iplCreateROI(1, 0, 0, image->width, image->height);\r
467             \r
468             for(int i = 0; i < 3; i++)\r
469             {\r
470                 srcImage->roi->coi = i + 1;\r
471                 iplAnd(srcImage, image, srcImage);\r
472             }\r
473             iplDeleteROI(srcImage->roi);\r
474             iplDeleteROI(image->roi);\r
475         }\r
476                 CString str;\r
477                 str.Format("%d", m_findHand.m_DefectsDepth.size());\r
478 \r
479                 if(m_findHand.m_convexDefCount !=0 )\r
480                 {\r
481                         CString def;\r
482                         for (int i=0;i<m_findHand.m_DefectsDepth.size();i++)\r
483                         {\r
484                                 def.Format(" %4.1f", m_findHand.m_DefectsDepth[i]);\r
485                                 str+=def;\r
486                         }\r
487 \r
488                 }\r
489                 frame->GetStatusBar()->SetPaneText(1, LPCTSTR(str));*/\r
490     }\r
491 \r
492     //********************Dynamic gestures section*********************** /\r
493     \r
494     //ask findHandCtl if it has collected gesture\r
495     if ( m_findHand.IsGestureFixed() && m_findHand.m_dynamicGesture )\r
496     {\r
497                 CDynGesture  local_gesture(m_hmmParams->m_num_states, m_hmmParams->m_num_mix);\r
498                 CDynGesture* gesture = NULL;\r
499 \r
500                 if (!m_doRecog) //collecting gestures\r
501         {\r
502                         //training stage \r
503             gesture = m_dgServer.FindGesture( m_findHand.m_dGestureName.c_str() );\r
504         \r
505             if ( !gesture )  //add new gesture to server\r
506             {\r
507                 gesture = m_dgServer.AddGesture( m_findHand.m_dGestureName.c_str() );\r
508             }\r
509                 }\r
510                 else\r
511                 {\r
512                         gesture = &local_gesture;\r
513                 }\r
514 \r
515         //add collected params to gesture\r
516                 gesture->AddParams( m_findHand.m_geomParams );\r
517 \r
518         if (m_doRecog) //recognizing gestures\r
519         {       \r
520                         float likelihood[10] = { -FLT_MAX,-FLT_MAX,-FLT_MAX,-FLT_MAX,-FLT_MAX,\r
521                                      -FLT_MAX,-FLT_MAX,-FLT_MAX,-FLT_MAX,-FLT_MAX };\r
522             \r
523             //convert params to observations form\r
524             gesture->ExtractObservations();  \r
525             \r
526             //recognize\r
527             int recognized_gesture = m_dgServer.RecognizeDynGesture( gesture, likelihood );\r
528                         if(recognized_gesture >= 0)\r
529                         {\r
530                                 CString gesture_name = m_dgServer.GetGesture( recognized_gesture )->GetName();\r
531                                 CStereoGRView* pView = GetView(GR_MAGICCUBE);\r
532                                 \r
533                                 if(gesture_name.CompareNoCase("rotate_left") == 0)\r
534                                 {\r
535                                         pView->RotateAzim(-1);\r
536                                 }\r
537                                 else if(gesture_name.CompareNoCase("rotate_right") == 0)\r
538                                 {\r
539                                         pView->RotateAzim(+1);\r
540                                 }\r
541                                 else if(gesture_name.CompareNoCase("rotate_counterclockwise") == 0)\r
542                                 {\r
543                                         pView->RotateIncl(-1);\r
544                                 }\r
545                                 else if(gesture_name.CompareNoCase("rotate_clockwise") == 0)\r
546                                 {\r
547                                         pView->RotateIncl(+1);\r
548                                 }\r
549                                 else if(gesture_name.CompareNoCase("zoom_in") == 0)\r
550                                 {\r
551                                         pView->Translate(-0.1f);\r
552                                 }\r
553                                 else if(gesture_name.CompareNoCase("zoom_out") == 0)\r
554                                 {\r
555                                         pView->Translate(+0.1f);\r
556                                 }\r
557                                 else if(gesture_name.CompareNoCase("close") == 0)\r
558                                 {\r
559                                         CloseView(GR_MAGICCUBE);\r
560                                 }\r
561                                 else if(gesture_name.CompareNoCase("reset") == 0)\r
562                                 {\r
563                                         pView->InitModel();\r
564                                 }\r
565                                 \r
566 \r
567                                 //ASSERT( likelihood[0] <= 0 );\r
568             \r
569                                 //write result to status bar\r
570                                 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();\r
571                                 frame->GetStatusBar()->SetPaneText(2, "");\r
572                                 CString RecogResult;\r
573                                 RecogResult.Format("Recognized %s, likelihood %f",\r
574                                         m_dgServer.GetGesture( recognized_gesture )->GetName(), likelihood[0] );                                \r
575                                 frame->GetStatusBar()->SetPaneText(2, RecogResult);     \r
576                         }\r
577         }\r
578         \r
579         m_findHand.ReleaseFixedGesture();\r
580     }\r
581     /*****************************************************************/\r
582 \r
583 \r
584     ASSERT(iplGetErrStatus() >= 0);\r
585     if(::IsWindow(m_gestRec.m_hWnd))\r
586     {\r
587         m_gestRec.UpdateStatus();\r
588     }\r
589     ASSERT(iplGetErrStatus() >= 0);\r
590 \r
591     PTGreyUnFreezeData();    \r
592 }\r
593 \r
594 void CStereoGRApp::OpenView(int dataType)\r
595 {\r
596     // Check if the view alredy exists...\r
597     if(m_views[dataType])\r
598         return;\r
599 \r
600     SetDocType(dataType);\r
601     OnFileNew();\r
602     switch(dataType)\r
603     {\r
604     case PT_DISPARITY_OBJ_IMAGE:\r
605         OpenView(PT_RIGHT_RAW_IMAGE);\r
606         OpenView(PT_DISPARITY_IMAGE);\r
607         break;\r
608 \r
609     case PT_POINTCLOUD_IMAGE:\r
610         OpenView(PT_DISPARITY_OBJ_IMAGE);\r
611         break;\r
612 \r
613         case GR_MAGICCUBE:\r
614                 OpenView(PT_POINTCLOUD_IMAGE);\r
615                 OpenView(PT_LEFT_RAW_IMAGE);\r
616                 OpenView(PT_TOP_RAW_IMAGE);\r
617                 break;\r
618     }\r
619 }\r
620 \r
621 void CStereoGRApp::SetView(int dataType, CStereoGRView *pView)\r
622 {\r
623     m_views[dataType] = pView;\r
624     m_viewIds[dataType] = 1;\r
625 }\r
626 \r
627 void CStereoGRApp::CloseView(int dataType)\r
628 {\r
629         PTGreyFreezeData(INFINITE);\r
630         m_isClosingView++;\r
631         switch(dataType)\r
632         {\r
633         case PT_POINTCLOUD_IMAGE:\r
634         case PT_LEFT_RAW_IMAGE:\r
635         case PT_TOP_RAW_IMAGE:\r
636                 CloseView(GR_MAGICCUBE);\r
637                 break;\r
638 \r
639         case PT_DISPARITY_OBJ_IMAGE:\r
640                 CloseView(PT_POINTCLOUD_IMAGE);\r
641                 break;\r
642 \r
643         case PT_RIGHT_RAW_IMAGE:\r
644         case PT_DISPARITY_IMAGE:\r
645                 CloseView(PT_DISPARITY_OBJ_IMAGE);\r
646                 break;\r
647         }\r
648 \r
649     ASSERT(dataType >= 0 && dataType < VIEWS_COUNT);\r
650     if(m_views[dataType])\r
651     {\r
652         m_views[dataType]->GetParent()->DestroyWindow();\r
653         m_viewIds[dataType] = 0;\r
654     }\r
655         m_isClosingView--;\r
656     PTGreyUnFreezeData();\r
657 }\r
658 \r
659 IPLStatus __stdcall _iplErrorHandler(IPLStatus status, const char* func, const char* context, \r
660                             const char* file, int line)\r
661 {\r
662     if(status != -10)\r
663         ASSERT(0);\r
664     return IPL_StsOk;\r
665 }\r
666 \r
667 void CStereoGRApp::Update()\r
668 {\r
669     if(!PTGreyFreezeData(INFINITE))\r
670         return;\r
671 \r
672     int e = iplGetErrStatus();\r
673     ASSERT(e >= 0);\r
674     // Retrieve the data\r
675     for(int i = 0; i < VIEWS_COUNT; i++)\r
676     {\r
677         CStereoGRView* pView = GetView(i);\r
678         if(pView)\r
679             pView->UpdateData();\r
680     }\r
681     // Run algorithms on the data\r
682     Process();\r
683     PTGreyUnFreezeData();\r
684 \r
685     // Render the results\r
686     for(i = 0; i < VIEWS_COUNT; i++)\r
687     {\r
688         CStereoGRView* pView = GetView(i);\r
689         if(pView)\r
690             pView->UpdateView();\r
691     }\r
692     ASSERT(iplGetErrStatus() >= 0);\r
693 }\r
694 \r
695 IplImage* CStereoGRApp::GetImage(int dataType)\r
696 {\r
697     if(!m_views[dataType])\r
698         return 0;\r
699 \r
700     return m_views[dataType]->GetImage();\r
701 }\r
702 \r
703 /*void CStereoGRApp::SetImage(int dataType, IplImage *image, BOOL copy)\r
704 {\r
705     if(!m_views[dataType])\r
706         return;\r
707 \r
708     m_views[dataType]->SetImage(image, copy);\r
709 }*/\r
710 \r
711 void CStereoGRApp::OnRungestrec() \r
712 {\r
713     m_gestRec.DoModal();        \r
714 }\r
715 \r
716 void CStereoGRApp::ValidateData(BOOL flag)\r
717 {\r
718     m_isNewData = flag;\r
719 }\r
720 \r
721 BOOL CStereoGRApp::IsNewData()\r
722 {\r
723     return m_isNewData;\r
724 }\r
725 \r
726 \r
727 void CStereoGRApp::OnTrain() \r
728 {       \r
729     m_dgServer.TrainAllGestures();\r
730 }\r
731 \r
732 \r
733 void CStereoGRApp::OnSettings()\r
734 {\r
735     CPropertySheet sheet;\r
736     sheet.AddPage(m_ptOptions);\r
737     sheet.AddPage(m_grOptions);\r
738     sheet.AddPage(m_hmmParams);\r
739     sheet.AddPage(m_dgProp);\r
740     sheet.AddPage(m_dgStat);\r
741 \r
742     // Load PointGrey options\r
743     int rawres, stereores;\r
744     PTGreyGetProperty("StereoResolution", &stereores);\r
745     m_ptOptions->m_stereoRes = stereores;\r
746     PTGreyGetProperty("RawResolution", &rawres);\r
747     m_ptOptions->m_rawRes = rawres;\r
748     PTGreyGetProperty("MinDisparity", &m_ptOptions->m_minDisp);\r
749     PTGreyGetProperty("MaxDisparity", &m_ptOptions->m_maxDisp);\r
750     PTGreyGetProperty("DisparityThreshold", &m_ptOptions->m_dispThresh);\r
751     PTGreyGetProperty("DifferenceThreshold", &m_ptOptions->m_diffThresh);\r
752     PTGreyGetProperty("DepthThreshold", &m_ptOptions->m_depthThresh);\r
753     PTGreyGetProperty("ContourProcessing", &m_ptOptions->m_checkContours);\r
754 \r
755     // Load StereoGR options\r
756     m_grOptions->m_maskImprove = m_findHand.m_maskImprovigFlag;\r
757     m_grOptions->m_frameCount = m_findHand.m_trainFrameCount;\r
758     m_grOptions->m_segThresh = m_findHand.m_segThresh;\r
759 \r
760     if(sheet.DoModal() == IDOK)\r
761     {\r
762         // Save PointGrey options\r
763         PTGreyFreezeData(INFINITE);\r
764         if(rawres != m_ptOptions->m_rawRes || stereores != m_ptOptions->m_stereoRes)\r
765         {\r
766             // The resolution has changed...\r
767             WriteProfileInt("Settings\\PTGrey", "Raw resolution", m_ptOptions->m_rawRes);\r
768             WriteProfileInt("Settings\\PTGrey", "Stereo resolution", m_ptOptions->m_stereoRes);\r
769             AfxMessageBox("The resolution change will not take effect until application restart.");\r
770         }\r
771         PTGreySetProperty("MinDisparity", &m_ptOptions->m_minDisp);\r
772         PTGreySetProperty("MaxDisparity", &m_ptOptions->m_maxDisp);\r
773         PTGreySetProperty("DisparityThreshold", &m_ptOptions->m_dispThresh);\r
774         PTGreySetProperty("DifferenceThreshold", &m_ptOptions->m_diffThresh);\r
775         PTGreySetProperty("DepthThreshold", &m_ptOptions->m_depthThresh);\r
776         PTGreySetProperty("ContourProcessing", &m_ptOptions->m_checkContours);\r
777         PTGreyUnFreezeData();\r
778 \r
779         // Save StereoGR options\r
780         m_findHand.m_maskImprovigFlag = m_grOptions->m_maskImprove;\r
781         m_findHand.m_trainFrameCount = m_grOptions->m_frameCount;\r
782         m_findHand.m_segThresh = m_grOptions->m_segThresh;\r
783 \r
784         //change HMM parameters of gestures\r
785         \r
786         m_dgServer.SetHMMParams( m_hmmParams->m_num_states, m_hmmParams->m_num_mix );\r
787         \r
788                 m_findHand.m_dGestureName = m_dgProp->GetGestureName();\r
789                 m_findHand.m_dynamicGesture = m_dgProp->IsCollectGesture();\r
790                 m_findHand.m_saveDynGest =  m_dgProp->IsSaveToFile();\r
791                 m_findHand.m_path = m_dgProp->GetSavePath();\r
792     }\r
793 }\r
794 \r
795 \r
796 void CStereoGRApp::OnSaveDynamicGestures() \r
797 {\r
798         int numgest = m_dgServer.GetNumGestures();\r
799     for( int i = 0; i < numgest; i++ )\r
800     {\r
801         CDynGesture* gesture = m_dgServer.GetGesture( i );\r
802         CString path = gesture->GetName();\r
803         gesture->SaveParams( path );\r
804     }\r
805     // TODO: Add your command handler code here\r
806 }\r
807 \r
808 CStereoGRApp::LoadSettings()\r
809 {\r
810         // Create property pages    \r
811         CreatePropertyPages();\r
812     // Load the PTGrey settings\r
813     char * _settings[] = {\r
814         "CameraBrightness",\r
815         "CameraIris",\r
816         "CameraExposure",\r
817         "MinDisparity",\r
818         "MaxDisparity",\r
819         "DisparityThreshold",\r
820         "DifferenceThreshold",\r
821         "DepthThreshold"\r
822     };\r
823 \r
824     for(int i = 0; i < sizeof(_settings)/sizeof(char*); i++)\r
825     {\r
826         int value;\r
827         PTGreyGetProperty(_settings[i], &value);\r
828         value = GetProfileInt("Settings\\PTGrey", _settings[i], value);\r
829         PTGreySetProperty(_settings[i], &value);\r
830     }\r
831 \r
832     // Load the StereoGR settings\r
833     m_findHand.m_segThresh = GetProfileInt("Settings\\PTGrey", "Segmentation threshold", m_findHand.m_segThresh);\r
834     m_findHand.m_trainFrameCount = GetProfileInt("Settings\\PTGrey", "Train framecount", \r
835         m_findHand.m_trainFrameCount);\r
836     m_findHand.m_maskImprovigFlag = GetProfileInt("Settings\\PTGrey", "Improve mask", \r
837         m_findHand.m_maskImprovigFlag);\r
838 \r
839     // Load HMM settings\r
840     m_hmmParams->m_num_states = GetProfileInt("Settings\\HMM", "Number of states", 5);\r
841     m_hmmParams->m_num_mix = GetProfileInt("Settings\\HMM", "Number of mixtures", 3);\r
842 \r
843         // Load StereoGR parameters\r
844 \r
845         RECT mainView;\r
846         mainView.left = GetProfileInt("Settings\\StereoGR", "left", 0);\r
847         mainView.top = GetProfileInt("Settings\\StereoGR", "top", 0);\r
848         mainView.right = mainView.left + GetProfileInt("Settings\\StereoGR", "width", 800);\r
849         mainView.bottom = mainView.top + GetProfileInt("Settings\\StereoGR", "height", 600);\r
850         AfxGetMainWnd()->MoveWindow(&mainView);\r
851 \r
852         for(i = 0; i < VIEWS_COUNT; i++)\r
853         {\r
854                 CString str;\r
855                 str.Format("Settings\\StereoGR\\View%d", i);\r
856                 POINT view;\r
857 \r
858                 view.x = GetProfileInt(LPCTSTR(str), "left", 0);\r
859                 view.y = GetProfileInt(LPCTSTR(str), "top", 0);\r
860 \r
861                 m_TopLefts[i] = view;\r
862         \r
863                 if(i == PT_POINTCLOUD_IMAGE || i == GR_MAGICCUBE)\r
864                 {\r
865                         str.Format("Settings\\StereoGR\\View%d_3d", i);\r
866                         POINT view;\r
867 \r
868                         view.x = GetProfileInt(LPCTSTR(str), "left", 0);\r
869                         view.y = GetProfileInt(LPCTSTR(str), "top", 0);\r
870 \r
871                         m_TopLefts3D[i] = view;\r
872                 }\r
873         }\r
874 \r
875     m_dgProp->m_savePath = m_modulePath;\r
876     return TRUE;\r
877 }\r
878 \r
879 CStereoGRApp::SaveSettings()\r
880 {\r
881     // Load the PTGrey settings\r
882     char * _settings[] = {\r
883         "CameraBrightness",\r
884         "CameraIris",\r
885         "CameraExposure",\r
886         "MinDisparity",\r
887         "MaxDisparity",\r
888         "DisparityThreshold",\r
889         "DifferenceThreshold",\r
890         "DepthThreshold"\r
891     };\r
892 \r
893     for(int i = 0; i < sizeof(_settings)/sizeof(char*); i++)\r
894     {\r
895         int value;\r
896         PTGreyGetProperty(_settings[i], &value);\r
897         WriteProfileInt("Settings\\PTGrey", _settings[i], value);\r
898     }\r
899 \r
900     // Load the StereoGR settings\r
901     WriteProfileInt("Settings\\PTGrey", "Segmentation threshold", m_findHand.m_segThresh);\r
902     WriteProfileInt("Settings\\PTGrey", "Train framecount", m_findHand.m_trainFrameCount);\r
903     WriteProfileInt("Settings\\PTGrey", "Improve mask", m_findHand.m_maskImprovigFlag);\r
904 \r
905     // Load HMM settings\r
906     WriteProfileInt( "Settings\\HMM", "Number of states", m_hmmParams->m_num_states );\r
907     WriteProfileInt( "Settings\\HMM", "Number of mixtures", m_hmmParams->m_num_mix );\r
908 \r
909         // Saving the views positions\r
910 \r
911         RECT mainRect;\r
912         AfxGetMainWnd()->GetWindowRect(&mainRect);\r
913         WriteProfileInt("Settings\\StereoGR", "left", mainRect.left);\r
914         WriteProfileInt("Settings\\StereoGR", "top", mainRect.top);\r
915         WriteProfileInt("Settings\\StereoGR", "width", mainRect.right - mainRect.left);\r
916         WriteProfileInt("Settings\\StereoGR", "height", mainRect.bottom - mainRect.top);\r
917 \r
918     \r
919     return TRUE;\r
920 }\r
921 \r
922 int CStereoGRApp::ExitInstance() \r
923 {\r
924 //    SaveSettings();   \r
925         int ret = CWinApp::ExitInstance();\r
926         PTGreyExitCamera(2);\r
927         return ret;\r
928 }\r
929 \r
930 \r
931 void CStereoGRApp::OnLoadDynamicGestures() \r
932 {\r
933     int numgest = 6;\r
934     char* names[6] = { "Rotate left", "Rotate right", "Move up", \r
935                        "Move down", "Zoom out", "Zoom in" };\r
936 \r
937     for( int i = 0; i < numgest; i++ )\r
938     {\r
939         CDynGesture* gesture = new CDynGesture(m_hmmParams->m_num_states, m_hmmParams->m_num_mix );\r
940         CString path = names[i];\r
941         if ( gesture->LoadParams( path ) )\r
942         {\r
943              gesture->SetName( path );\r
944              //add to dgServer\r
945              m_dgServer.AddGesture( gesture );\r
946         }\r
947         else delete gesture;  \r
948     }\r
949 }\r
950 \r
951 void CStereoGRApp::OnSaveBase() \r
952 {\r
953     CFileDialog dlg( FALSE, 0, 0, /*OFN_ALLOWMULTISELECT | */OFN_ENABLESIZING |\r
954                      OFN_EXPLORER,\r
955                      "Dynamic Gesture base (*.txt) |*.txt|", 0 );\r
956     \r
957     if ( dlg.DoModal() == IDOK )\r
958     {           \r
959         m_dgServer.SaveGestureBase( dlg.GetFileName() );\r
960     }\r
961         // TODO: Add your command handler code here     \r
962 }\r
963 \r
964 void CStereoGRApp::OnLoadBase() \r
965 {\r
966     CFileDialog dlg( TRUE, 0, 0, /*OFN_ALLOWMULTISELECT | */OFN_ENABLESIZING |\r
967                      OFN_EXPLORER,\r
968                      "Dynamic Gesture base (*.txt) |*.txt|", 0 );\r
969     \r
970     if ( dlg.DoModal() == IDOK )\r
971     {\r
972         m_dgServer.LoadGestureBase( dlg.GetFileName() );\r
973     }\r
974 }\r
975 \r
976 void CStereoGRApp::OnRecogFileDg() \r
977 {\r
978         // TODO: Add your command handler code here\r
979     CFileDialog dlg( TRUE, 0, 0, /*OFN_ALLOWMULTISELECT | */OFN_ENABLESIZING |\r
980                      OFN_EXPLORER | OFN_FILEMUSTEXIST,\r
981                      "Dynamic Gesture observations (*.obs) |*.obs|", 0 );\r
982 \r
983     if ( dlg.DoModal()== IDOK )\r
984     {\r
985         float likelihood[10] = {-1, -1, -1, -1, -1, \r
986                               -1, -1, -1, -1, -1 };\r
987 \r
988         CDynGesture gesture(m_hmmParams->m_num_states, m_hmmParams->m_num_mix );\r
989         gesture.LoadSequence( dlg.GetFileName() );\r
990         gesture.ExtractObservations();\r
991 \r
992         m_dgServer.TrainAllGestures();\r
993 \r
994         int rg = m_dgServer.RecognizeDynGesture( &gesture, likelihood );\r
995 \r
996         //write result to status bar\r
997                 CMainFrame* frame = (CMainFrame*)AfxGetMainWnd();\r
998             frame->GetStatusBar()->SetPaneText(2, "");\r
999                 CString RecogResult;\r
1000                 RecogResult.Format("Recognized %s likelihood %f", \r
1001             m_dgServer.GetGesture( rg )->GetName(), likelihood[0] );                            \r
1002             frame->GetStatusBar()->SetPaneText(2, RecogResult); \r
1003     }\r
1004 }\r
1005 \r
1006 \r
1007 \r
1008 \r
1009 void CStereoGRApp::OnDeleteHmm() \r
1010 {\r
1011     m_dgServer.DeleteHMMInfo();\r
1012         // TODO: Add your command handler code here\r
1013         \r
1014 }\r
1015 \r
1016 void CStereoGRApp::OnRemoveAllDg() \r
1017 {\r
1018         m_dgServer.CleanAll();// TODO: Add your command handler code here\r
1019         \r
1020 }\r
1021 \r
1022 \r
1023 void CStereoGRApp::Zoom()\r
1024 {\r
1025         \r
1026 }\r
1027 \r
1028 \r
1029 void CStereoGRApp::CreatePropertyPages()\r
1030 {\r
1031     m_hmmParams = new CHMMParams;\r
1032     m_ptOptions = new CPTOptions;\r
1033     m_grOptions = new CGROptions;\r
1034     m_dgStat = new CDGStat;\r
1035         m_dgProp = new CDGProp;\r
1036 }\r
1037 \r
1038 void CStereoGRApp::OnUpdateRungestrec(CCmdUI* pCmdUI) \r
1039 {\r
1040         // This feature is disabled in the current release\r
1041         pCmdUI->Enable(FALSE);\r
1042 }\r