gpl license text and copyright added to all files
[The-Artvertiser.git] / artvertiser / calibmodel.cpp
blob67e7809c3da74d0c2715b0bc0985649be16fcf81
1 /*
2 Copyright 2008, 2009, 2010 Julian Oliver <julian@julianoliver.com>
3 and Damian Stewart <damian@frey.co.nz>, based on BazAR which is
4 Copyright 2005, 2006 Computer Vision Lab, 3 Ecole Polytechnique
5 Federale de Lausanne (EPFL), Switzerland.
6 Distributed under the terms of the GNU General Public License v3.
8 This file is part of The Artvertiser.
10 The Artvertiser is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 The Artvertiser is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public License
21 along with The Artvertiser. If not, see <http://www.gnu.org/licenses/>.
24 #include "calibmodel.h"
25 #include "multigrab.h"
27 char CalibModel::progress_string[2048];
29 CalibModel::CalibModel()
31 image=0;
32 image_width = 0;
33 image_height = 0;
34 win = "The Artvertiser 0.4";
35 train_working_image = 0;
36 interactive_train_running = false;
37 interactive_train_should_stop = false;
38 debounce_green = false;
39 debounce_redblue = false;
40 strcpy(progress_string, "");
41 learn_running = false;
43 cvInitFont(&train_font, CV_FONT_HERSHEY_SIMPLEX, .5, .5, 0, 0, CV_AA);
46 CalibModel::~CalibModel()
48 if (image) cvReleaseImage(&image);
49 if ( train_working_image )
51 cvReleaseImage( &train_working_image );
52 cvReleaseImage( &train_shot );
56 void CalibModel::useModelFile(const char* file)
58 modelfile = file;
61 CalibModel *objectPtr=0;
63 void CalibModel::onMouse(int event, int x, int y, int flags)
65 CvPoint* ptr;
66 if ( state == ARTVERT_CORNERS )
67 ptr = artvert_corners;
68 else
69 ptr = corners;
70 if (event == CV_EVENT_LBUTTONDOWN)
72 // try to grab something
73 grab = -1;
74 for (int i=0; i<4; i++)
76 int dx = x-ptr[i].x;
77 int dy = y-ptr[i].y;
78 if (sqrt((double)(dx*dx+dy*dy)) <10) {
79 grab = i;
80 break;
85 if (grab!=-1)
87 ptr[grab].x = x;
88 ptr[grab].y = y;
91 if (event == CV_EVENT_LBUTTONUP)
93 grab=-1;
97 bool CalibModel::buildCached(int nbcam, CvCapture *capture,
98 bool cache, planar_object_recognizer &detector,
99 bool running_on_binoculars )
102 detector.clear();
104 printf("buildCached about to grab a lock\n");
106 detector.lock();
109 detector.ransac_dist_threshold = 5;
110 detector.max_ransac_iterations = 800;
111 //detector.ransac_stop_support = 50;
112 //detector.non_linear_refine_threshold = 15.0f;
113 //detector.point_detector_tau = 10;
115 // A lower threshold will allow detection in harder conditions, but
116 // might lead to false positives.
117 detector.match_score_threshold=.03f;
119 detector.min_view_rate=.1;
120 detector.views_number = 1000;
121 // damian below
122 //detector.min_view_rate = .2;
124 static const int MAX_MODEL_KEYPOINTS = 500; // maximum number of keypoints on the model
125 static const int PATCH_SIZE = 32; // patch size in pixels
126 static const int YAPE_RADIUS = 5; // yape radius
127 static const int NUM_TREES = 12; // num classifier trees
128 static const int NUM_GAUSSIAN_LEVELS = 3; // num gaussian levels
129 /*static const int MAX_MODEL_KEYPOINTS = 500; // maximum number of keypoints on the model
130 static const int PATCH_SIZE = 32; // patch size in pixels
131 static const int YAPE_RADIUS = 5; // yape radius
132 static const int NUM_TREES = 12; // num classifier trees
133 static const int NUM_GAUSSIAN_LEVELS = 3; // num gaussian levels*/
136 // Should we train or load the classifier ?
137 if ( cache )
138 printf("model.buildCached() trying to load from %s...\n", modelfile );
139 if(cache && detector.build_with_cache(
140 string(modelfile), // mode image file name
141 /*500, // maximum number of keypoints on the model
142 //200, // maximum number of keypoints on the model
143 32, // patch size in pixels
144 5, // yape radius. Use 3,5 or 7.
145 //3, // yape radius. Use 3,5 or 7.
146 12, // number of trees for the classifier. Somewhere between 12-50
147 //20, // number of trees for the classifier. Somewhere between 12-50
148 3*/ // number of levels in the gaussian pyramid
149 // damian below
150 MAX_MODEL_KEYPOINTS, // max keypoints
151 PATCH_SIZE, // patch size
152 YAPE_RADIUS, // yape radius. Use 3,5 or 7.
153 NUM_TREES, // number of trees for the classifier. Somewhere between 12-50
154 NUM_GAUSSIAN_LEVELS // number of levels in the gaussian pyramid
158 // loading worked. Remember the region of interest.
159 corners[0].x = detector.new_images_generator.u_corner1;
160 corners[0].y = detector.new_images_generator.v_corner1;
161 corners[1].x = detector.new_images_generator.u_corner2;
162 corners[1].y = detector.new_images_generator.v_corner2;
163 corners[2].x = detector.new_images_generator.u_corner3;
164 corners[2].y = detector.new_images_generator.v_corner3;
165 corners[3].x = detector.new_images_generator.u_corner4;
166 corners[3].y = detector.new_images_generator.v_corner4;
168 MultiThreadCapture* mtc = MultiThreadCaptureManager::getInstance()->getCaptureForCam(capture);
170 IplImage* init_image = NULL;
171 int timeout = 10000;
172 bool got = false;
173 do {
174 got = mtc->getCopyOfLastFrame( &init_image );
176 while ( !got &&
177 !usleep( 10*1000 ) &&
178 (timeout-=10) > 0 );
179 if ( init_image == NULL )
181 printf("getCopyOfLastFrame timed out: capture failed\n");
182 detector.unlock();
183 detector.clear();
184 return false;
186 if ( image != 0 )
187 cvReleaseImage( &image );
188 image = cvLoadImage(modelfile, mtc->getNumChannelsRaw()==3 );
189 image_width = image->width;
190 image_height = image->height;
191 //cvReleaseImage(&init_image);
193 /*printf("dumping loaded cache:\n");
194 detector.dump();
198 else
200 if ( image != 0 )
201 cvReleaseImage( &image );
202 image =0;
203 // ask the user the take a shot of the model
204 bool result = false;
205 if( running_on_binoculars )
206 result = interactiveTrainBinoculars();
207 else
208 result = interactiveSetup(capture);
209 if (!result)
211 printf("interactiveSetup failed\n");
212 detector.unlock();
213 detector.clear();
214 return false;
216 else
218 printf("interactiveSetup succeeded\n");
221 image_width = image->width;
222 image_height = image->height;
224 // train the classifier to detect this model
225 //if (!detector.build(image, 500, 32, 3, 12, 3,0, 0))
226 //if (!detector.build(image, 200, 32, 5, 20, 3,0, 0))
227 int working_roi[8] = { corners[0].x, corners[0].y,
228 corners[1].x, corners[1].y,
229 corners[2].x, corners[2].y,
230 corners[3].x, corners[3].y
232 //LEARNPROGRESSION progress;
233 //LEARNPROGRESSION progress = 0;
235 printf("about to call detector.build...\n");
236 learn_running = true;
237 strcpy(progress_string, "preparing..");
238 if (!detector.build(image,
239 MAX_MODEL_KEYPOINTS, // max keypoints
240 PATCH_SIZE, // patch size
241 YAPE_RADIUS, // yape radius. Use 3,5 or 7.
242 NUM_TREES, // number of trees for the classifier. Somewhere between 12-50
243 NUM_GAUSSIAN_LEVELS, // number of levels in the gaussian pyramid
244 &learnProgressionFunc,
245 working_roi
248 learn_running = false;
249 printf("build based on interactiveSetup failed\n");
250 detector.unlock();
251 detector.clear();
252 return false;
255 printf("detector.build succeeded\n");
256 strcpy( progress_string, "saving..\n");
257 // save the image
258 if (!cvSaveImage(modelfile, image))
260 printf("saving input image failed\n");
261 learn_running = false;
262 detector.unlock();
263 detector.clear();
264 return false;
267 // and the region of interest (ROI)
268 string roifn = string(modelfile) + ".roi";
269 ofstream roif(roifn.c_str());
270 if (!roif.good())
272 learn_running = false;
273 detector.unlock();
274 detector.clear();
275 printf("saving .roi file failed\n");
276 return false;
278 for (int i=0;i<4; i++)
279 roif << corners[i].x << " " << corners[i].y << "\n";
280 roif.close();
282 // and the artvert corners
283 roifn = string(modelfile) + ".artvertroi";
284 ofstream artvert_roif(roifn.c_str());
285 if (!artvert_roif.good())
287 learn_running = false;
288 detector.unlock();
289 detector.clear();
290 printf("saving .artvertroi file failed\n");
291 return false;
293 for (int i=0;i<4; i++)
294 artvert_roif << artvert_corners[i].x << " " << artvert_corners[i].y << "\n";
295 artvert_roif.close();
297 // and the trained classifier
298 string classifier_directory = string(modelfile)+".classifier";
299 detector.save(classifier_directory);
301 string stable_points_filename = string(modelfile)+"_stable_points.bmp";
302 printf("saving stable points to %s\n", stable_points_filename.c_str());
303 detector.save_image_of_model_points(PATCH_SIZE, stable_points_filename.c_str() );
305 const char* initial_points_filename = "initial_model_points.bmp";
306 string initial_points_new_filename = string(modelfile)+"_initial_points.bmp";
307 printf("renaming %s to %s\n", initial_points_filename, initial_points_new_filename.c_str() );
308 rename(initial_points_filename, initial_points_new_filename.c_str() );
310 /*printf("dumping trained cache:\n");
311 detector.dump();*/
313 learn_running = false;
316 detector.unlock();
317 assert( detector.isReady() );
319 float cn[4][2];
320 for (int i=0; i<4; i++)
322 cn[i][0] = corners[i].x;
323 cn[i][1] = corners[i].y;
324 cout << corners[i].x << " " << corners[i].y << endl;
327 // prepare the light calibration reference
328 return map.init(nbcam, image, cn, 8, 6);
331 static void putText(IplImage *im, const char *text, CvPoint p, CvFont *f1)
333 cvPutText(im,text,p,f1, cvScalar(0,255, 255));
337 IplImage *myRetrieveFrame(CvCapture *capture)
339 #ifdef USE_MULTITHREADCAPTURE
340 assert(false && "don't call myRetrieveFrame when USE_MULTITHREADCAPTURE");
341 #endif
343 static IplImage *s=0;
344 IplImage *frame =cvRetrieveFrame(capture);
345 if (frame == 0) return 0;
346 IplImage *ret=frame;
347 if (frame->nChannels==1) {
348 printf(" PERFORMANCE WARNING: myRetrieveFrame converting colour\n");
349 if (!s) s=cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 3);
350 cvCvtColor(frame,s,CV_GRAY2BGR);
351 ret = s;
353 if (ret->origin) {
354 printf(" PERFORMANCE WARNING: myRetrieveFrame flipping\n");
355 if (!s) s=cvCreateImage(cvSize(frame->width,frame->height), IPL_DEPTH_8U, 3);
356 cvFlip(ret, s);
357 ret->origin=0;
358 ret = s;
360 return ret;
363 IplImage *myQueryFrame(CvCapture *capture)
365 #ifdef USE_MULTITHREADCAPTURE
366 assert(false && "don't call myQueryFrame when USE_MULTITHREADCAPTURE");
367 #endif
369 cvGrabFrame(capture);
370 return myRetrieveFrame(capture);
374 bool CalibModel::interactiveTrainBinoculars()
376 // setup
377 state = TAKE_SHOT;
378 train_should_proceed = false;
379 // we want the interactive training to run
380 interactive_train_running = true;
381 interactive_train_should_stop = false;
382 debounce_green = true;
383 debounce_redblue = true;
385 // wait until done
386 int timeout =5*60;
387 // 5 minute time out
388 while ( interactive_train_running && !interactive_train_should_stop && timeout>0 )
390 printf("waiting for interactiveTrainBinoculars to complete .. %i\n", timeout );
391 timeout-=5;
392 sleep(5);
395 return train_should_proceed;
398 void CalibModel::interactiveTrainBinocularsUpdate( IplImage* frame,
399 bool button_red,
400 bool button_green,
401 bool button_blue )
403 if ( !interactive_train_running )
404 return;
406 if ( interactive_train_should_stop )
408 interactive_train_running = false;
409 return;
412 // copy to training
413 if ( train_working_image == 0 )
415 train_working_image = cvCreateImage( cvGetSize( frame ), frame->depth, frame->nChannels );
416 train_shot = cvCreateImage( cvGetSize( frame ), frame->depth, frame->nChannels );
419 // inputs
420 bool R__ = ( button_red&&!button_green&&!button_blue);
421 bool _G_ = (!button_red&& button_green&&!button_blue);
422 bool __B = (!button_red&&!button_green&& button_blue);
423 bool RG_ = ( button_red&& button_green&&!button_blue);
424 bool _GB = (!button_red&& button_green&& button_blue);
425 bool R_B = ( button_red&&!button_green&& button_blue);
426 bool RGB = ( button_red&& button_green&& button_blue);
428 // debounce
430 // don't allow just green if we're trying to debounce
431 if ( !button_green )
432 debounce_green = false;
433 else if ( debounce_green && _G_ )
434 _G_ = false;
436 // don't allow red+blue if we're trying to debounce
437 if ( !button_red || !button_blue )
438 debounce_redblue = false;
439 else if ( debounce_redblue && R_B )
440 R_B = false;
442 // for drawing
443 int four = 4;
444 CvPoint *ptr;
445 int oldx, oldy;
447 // update
448 switch( state )
450 case TAKE_SHOT:
451 if ( _G_ )
453 // advance
454 cvCopy( frame, train_shot );
455 state = CORNERS;
456 int d = 30;
457 corners[0].x = d;
458 corners[0].y = d;
459 corners[1].x = frame->width-d;
460 corners[1].y = d;
461 corners[2].x = frame->width-d;
462 corners[2].y = frame->height-d;
463 corners[3].x = d;
464 corners[3].y = frame->height-d;
465 // setup index
466 corner_index=0;
467 x = corners[corner_index].x;
468 y = corners[corner_index].y;
469 // debounce the green button
470 debounce_green = true;
472 else if ( R_B )
474 // abort
475 interactive_train_running = false;
476 debounce_redblue = true;
478 else
480 cvCopy( frame, train_working_image );
481 putText(train_working_image, modelfile, cvPoint(3,20), &train_font );
482 putText(train_working_image,"Please take a frontal view", cvPoint(3,40), &train_font);
483 putText(train_working_image,"of a textured planar surface", cvPoint(3,60), &train_font);
484 putText(train_working_image,"and press green", cvPoint(3,80), &train_font);
485 putText(train_working_image,"Press red+blue to abort", cvPoint(3,100), &train_font);
487 break;
488 case CORNERS:
489 cvCopy( train_shot, train_working_image );
490 putText(train_working_image, modelfile, cvPoint(3,20), &train_font);
491 putText(train_working_image, "Move green corners to match the", cvPoint(3,40), &train_font);
492 putText(train_working_image, "calibration target", cvPoint(3,60), &train_font);
493 putText(train_working_image, "Press red+blue to restart", cvPoint(3,80), &train_font);
494 putText(train_working_image, "Press green when ready", cvPoint(3,100), &train_font);
496 oldx=x; oldy=y;
497 if ( R__ )
498 x += 1;
499 else if ( __B )
500 x -= 1;
501 else if ( RG_ )
502 y += 1;
503 else if ( _GB )
504 y -= 1;
505 // update corner if necessary
506 if ( oldx != x )
507 corners[corner_index].x = x;
508 if ( oldy != y )
509 corners[corner_index].y = y;
510 // continue checking buttons
511 if ( _G_ )
513 // accept
514 corners[corner_index].x = x;
515 corners[corner_index].y = y;
516 corner_index++;
517 if ( corner_index > 3 )
519 // next
520 corner_index = 0;
521 for ( int i=0; i<4; i++ )
522 artvert_corners[i] = corners[i];
523 state = ARTVERT_CORNERS;
525 // setup index
526 corner_index=0;
527 x = artvert_corners[corner_index].x;
528 y = artvert_corners[corner_index].y;
530 else
532 x = corners[corner_index].x;
533 y = corners[corner_index].y;
536 debounce_green = true;
538 else if ( R_B )
540 // back
541 corner_index--;
542 if ( corner_index < 0 )
543 state = TAKE_SHOT;
544 else
546 x = corners[corner_index].x;
547 y = corners[corner_index].y;
549 debounce_redblue = true;
552 ptr = corners;
553 cvPolyLine(train_working_image, &ptr, &four, 1, 1,
554 cvScalar(0,255,0));
555 cvCircle( train_working_image, corners[corner_index], 10, cvScalar(0,255,0));
557 break;
559 case ARTVERT_CORNERS:
560 cvCopy( train_shot, train_working_image );
561 putText(train_working_image, modelfile, cvPoint(3,20), &train_font);
562 putText(train_working_image, "Move red corners to match the", cvPoint(3,40), &train_font);
563 putText(train_working_image, "artvert target area;", cvPoint(3,60), &train_font);
564 putText(train_working_image, "Press red+blue to restart", cvPoint(3,80), &train_font);
565 putText(train_working_image, "Press green when ready", cvPoint(3,100), &train_font);
567 oldx = x; oldy = y;
568 if ( R__ )
569 x += 1;
570 else if ( __B )
571 x -= 1;
572 else if ( RG_ )
573 y += 1;
574 else if ( _GB )
575 y -= 1;
576 // update corner if necessary
577 if ( oldx != x )
578 artvert_corners[corner_index].x = x;
579 if ( oldy != y )
580 artvert_corners[corner_index].y = y;
581 // continue checking buttons
582 if ( _G_ )
584 // accept
585 artvert_corners[corner_index].x = x;
586 artvert_corners[corner_index].y = y;
587 corner_index++;
588 if ( corner_index > 3 )
590 // finished
591 if ( image != 0 )
592 cvReleaseImage( &image );
593 image = cvCreateImage( cvGetSize( train_shot), train_shot->depth, train_shot->nChannels );
594 cvCopy( train_shot, image );
595 train_should_proceed = true;
596 interactive_train_running = false;
598 else
600 x = artvert_corners[corner_index].x;
601 y = artvert_corners[corner_index].y;
603 debounce_green = true;
605 else if ( R_B )
607 // back
608 corner_index--;
609 if ( corner_index < 0 )
610 state = CORNERS;
611 else
613 x = artvert_corners[corner_index].x;
614 y = artvert_corners[corner_index].y;
616 debounce_redblue = true;
620 ptr = corners;
621 cvPolyLine(train_working_image, &ptr, &four, 1, 1,
622 cvScalar(0,255,0));
623 ptr = artvert_corners;
624 cvPolyLine(train_working_image, &ptr, &four, 1, 1,
625 cvScalar(0,0,255));
626 cvCircle( train_working_image, artvert_corners[corner_index], 10, cvScalar(0,0,255));
628 break;
631 train_texture.setImage( train_working_image );
635 void CalibModel::interactiveTrainBinocularsDraw()
637 if ( !interactive_train_running )
638 return;
640 IplTexture* tex = &train_texture;
642 IplImage *im = tex->getIm();
643 int w = im->width-1;
644 int h = im->height-1;
646 glMatrixMode(GL_PROJECTION);
647 glLoadIdentity();
648 glMatrixMode(GL_MODELVIEW);
649 glLoadIdentity();
651 glDisable(GL_BLEND);
652 glDisable(GL_DEPTH_TEST);
654 tex->loadTexture();
656 glBegin(GL_QUADS);
657 glColor4f(1,1,1,1);
659 glTexCoord2f(tex->u(0), tex->v(0));
660 glVertex2f(-1, 1);
661 glTexCoord2f(tex->u(w), tex->v(0));
662 glVertex2f(1, 1);
663 glTexCoord2f(tex->u(w), tex->v(h));
664 glVertex2f(1, -1);
665 glTexCoord2f(tex->u(0), tex->v(h));
666 glVertex2f(-1, -1);
667 glEnd();
669 tex->disableTexture();
674 bool CalibModel::interactiveSetup(CvCapture *capture )
680 CvFont font, fontbold;
682 cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, .5, .5, 0, 0, CV_AA);
684 cvNamedWindow(win, CV_WINDOW_AUTOSIZE);
685 grab=-1;
687 objectPtr = this;
688 cvSetMouseCallback(win, onMouseStatic, this);
690 bool pause=false;
692 IplImage *frame_gray, *frame = NULL;
693 FTime timestamp;
694 MultiThreadCapture* mtc = MultiThreadCaptureManager::getInstance()->getCaptureForCam(capture);
695 int timeout = 10000;
696 bool got = false;
697 do {
698 got = mtc->getLastDetectFrame( &frame_gray, &frame, &timestamp, /*blocking*/true );
700 while ( !got &&
701 !usleep( 100000 ) &&
702 (timeout-=100) > 0 );
703 if ( frame == NULL )
705 printf("capture failed\n");
706 return false;
709 IplImage *shot=0, *text=0;
711 state = TAKE_SHOT;
713 bool accepted =false;
714 bool artvert_accepted = false;
715 while (!accepted) {
717 // wait for a key
718 char k = cvWaitKey(10);
720 if (k==27 || k=='q') {
721 if (shot) cvReleaseImage(&shot);
722 if (text) cvReleaseImage(&text);
723 return false;
726 // clear text or grab the image to display
727 if (!pause || shot==0) {
728 bool got = mtc->getLastDetectFrame( &frame_gray, &frame, NULL,/*block until available*/true );
729 if ( !got )
730 continue;
731 if (!text) {
732 text=cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
733 int d = 30;
734 corners[0].x = d;
735 corners[0].y = d;
736 corners[1].x = frame->width-d;
737 corners[1].y = d;
738 corners[2].x = frame->width-d;
739 corners[2].y = frame->height-d;
740 corners[3].x = d;
741 corners[3].y = frame->height-d;
743 if (frame->nChannels==1)
744 cvCvtColor(frame, text, CV_GRAY2BGR);
745 else
746 cvCopy(frame,text);
747 } else {
748 if (shot->nChannels==1)
749 cvCvtColor(shot, text, CV_GRAY2BGR);
750 else
751 cvCopy(shot, text);
754 int four = 4;
755 CvPoint *ptr;
756 // display text / react to keyboard
757 switch (state) {
758 default:
759 case TAKE_SHOT:
760 if (k==' ') {
761 if (shot) cvCopy(frame,shot);
762 else shot = cvCloneImage(frame);
763 pause = true;
764 state = CORNERS;
765 k=-1;
766 } else {
767 putText(text, modelfile, cvPoint(3,20), &font);
768 putText(text,"Please take a frontal view", cvPoint(3,40), &font);
769 putText(text,"of a textured planar surface", cvPoint(3,60), &font);
770 putText(text,"and press space", cvPoint(3,80), &font);
771 break;
773 case CORNERS:
774 putText(text, modelfile, cvPoint(3,20), &font);
775 putText(text, "Drag green corners to match the", cvPoint(3,40), &font);
776 putText(text, "calibration target", cvPoint(3,60), &font);
777 putText(text, "press 'r' to restart", cvPoint(3,80), &font);
778 putText(text, "press space when ready", cvPoint(3,100), &font);
779 if (k=='r') {
780 pause = false;
781 state = TAKE_SHOT;
783 if (k==' ') {
784 for ( int i=0;i<4; i++ )
786 artvert_corners[i].x = corners[i].x;
787 artvert_corners[i].y = corners[i].y;
789 state = ARTVERT_CORNERS;
791 ptr = corners;
792 cvPolyLine(text, &ptr, &four, 1, 1,
793 cvScalar(0,255,0));
794 break;
795 case ARTVERT_CORNERS:
796 putText(text, "Drag red corners to match the", cvPoint(3,20), &font);
797 putText(text, "artvert target area;", cvPoint(3,40), &font);
798 putText(text, "press 'r' to restart", cvPoint(3,60), &font);
799 putText(text, "press space when ready", cvPoint(3,80), &font);
800 if (k=='r') {
801 pause = false;
802 state = TAKE_SHOT;
804 if (k==' ') {
805 accepted = true;
807 ptr = corners;
808 cvPolyLine(text, &ptr, &four, 1, 1,
809 cvScalar(0,255,0));
810 ptr = artvert_corners;
811 cvPolyLine(text, &ptr, &four, 1, 1,
812 cvScalar(0,0,255));
813 break;
815 cvShowImage(win, text);
818 cvReleaseImage(&text);
819 image = shot;
821 cvDestroyWindow( win );
822 // make sure the destroy window succeeds
823 cvWaitKey(0);
825 return true;
828 void CalibModel::onMouseStatic(int event, int x, int y, int flags, void* param)
830 if (param)
831 ((CalibModel *)param)->onMouse(event,x,y,flags);
832 if (objectPtr)
833 objectPtr->onMouse(event,x,y,flags);
834 else
835 cerr << "onMouseStatic(): null-pointer.\n";
839 void CalibModel::learnProgressionFunc( int phase, int current, int total )
841 sprintf(progress_string, "learning, phase %i/4: %4.1f%%", phase+1, 100.0f*float(current)/total );
842 if ( current==0 )
843 printf("\n");
844 printf("\rphase %i/4: %4i/%4i ", phase+1, current, total);
845 fflush(stdout);
847 /*for ( int i=0; i<4; i++ )
849 if ( phase > i )
850 strcat(progress_string, "[----------------------------------------]\n" );
851 else if ( phase == i )
853 float finishedPct = float(current)/float(total);
854 int count = finishedPct*40;
855 strcat(progress_string, "[");
856 for ( int j=0; j<count; j++ )
858 strcat(progress_string, "-");
860 for ( int j=0; j<40-count; j++ )
862 strcat(progress_string, " ");
864 strcat(progress_string, "]\n");
866 else
867 strcat( progress_string, "[ ]\n");