bazar  1.3.1
augment3d.cpp
Go to the documentation of this file.
1 
9 #include <iostream>
10 #include "cv.h"
11 #include "highgui.h"
12 #include <garfeild.h>
13 
14 #ifdef HAVE_CONFIG_H
15 #include <config.h>
16 #endif
17 
18 char *modelFile="model.jpg";
19 
21 void show_result(CamAugmentation &augment, IplImage *video, IplImage **dst);
22 
23 void usage(const char *s) {
24  cerr << "usage:\n" << s
25  << "[<cam number>|<video file>] [-m <model image>]\n";
26  exit(1);
27 }
28 
29 int main( int argc, char** argv )
30 {
31  CvCapture* capture = 0;
32 
33  const char *captureSrc = "0";
34 
35  // parse command line
36  for (int i=1; i<argc; i++) {
37  if (strcmp(argv[i], "-m") ==0) {
38  if (i==argc-1) usage(argv[0]);
39  modelFile = argv[i+1];
40  i++;
41  } else if (argv[i][0]=='-') {
42  usage(argv[0]);
43  } else {
44  captureSrc = argv[i];
45  }
46  }
47 
48  if(strlen(captureSrc) == 1 && isdigit(captureSrc[0]))
49  capture = cvCaptureFromCAM( captureSrc[0]-'0');
50  else
51  capture = cvCaptureFromAVI( captureSrc );
52 
53  if( !capture )
54  {
55  cerr <<"Could not initialize capturing from " << captureSrc << " ...\n";
56  return -1;
57  }
58 
59  // Allocate the detector object
60  planar_object_recognizer detector;
61 
62  // fine tuning for accuracy
63  detector.ransac_dist_threshold = 5;
64  detector.max_ransac_iterations = 800;
65  detector.non_linear_refine_threshold = 2.5;
66 
67  // Train or load classifier
68  if(!detector.build_with_cache(
69  string(modelFile), // mode image file name
70  400, // maximum number of keypoints on the model
71  32, // patch size in pixels
72  3, // yape radius. Use 3,5 or 7.
73  16, // number of trees for the classifier. Somewhere between 12-50
74  1 // number of levels in the gaussian pyramid
75  ))
76  {
77  cerr << "Unable to load the model image "
78  << modelFile <<" or its classifier.\n";
79  return -1;
80  }
81 
82  // A lower threshold will allow detection in harder conditions, but
83  // might lead to false positives.
84  detector.match_score_threshold=.03f;
85 
86  const char *win = "Bazar";
87 
88  IplImage* display=0;
89  IplImage*gray=0;
90 
91  cvNamedWindow(win, 0);
92 
93  CamAugmentation augment;
94 
95  if (!augment.LoadOptimalStructureFromFile("camera_c.txt", "camera_r_t.txt")) {
96  cerr << "Unable to load calibration data\n";
97  return -2;
98  }
99 
100  for(;;)
101  {
102  // acquire image
103  IplImage *frame = cvQueryFrame( capture );
104  if( !frame )
105  break;
106 
107  // convert it to gray levels, if required
108  if (frame->nChannels >1) {
109  if( !gray )
110  gray = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
111  cvCvtColor(frame, gray, CV_RGB2GRAY);
112  } else {
113  gray = frame;
114  }
115 
116  // run the detector
117  if (detector.detect(gray)) {
118  // start on a new frame
119  augment.Clear();
120 
121  // we have only 1 camera
122  add_detected_homography(detector, augment);
123 
124  // bundle adjust
125  augment.Accomodate(4, 1e-4);
126  show_result(augment, frame, &display);
127  cvShowImage(win,display);
128  } else {
129  cvShowImage(win, frame);
130  }
131  //cvShowImage(win, frame);
132 
133  if( cvWaitKey(10) >= 0 )
134  break;
135  }
136 
137  cvReleaseCapture( &capture );
138  cvDestroyWindow(win);
139 
140  return 0;
141 }
142 
143 void show_result(CamAugmentation &augment, IplImage *video, IplImage **dst)
144 {
145  if (*dst==0) *dst=cvCloneImage(video);
146  else cvCopy(video, *dst);
147 
148  CvMat *m = augment.GetProjectionMatrix(0);
149  if (!m) return;
150 
151  double w =video->width/2.0;
152  double h =video->height/2.0;
153 
154  // 3D coordinates of an object
155  double pts[4][4] = {
156  {w,h,0, 1},
157  {2*w,h,0, 1},
158  {w,2*h,0, 1},
159  {w,h,-w-h, 1}
160  };
161  double projected[3][4];
162  CvMat ptsMat, projectedMat;
163  cvInitMatHeader(&ptsMat, 4, 4, CV_64FC1, pts);
164  cvInitMatHeader(&projectedMat, 3, 4, CV_64FC1, projected);
165 
166  // project the 4 3D points
167  cvGEMM(m, &ptsMat, 1, 0, 0, &projectedMat, CV_GEMM_B_T );
168  for (int i=0; i<4; i++) {
169  projected[0][i] /= projected[2][i];
170  projected[1][i] /= projected[2][i];
171  }
172 
173  // draw the projected lines
174  cvLine(*dst, cvPoint((int)projected[0][0], (int)projected[1][0]),
175  cvPoint((int)projected[0][1], (int)projected[1][1]), CV_RGB(0,255,0));
176  cvLine(*dst, cvPoint((int)projected[0][0], (int)projected[1][0]),
177  cvPoint((int)projected[0][2], (int)projected[1][2]), CV_RGB(255,0,0));
178  cvLine(*dst, cvPoint((int)projected[0][0], (int)projected[1][0]),
179  cvPoint((int)projected[0][3], (int)projected[1][3]), CV_RGB(0,0,255));
180 
181 
182  cvReleaseMat(&m);
183 }
184 
186 {
187  static std::vector<CamCalibration::s_struct_points> pts;
188  pts.clear();
189 
190  for (int i=0; i<detector.match_number; ++i) {
191  image_object_point_match * match = detector.matches+i;
192  if (match->inlier) {
193  pts.push_back(CamCalibration::s_struct_points(
194  PyrImage::convCoordf(match->image_point->u, int(match->image_point->scale), 0),
195  PyrImage::convCoordf(match->image_point->v, int(match->image_point->scale), 0),
196  PyrImage::convCoordf(match->object_point->M[0], int(match->object_point->scale), 0),
197  PyrImage::convCoordf(match->object_point->M[1], int(match->object_point->scale), 0)));
198  }
199  }
200 
201  a.AddHomography(pts, detector.H);
202  return true;
203 }