Update the changelog
[opencv] / apps / cvlkdemo / cvlkdemo.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*/
41
42 #include <tcl.h>
43 #include <tk.h>
44 //#include <tkInt.h>
45
46 #ifndef WIN32
47 //#include <pthread.h>
48 //#include <sys/types.h>
49 #include <unistd.h>
50 //#include <signal.h>
51 //#include <wait.h>
52 //#include <stdlib.h>
53 //#include <string.h>
54 #endif
55
56 #ifndef WIN32
57     #define Tk_GetHWND(id) id
58 #else
59     extern "C"
60     {
61     int Tk_GetHWND(int win);
62     }
63 #endif
64
65 #if _MSC_VER >= 1200
66 #pragma warning( disable: 4100 4663 4189 4101 4018 4710 )
67 #endif
68
69 #include "cvcam.h"
70 #include "highgui.h"
71 #include "demoview.h"
72
73 #define SYSTEM_WIN_FROM_TK_WIN(tkwin) Tk_GetHWND(Tk_WindowId(tkwin)) 
74
75 char cmd[300];
76
77 void    MainEx(int argc, char **argv, Tcl_AppInitProc *pfappInitProc, Tcl_Interp *pintrp,
78                char *pchfileName);
79 int     Tcl_AppInit(Tcl_Interp *pintrp);
80 void    WishPanic TCL_VARARGS_DEF(char *,arg1);
81 void    Panic (Tcl_Interp * pintrp, const char * pch);
82
83 CLkDemoView view;
84 CImage lastframe;
85
86
87 static char* module_path;
88 CvPoint P;
89
90 ///////////////////////////////////////////////////////////////////////////////
91 static char* GetPathFromModuleName( char* modulename )
92 {
93     int i;
94     if( !modulename )
95         return 0;
96 #ifndef WIN32
97     /* if module is link find real path */
98     int  len;
99     char real[1000];
100     strcpy( real, modulename );
101     while( (len = readlink( real, real, 1000 )) > 0 )
102         real[len] = 0;
103     char* path = (char*)malloc( strlen( real ) + 10 );
104     strcpy( path, real );
105 #else
106     char* path = (char*)malloc( strlen( modulename ) + 10 );
107     strcpy( path, modulename );
108 #endif
109
110     for( i = strlen( path ) - 1;
111          i > 0 && path[i] != '\\' && path[i] != '/';
112          i-- );
113
114     if( i <= 0 )
115     {
116         path[0] = '.';
117         i = 1;
118     }
119
120     path[i] = '/';
121     path[i + 1] = 0;
122
123 #ifdef WIN32
124     for( i = 0; i < (int)strlen( path ); i++ )
125         if( path[i] == '\\' )
126             path[i] = '/';
127 #endif
128
129     return path;
130 }
131
132 // Callback function ----------------------------------------------------------
133 void testcallback(IplImage* img)
134 {
135     assert (img);
136     lastframe.Destroy();
137     lastframe.Create(img->width,img->height,24,img->origin);
138     lastframe.CopyOf(img);
139     
140     if (view.m_track) {
141
142         if (!view.m_trackinit) {
143             view.StartTracking(lastframe);
144             view.m_trackinit = true;
145         }
146
147         view.TrackFeatures(lastframe);
148         
149         //double kx = (double)view.m_w/img->width;
150         //double ky = (double)view.m_h/img->height;
151         
152         if( !view.m_night_mode )
153         {
154             
155         }
156         else
157         {
158             //iplSet( img, 0 );
159             //CvPoint tl = {0,0};
160             //CvPoint br = {img->width,img->height};
161             //cvRectangle(img, tl, br, 0, (img->width > img->height) ? img->width : img->height);
162             //cvRectangle(img, tl, br, 0, 255);
163             memset(img->imageData,0,img->imageSize);
164         }
165         
166         int i, count = view.m_tracker.GetCount();
167         const PointArray& array = view.m_tracker.GetPoints();
168
169         cvCircle( img, P, cvRound(3), CV_RGB(0,0,255));
170                 
171         for( i = 0; i < count; i++ )
172         {
173             CvPoint pt;
174             int color;
175             if( i != view.m_moved_idx )
176             {
177                 pt = cvPoint( cvRound(array[i].x), cvRound(array[i].y));
178                 color = CV_RGB(0,255,0);
179             }
180             else
181             {
182                 pt = cvPoint( cvRound(view.m_moved_point.x),
183                     cvRound(view.m_moved_point.y));
184                 color = CV_RGB(255,0,0);
185             }
186             cvCircle( img, pt, 1, color, CV_FILLED );
187         }
188     }
189     else
190     {
191         if  (view.m_trackinit)
192         {
193             view.StopTracking();
194             view.m_trackinit = false;
195         }
196     }
197     
198 #ifdef WIN32
199     Sleep(10);
200 #endif
201 }
202 //-----------------------------------------------------------------------------
203
204 /*
205  *----------------------------------------------------------------------
206  *
207  * Commands routines.
208  *
209  * Results:
210  *  TCL_OK - if sucsess, or TCL_ERROR
211  *
212  *----------------------------------------------------------------------
213  */
214
215 int Init_Camera (ClientData, Tcl_Interp *interp,
216     int, char **)
217 {
218     cvcamWindow mainwin;
219     int ncameras,ret;
220     Tk_Window win;
221     char com[1000]="set dlg [Dialog .dlg -parent . -modal local -separator 1 -title   \"Choice of cameras\" \
222                    -side bottom -anchor  s -default 0]";
223     CameraDescription cd;
224     
225     ncameras = cvcamGetCamerasCount();
226
227     if (ncameras==0) 
228     {
229         Tcl_Eval(interp,"tk_dialog .pattern {Error} { Cameras not found.} {} 0 OK");
230         return TCL_ERROR;
231     }
232   
233     ret = Tcl_Eval(interp,com);
234
235     strcpy(com,"$dlg add -name ok -width 5");
236     ret = Tcl_Eval(interp,com);
237
238     strcpy(com, "set top [$dlg getframe]");
239     ret = Tcl_Eval(interp,com);
240
241     strcpy(com, "label $top.lab1 -text \"Several cameras has found in your system. Choose one of them.\" \n\
242                 pack $top.lab1 -side top -anchor nw" );
243     ret = Tcl_Eval(interp,com);
244                 
245     strcpy(com, "label $top.lab2 -text \"\" \n\
246                 pack $top.lab2 -side top -anchor nw");
247     ret = Tcl_Eval(interp,com);
248
249     strcpy(com, "label $top.lab3 -text \"Cameras:\" \n\
250                  pack $top.lab3 -side top -anchor nw");
251     ret = Tcl_Eval(interp,com);
252
253     strcpy(com, "ComboBox $top.cb -width 50 -height 4 -editable no -modifycmd CVLkDemo::Modify");
254     ret = Tcl_Eval(interp,com);
255     
256     strcpy(com, "pack $top.cb -side top");
257     ret = Tcl_Eval(interp,com);
258
259     strcpy(com, "$top.cb configure -values {");
260     for (int i=0; i<ncameras; i++)
261     {        
262         cvcamGetProperty(i, CVCAM_DESCRIPTION, (void*)&cd);
263         strcat(com,"\"");
264         strcat(com,cd.DeviceDescription);
265         strcat(com,"\" ");
266     }
267     strcat(com,"}");
268     ret = Tcl_Eval(interp, com);
269
270     strcpy(com,"$top.cb setvalue @0 \n CVLkDemo::Modify \n set ret [$dlg draw]");
271     ret = Tcl_Eval(interp, com);
272
273     strcpy(com,"destroy $dlg");
274     ret = Tcl_Eval(interp, com);
275     
276     ret = Tcl_Eval(interp, "set tmp $CVLkDemo::cam");
277     int n = atoi(interp->result);
278
279     ret = Tcl_Eval(interp, "set f $CVLkDemo::curframe");
280         
281     win = Tk_NameToWindow(interp, interp->result, 
282         Tk_MainWindow(interp));
283     
284     Tk_MapWindow(win);
285     int w = Tk_Width(win);
286     int h = Tk_Height(win);
287  
288     mainwin = SYSTEM_WIN_FROM_TK_WIN(win);
289     /*int prop;*/
290     
291     cvcamSetProperty(n, CVCAM_PROP_ENABLE, CVCAMTRUE);
292     cvcamSetProperty(n, CVCAM_PROP_RENDER, CVCAMTRUE);
293     cvcamSetProperty(n, CVCAM_PROP_WINDOW,  &mainwin);
294     cvcamSetProperty(n, CVCAM_PROP_CALLBACK, (void*)testcallback);
295     cvcamSetProperty(n, CVCAM_RNDWIDTH, (void*)&w);
296     cvcamSetProperty(n, CVCAM_RNDHEIGHT, (void*)&h);
297     view.SetSize(w,h);
298
299     cvcamInit();
300     cvcamGetProperty(n, CVCAM_DESCRIPTION, (void*)&cd);
301     sprintf(com,"set CVLkDemo::curcam \"%s\"",cd.DeviceDescription);
302     Tcl_Eval(interp, com);
303         
304     return TCL_OK;
305 }
306
307 int Close_Camera (ClientData, Tcl_Interp *,
308                   int, char **)
309 {
310     view.m_started = false;
311     cvcamExit();
312     return TCL_OK;
313 }
314
315 int Start_Camera (ClientData, Tcl_Interp *,
316                  int, char **)
317 {
318     view.m_started = true;
319     cvcamStart();
320     return TCL_OK;
321 }
322
323 int Stop_Camera (ClientData, Tcl_Interp *,
324                   int, char **)
325 {
326     view.m_started = false;
327     cvcamStop();
328     return TCL_OK;
329 }
330
331 int Set_Track (ClientData, Tcl_Interp *,
332                  int, char **)
333 {
334     view.m_track = true;
335     //view.StartTracking(lastframe);
336     return TCL_OK;
337 }
338
339 int Reset_Track (ClientData, Tcl_Interp *,
340                int, char **)
341 {
342     //view.StopTracking();
343     view.m_track = false;
344
345     return TCL_OK;
346 }
347
348 int Set_Night (ClientData, Tcl_Interp *,
349                int, char **)
350 {
351     view.m_night_mode = true;
352     return TCL_OK;
353 }
354
355 int Reset_Night (ClientData, Tcl_Interp *,
356                  int, char **)
357 {
358     view.m_night_mode = false;
359         
360     return TCL_OK;
361 }
362
363 int Set_Video (ClientData, Tcl_Interp *,
364                int, char **)
365 {
366     void *p = 0;
367     cvcamGetProperty(0,CVCAM_VIDEOFORMAT, p);
368
369     return TCL_OK;
370 }
371
372 int Set_CameraOpt (ClientData, Tcl_Interp *,
373                int, char **)
374 {
375     void *p = 0;
376     cvcamGetProperty(0,CVCAM_CAMERAPROPS, p);
377     
378     return TCL_OK;
379 }
380
381 int Button_Press (ClientData, Tcl_Interp *,
382                int, char **argv)
383 {
384     CvPoint p;
385     p.x = atoi(argv[1]);
386     p.y = atoi(argv[2]);
387 #ifdef WIN32    
388     p.y = view.m_h - p.y;
389 #endif
390     P = view.ConvertScreenToImage(p);
391
392     if (view.m_track)
393     {
394         int index = view.FindPoint(P);
395         if( index > 0 )
396         {
397             view.m_moved_idx = index;
398             view.m_moved_point = P;
399         }
400         else if( view.m_gray.GetImage() )
401         {
402             view.m_tracker.AddPoint( P, view.m_gray );
403         }
404     }
405     return TCL_OK;
406 }
407
408 int Button_Release (ClientData, Tcl_Interp *,
409                   int, char **argv)
410 {
411     CvPoint p;
412     p.x = atoi(argv[1]);
413     p.y = atoi(argv[2]);
414 #ifdef WIN32    
415     p.y = view.m_h - p.y;
416 #endif
417
418     
419     if (view.m_track)
420     {
421         if( view.m_moved_idx > 0 && view.m_gray.GetImage() )
422         {
423             view.m_tracker.MovePoint( view.m_moved_idx, view.m_moved_point, view.m_gray );
424             view.m_moved_idx = -1;
425         }
426     }
427     
428     return TCL_OK;
429 }
430
431 int Motion (ClientData, Tcl_Interp *,
432                     int, char **argv)
433 {
434     CvPoint p;
435     p.x = atoi(argv[1]); 
436     p.y = atoi(argv[2]);
437 #ifdef WIN32    
438     p.y = view.m_h - p.y;
439 #endif
440     P = view.ConvertScreenToImage(p);
441     if (view.m_track)
442     {
443         if( view.m_moved_idx > 0 && view.m_gray.GetImage() )
444         {
445             view.m_moved_point.x = P.x;
446             view.m_moved_point.y = P.y;
447         }
448     }
449     
450     return TCL_OK;
451 }
452
453 int Configure (ClientData, Tcl_Interp *interp,
454             int, char **)
455 {
456     if (view.m_started)
457     {
458         Tk_Window win;
459         Tcl_Eval(interp, "set f $CVLkDemo::curframe");
460     
461         win = Tk_NameToWindow(interp, interp->result, 
462             Tk_MainWindow(interp));
463     
464         Tk_MapWindow(win);
465         int w = Tk_Width(win);
466         int h = Tk_Height(win);
467     
468         cvcamSetProperty(0, CVCAM_RNDWIDTH, (void*)&w);
469         cvcamSetProperty(0, CVCAM_RNDHEIGHT, (void*)&h);
470         view.SetSize(w,h);
471     }
472     
473     return TCL_OK;
474 }
475
476
477 //-----------------------------------------------------------------------------
478
479 /*
480  *----------------------------------------------------------------------
481  *
482  * Commands_Init -- Commands initialisation routine.
483  *
484  * Results:
485  *  TCL_OK - if sucsess, or TCL_ERROR
486  *
487  *----------------------------------------------------------------------
488  */
489 int
490 Commands_Init(Tcl_Interp *interp)
491 {
492     Tcl_CreateCommand (interp, "pInitCamera", Init_Camera,
493         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
494     Tcl_CreateCommand (interp, "pStartCamera", Start_Camera,
495         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
496     Tcl_CreateCommand (interp, "pCloseCamera", Close_Camera,
497         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
498     Tcl_CreateCommand (interp, "pStopCamera", Stop_Camera,
499         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
500     Tcl_CreateCommand (interp, "pSetTrack", Set_Track,
501         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
502     Tcl_CreateCommand (interp, "pResetTrack", Reset_Track,
503         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
504     Tcl_CreateCommand (interp, "pSetNight", Set_Night,
505         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
506     Tcl_CreateCommand (interp, "pResetNight", Reset_Night,
507         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
508     Tcl_CreateCommand (interp, "pSetVideo", Set_Video,
509         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
510     Tcl_CreateCommand (interp, "pButtonPress", Button_Press,
511         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
512     Tcl_CreateCommand (interp, "pButtonRelease", Button_Release,
513         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
514     Tcl_CreateCommand (interp, "pMotion", Motion,
515         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
516     Tcl_CreateCommand (interp, "pSetCameraOpt", Set_CameraOpt,
517         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
518     Tcl_CreateCommand (interp, "pConfigure", Configure,
519         (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
520     
521     
522     return TCL_OK;
523 }
524
525
526 /*
527  *----------------------------------------------------------------------
528  *
529  * MainEx -- Main program for Tk-based applications.
530  *
531  *----------------------------------------------------------------------
532  */
533 void
534 MainEx( int, char**, Tcl_AppInitProc *appInitProc,
535         Tcl_Interp *pintrp, char *fileName )
536 {
537     int code;
538
539     (*appInitProc)(pintrp);
540
541     if ( Commands_Init(pintrp) != TCL_OK) 
542         Panic (pintrp,"Can't initialise commands!");
543
544     char set_path[1000];
545     strcat( strcat( strcpy( set_path, "set ::image_path \"" ), module_path ), "\"" );
546     code = Tcl_Eval( pintrp, set_path );
547     
548     if (fileName != NULL) 
549     {
550         char  script[1000];
551         strcat( strcat( strcpy( script, module_path ), "" ), fileName );
552         code = Tcl_EvalFile(pintrp, script);
553         if (code != TCL_OK)
554             Panic (pintrp,"Evaluate file error!");
555     }
556     else Tcl_SourceRCFile(pintrp);
557
558     Tcl_ResetResult(pintrp);
559
560     Tk_MainLoop();
561     
562     Tcl_DeleteInterp(pintrp);
563     return;
564 }
565
566 /*
567  *----------------------------------------------------------------------
568  *
569  * WishPanic -- escape function.
570  *
571  *----------------------------------------------------------------------
572  */
573
574 void WishPanic TCL_VARARGS_DEF(char *,arg1)
575 {
576     va_list argList;
577     char buf[1024];
578     char *format;
579
580     format = TCL_VARARGS_START(char *,arg1,argList);
581     printf(buf, format, argList);
582 }
583
584 /*
585  *----------------------------------------------------------------------
586  *
587  * Panic -- error output & exit function.
588  *
589  *----------------------------------------------------------------------
590  */
591
592 void Panic (Tcl_Interp * pintrp, const char * pch)
593 {
594     printf("Thread %P:",Tcl_GetCurrentThread());
595     printf(pch);
596     printf("\n    Reason:");
597     printf(pintrp->result);
598     printf("\n");
599
600     Tcl_DeleteInterp(pintrp);
601     Tcl_Exit(1);
602 }
603
604 /*void Panic (Tcl_Interp * pintrp, const char * pch)
605 {
606     char buf[2048];
607     sprintf(buf, "\nThread %p, Interpetator %p:\n",
608         Tcl_GetCurrentThread(), pintrp);
609     
610     Tcl_AddErrorInfo(pintrp, buf);
611     Tcl_AddErrorInfo(pintrp, pch);
612     TkpDisplayWarning(Tcl_GetVar(pintrp, "errorInfo",
613     TCL_GLOBAL_ONLY), "Error in startup script");
614     Tcl_DeleteInterp(pintrp);
615     Tcl_Exit(1);
616 }*/
617
618 /*
619  *----------------------------------------------------------------------
620  *
621  * Tcl_AppInit -- Initialisation function.
622  *
623  *----------------------------------------------------------------------
624  */
625
626 int Tcl_AppInit(Tcl_Interp *pintrp)
627 {
628
629     if (Tcl_InitStubs(pintrp, TCL_VERSION, 1) == NULL)
630         Panic (pintrp,"Tcl stub's initialisation failed!");
631         
632     if (Tcl_Init(pintrp) == TCL_ERROR)
633         Panic (pintrp,"Tcl's initialisation failed!");
634     
635     if (Tk_Init(pintrp) == TCL_ERROR)
636         Panic (pintrp,"Tk's initialisation failed!");
637
638     return TCL_OK;
639 }
640
641 // main body ------------------------------------------------------------------
642
643 int main(int argc, char* argv[])
644 {
645     module_path = GetPathFromModuleName( argv[0] );
646
647     Tcl_Interp* g_pInterp = Tcl_CreateInterp();
648     
649     Tcl_SetPanicProc(WishPanic);
650     Tcl_FindExecutable(argv[0]);
651
652     MainEx(argc, argv, Tcl_AppInit, g_pInterp, "cvlkdemo.tcl");
653
654     cvcamExit();
655
656     return 0;
657 }