1 #include "calibmodel.h"
4 CalibModel::CalibModel()
9 win
= "The Artvertiser 0.4";
12 CalibModel::~CalibModel()
14 if (image
) cvReleaseImage(&image
);
17 void CalibModel::useModelFile(const char* file
)
22 CalibModel
*objectPtr
=0;
24 void CalibModel::onMouse(int event
, int x
, int y
, int flags
)
27 if ( state
== ARTVERT_CORNERS
)
28 ptr
= artvert_corners
;
31 if (event
== CV_EVENT_LBUTTONDOWN
)
33 // try to grab something
35 for (int i
=0; i
<4; i
++)
39 if (sqrt((double)(dx
*dx
+dy
*dy
)) <10) {
52 if (event
== CV_EVENT_LBUTTONUP
)
58 bool CalibModel::buildCached(int nbcam
, CvCapture
*capture
, bool cache
, planar_object_recognizer
&detector
, bool dont_try_to_train
)
64 detector
.ransac_dist_threshold
= 5;
65 detector
.max_ransac_iterations
= 800;
66 //detector.ransac_stop_support = 50;
67 //detector.non_linear_refine_threshold = 15.0f;
68 //detector.point_detector_tau = 10;
70 // A lower threshold will allow detection in harder conditions, but
71 // might lead to false positives.
72 detector
.match_score_threshold
=.03f
;
74 detector
.min_view_rate
=.1;
75 detector
.views_number
= 1000;
77 //detector.min_view_rate = .2;
79 static const int MAX_MODEL_KEYPOINTS
= 500; // maximum number of keypoints on the model
80 static const int PATCH_SIZE
= 32; // patch size in pixels
81 static const int YAPE_RADIUS
= 5; // yape radius
82 static const int NUM_TREES
= 12; // num classifier trees
83 static const int NUM_GAUSSIAN_LEVELS
= 3; // num gaussian levels
84 /*static const int MAX_MODEL_KEYPOINTS = 500; // maximum number of keypoints on the model
85 static const int PATCH_SIZE = 32; // patch size in pixels
86 static const int YAPE_RADIUS = 5; // yape radius
87 static const int NUM_TREES = 12; // num classifier trees
88 static const int NUM_GAUSSIAN_LEVELS = 3; // num gaussian levels*/
91 // Should we train or load the classifier ?
93 printf("model.buildCached() trying to load from %s...\n", modelfile
);
94 if(cache
&& detector
.build_with_cache(
95 string(modelfile
), // mode image file name
96 /*500, // maximum number of keypoints on the model
97 //200, // maximum number of keypoints on the model
98 32, // patch size in pixels
99 5, // yape radius. Use 3,5 or 7.
100 //3, // yape radius. Use 3,5 or 7.
101 12, // number of trees for the classifier. Somewhere between 12-50
102 //20, // number of trees for the classifier. Somewhere between 12-50
103 3*/ // number of levels in the gaussian pyramid
105 MAX_MODEL_KEYPOINTS
, // max keypoints
106 PATCH_SIZE
, // patch size
107 YAPE_RADIUS
, // yape radius. Use 3,5 or 7.
108 NUM_TREES
, // number of trees for the classifier. Somewhere between 12-50
109 NUM_GAUSSIAN_LEVELS
// number of levels in the gaussian pyramid
113 // loading worked. Remember the region of interest.
114 corners
[0].x
= detector
.new_images_generator
.u_corner1
;
115 corners
[0].y
= detector
.new_images_generator
.v_corner1
;
116 corners
[1].x
= detector
.new_images_generator
.u_corner2
;
117 corners
[1].y
= detector
.new_images_generator
.v_corner2
;
118 corners
[2].x
= detector
.new_images_generator
.u_corner3
;
119 corners
[2].y
= detector
.new_images_generator
.v_corner3
;
120 corners
[3].x
= detector
.new_images_generator
.u_corner4
;
121 corners
[3].y
= detector
.new_images_generator
.v_corner4
;
123 MultiThreadCapture
* mtc
= MultiThreadCaptureManager::getInstance()->getCaptureForCam(capture
);
125 IplImage* init_image = NULL;
129 got = mtc->getCopyOfLastFrame( &init_image );
132 !usleep( 10*1000 ) &&
134 if ( init_image == NULL )
136 printf("getCopyOfLastFrame timed out: capture failed\n");
142 cvReleaseImage( &image
);
143 image
= cvLoadImage(modelfile
, mtc
->getNumChannelsRaw()==3 );
144 image_width
= image
->width
;
145 image_height
= image
->height
;
146 //cvReleaseImage(&init_image);
148 /*printf("dumping loaded cache:\n");
156 cvReleaseImage( &image
);
158 // ask the user the take a shot of the model
159 if ( !cache
&& dont_try_to_train
)
161 printf("CalibModel: would normally try to train now but we were told not to\n");
166 if (!interactiveSetup(capture
))
168 printf("interactiveSetup failed\n");
174 image_width
= image
->width
;
175 image_height
= image
->height
;
177 // train the classifier to detect this model
178 //if (!detector.build(image, 500, 32, 3, 12, 3,0, 0))
179 //if (!detector.build(image, 200, 32, 5, 20, 3,0, 0))
180 int working_roi
[8] = { corners
[0].x
, corners
[0].y
,
181 corners
[1].x
, corners
[1].y
,
182 corners
[2].x
, corners
[2].y
,
183 corners
[3].x
, corners
[3].y
185 LEARNPROGRESSION progress
;
186 if (!detector
.build(image
,
187 MAX_MODEL_KEYPOINTS
, // max keypoints
188 PATCH_SIZE
, // patch size
189 YAPE_RADIUS
, // yape radius. Use 3,5 or 7.
190 NUM_TREES
, // number of trees for the classifier. Somewhere between 12-50
191 NUM_GAUSSIAN_LEVELS
, // number of levels in the gaussian pyramid
196 printf("build based on interactiveSetup failed\n");
204 if (!cvSaveImage(modelfile
, image
))
206 printf("saving input image failed\n");
212 // and the region of interest (ROI)
213 string roifn
= string(modelfile
) + ".roi";
214 ofstream
roif(roifn
.c_str());
219 printf("saving .roi file failed\n");
222 for (int i
=0;i
<4; i
++)
223 roif
<< corners
[i
].x
<< " " << corners
[i
].y
<< "\n";
226 // and the artvert corners
227 roifn
= string(modelfile
) + ".artvertroi";
228 ofstream
artvert_roif(roifn
.c_str());
229 if (!artvert_roif
.good())
233 printf("saving .artvertroi file failed\n");
236 for (int i
=0;i
<4; i
++)
237 artvert_roif
<< artvert_corners
[i
].x
<< " " << artvert_corners
[i
].y
<< "\n";
238 artvert_roif
.close();
240 // and the trained classifier
241 string classifier_directory
= string(modelfile
)+".classifier";
242 detector
.save(classifier_directory
);
244 string stable_points_filename
= string(modelfile
)+"_stable_points.bmp";
245 printf("saving stable points to %s\n", stable_points_filename
.c_str());
246 detector
.save_image_of_model_points(PATCH_SIZE
, stable_points_filename
.c_str() );
248 const char* initial_points_filename
= "initial_model_points.bmp";
249 string initial_points_new_filename
= string(modelfile
)+"_initial_points.bmp";
250 printf("renaming %s to %s\n", initial_points_filename
, initial_points_new_filename
.c_str() );
251 rename(initial_points_filename
, initial_points_new_filename
.c_str() );
253 /*printf("dumping trained cache:\n");
259 assert( detector
.isReady() );
262 for (int i
=0; i
<4; i
++)
264 cn
[i
][0] = corners
[i
].x
;
265 cn
[i
][1] = corners
[i
].y
;
266 cout
<< corners
[i
].x
<< " " << corners
[i
].y
<< endl
;
269 // prepare the light calibration reference
270 return map
.init(nbcam
, image
, cn
, 8, 6);
273 static void putText(IplImage
*im
, const char *text
, CvPoint p
, CvFont
*f1
)
275 cvPutText(im
,text
,p
,f1
, cvScalar(0,255, 255));
279 IplImage
*myRetrieveFrame(CvCapture
*capture
)
281 #ifdef USE_MULTITHREADCAPTURE
282 assert(false && "don't call myRetrieveFrame when USE_MULTITHREADCAPTURE");
285 static IplImage
*s
=0;
286 IplImage
*frame
=cvRetrieveFrame(capture
);
287 if (frame
== 0) return 0;
289 if (frame
->nChannels
==1) {
290 printf(" PERFORMANCE WARNING: myRetrieveFrame converting colour\n");
291 if (!s
) s
=cvCreateImage(cvSize(frame
->width
,frame
->height
), IPL_DEPTH_8U
, 3);
292 cvCvtColor(frame
,s
,CV_GRAY2BGR
);
296 printf(" PERFORMANCE WARNING: myRetrieveFrame flipping\n");
297 if (!s
) s
=cvCreateImage(cvSize(frame
->width
,frame
->height
), IPL_DEPTH_8U
, 3);
305 IplImage
*myQueryFrame(CvCapture
*capture
)
307 #ifdef USE_MULTITHREADCAPTURE
308 assert(false && "don't call myQueryFrame when USE_MULTITHREADCAPTURE");
311 cvGrabFrame(capture
);
312 return myRetrieveFrame(capture
);
317 bool CalibModel::interactiveSetup(CvCapture
*capture
)
320 CvFont font
, fontbold
;
322 cvInitFont(&font
, CV_FONT_HERSHEY_SIMPLEX
, .5, .5, 0, 0, CV_AA
);
324 cvNamedWindow(win
, CV_WINDOW_AUTOSIZE
);
328 cvSetMouseCallback(win
, onMouseStatic
, this);
331 #ifdef USE_MULTITHREADCAPTURE
332 IplImage
*frame_gray
, *frame
= NULL
;
334 MultiThreadCapture
* mtc
= MultiThreadCaptureManager::getInstance()->getCaptureForCam(capture
);
338 got
= mtc
->getLastDetectFrame( &frame_gray
, &frame
, ×tamp
, /*blocking*/true );
342 (timeout
-=100) > 0 );
345 printf("capture failed\n");
349 IplImage
*frame
= myQueryFrame(capture
);
351 IplImage
*shot
=0, *text
=0;
355 bool accepted
=false;
356 bool artvert_accepted
= false;
360 char k
= cvWaitKey(10);
362 if (k
==27 || k
=='q') {
363 if (shot
) cvReleaseImage(&shot
);
364 if (text
) cvReleaseImage(&text
);
368 // clear text or grab the image to display
369 if (!pause
|| shot
==0) {
370 #ifdef USE_MULTITHREADCAPTURE
371 bool got
= mtc
->getLastDetectFrame( &frame_gray
, &frame
, NULL
,/*block until available*/true );
375 frame
= myQueryFrame(capture
);
378 text
=cvCreateImage(cvGetSize(frame
), IPL_DEPTH_8U
, 3);
382 corners
[1].x
= frame
->width
-d
;
384 corners
[2].x
= frame
->width
-d
;
385 corners
[2].y
= frame
->height
-d
;
387 corners
[3].y
= frame
->height
-d
;
389 if (frame
->nChannels
==1)
390 cvCvtColor(frame
, text
, CV_GRAY2BGR
);
394 if (shot
->nChannels
==1)
395 cvCvtColor(shot
, text
, CV_GRAY2BGR
);
402 // display text / react to keyboard
407 if (shot
) cvCopy(frame
,shot
);
408 else shot
= cvCloneImage(frame
);
413 putText(text
, modelfile
, cvPoint(3,20), &font
);
414 putText(text
,"Please take a frontal view", cvPoint(3,40), &font
);
415 putText(text
,"of a textured planar surface", cvPoint(3,60), &font
);
416 putText(text
,"and press space", cvPoint(3,80), &font
);
420 putText(text
, modelfile
, cvPoint(3,20), &font
);
421 putText(text
, "Drag yellow corners to match the", cvPoint(3,40), &font
);
422 putText(text
, "calibration target", cvPoint(3,60), &font
);
423 putText(text
, "press 'r' to restart", cvPoint(3,80), &font
);
424 putText(text
, "press space when ready", cvPoint(3,100), &font
);
430 for ( int i
=0;i
<4; i
++ )
432 artvert_corners
[i
].x
= corners
[i
].x
;
433 artvert_corners
[i
].y
= corners
[i
].y
;
435 state
= ARTVERT_CORNERS
;
438 cvPolyLine(text
, &ptr
, &four
, 1, 1,
441 case ARTVERT_CORNERS
:
442 putText(text
, "Drag red corners to match the", cvPoint(3,20), &font
);
443 putText(text
, "artvert target area;", cvPoint(3,40), &font
);
444 putText(text
, "press 'r' to restart", cvPoint(3,60), &font
);
445 putText(text
, "press space when ready", cvPoint(3,80), &font
);
454 cvPolyLine(text
, &ptr
, &four
, 1, 1,
456 ptr
= artvert_corners
;
457 cvPolyLine(text
, &ptr
, &four
, 1, 1,
461 cvShowImage(win
, text
);
464 cvReleaseImage(&text
);
467 cvDestroyWindow( win
);
468 // make sure the destroy window succeeds
474 void CalibModel::onMouseStatic(int event
, int x
, int y
, int flags
, void* param
)
477 ((CalibModel
*)param
)->onMouse(event
,x
,y
,flags
);
479 objectPtr
->onMouse(event
,x
,y
,flags
);
481 cerr
<< "onMouseStatic(): null-pointer.\n";