bazar  1.3.1
interactive.cpp
Go to the documentation of this file.
1 
6 #include <iostream>
7 #include "cv.h"
8 #include "highgui.h"
9 #include <garfeild.h>
10 
11 #ifdef WIN32
12 #include <sys/timeb.h>
13 #else
14 #include <config.h>
15 #include <sys/time.h>
16 #endif
17 
18 char *modelFile="model.jpg";
19 
20 void acquire_model(CvCapture *capture, planar_object_recognizer &detector);
21 void show_result(planar_object_recognizer &recognizer, IplImage *video, IplImage **dst);
22 
23 using namespace std;
24 
25 void usage(const char *s) {
26  cerr << "usage:\n" << s
27  << "[<cam number>|<video file>] [-m <model image>]\n";
28  exit(1);
29 }
30 
31 int main( int argc, char** argv )
32 {
33  CvCapture* capture = 0;
34 
35  //cvSetErrMode(CV_ErrModeParent);
36 
37  const char *captureSrc = "0";
38 
39  // parse command line
40  for (int i=1; i<argc; i++) {
41  if (strcmp(argv[i], "-m") ==0) {
42  if (i==argc-1) usage(argv[0]);
43  modelFile = argv[i+1];
44  i++;
45  } else if (argv[i][0]=='-') {
46  usage(argv[0]);
47  } else {
48  captureSrc = argv[i];
49  }
50  }
51 
52  if(strlen(captureSrc) == 1 && isdigit(captureSrc[0]))
53  capture = cvCaptureFromCAM( captureSrc[0]-'0');
54  else
55  capture = cvCaptureFromAVI( captureSrc );
56 
57  if( !capture )
58  {
59  cerr <<"Could not initialize capturing from " << captureSrc << " ...\n";
60  return -1;
61  }
62 
63  cout << "Instructions:\n"
64  " 1 - present a textured planar object to the camera. \n"
65  " 2 - push space to freeze the image\n"
66  " 3 - if the frozen image makes a good model image, press 'y'.\n"
67  " Otherwise, press space to restart the video and take another shot. \n";
68 
69  // Allocate the detector object
70  planar_object_recognizer detector;
71 
72 
73  // Train or load classifier
74  if(!detector.build_with_cache(
75  string(modelFile), // mode image file name
76  400, // maximum number of keypoints on the model
77  32, // patch size in pixels
78  3, // yape radius. Use 3,5 or 7.
79  16, // number of trees for the classifier. Somewhere between 12-50
80  3 // number of levels in the gaussian pyramid
81  ))
82  {
83  // interactively acquire a model image
84  acquire_model(capture, detector);
85  }
86 
87  // A lower threshold will allow detection in harder conditions, but
88  // might lead to false positives.
89  detector.match_score_threshold=.03f;
90 
91  const char *win = "Bazar";
92 
93  IplImage* display=0;
94  IplImage*gray=0;
95 
96  cvNamedWindow(win, CV_WINDOW_AUTOSIZE);
97 
98 #ifdef WIN32
99  struct timeb last, now;
100  ftime(&last);
101 #else
102  struct timeval last, now;
103  gettimeofday(&last,0);
104 #endif
105 
106  int nbFrames=0;
107 
108  for(;;)
109  {
110  IplImage* frame = 0;
111 
112  // acquire image
113  frame = cvQueryFrame( capture );
114  if( !frame )
115  break;
116 
117  // convert it to gray levels, if required
118  if (frame->nChannels >1) {
119  if( !gray )
120  gray = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
121  cvCvtColor(frame, gray, CV_RGB2GRAY);
122  } else {
123  gray = frame;
124  }
125 
126  // run the detector
127  if (detector.detect(gray)) {
128  }
129  show_result(detector, frame, &display);
130  cvShowImage(win, display);
131  //cvShowImage(win, frame);
132 
133  if (nbFrames==4) {
134  nbFrames=0;
135 
136  double duration;
137 
138 #ifdef WIN32
139  ftime(&now);
140  duration = ( double(( now.time-last.time ) * 1e4)
141  + double( now.millitm-last.millitm ) ) / 1e4;
142 #else
143  gettimeofday(&now,0);
144  duration = double(now.tv_sec-last.tv_sec)
145  + double(now.tv_usec-last.tv_usec)/1e6;
146 #endif
147 
148  last = now;
149 
150  cout << "FPS: " << 5.0/duration << endl;
151  } else {
152  nbFrames++;
153  }
154 
155  if( cvWaitKey(1) >= 0 )
156  break;
157  }
158 
159  cvReleaseCapture( &capture );
160  cvDestroyWindow(win);
161 
162  return 0;
163 }
164 
165 void show_result(planar_object_recognizer &detector, IplImage *video, IplImage **dst)
166 {
167  if (*dst==0) *dst=cvCloneImage(video);
168  else cvCopy(video, *dst);
169 
170  if (detector.object_is_detected) {
171  for (int i=0; i<detector.match_number; ++i) {
172 
173  image_object_point_match * match = detector.matches+i;
174  if (match->inlier) {
175  cvCircle(*dst,
176  cvPoint((int) (PyrImage::convCoordf(match->image_point->u,
177  int(match->image_point->scale), 0)),
178  (int)(PyrImage::convCoordf(match->image_point->v,
179  int(match->image_point->scale), 0))),
180  3, CV_RGB(0,255,0), -1, 8,0);
181  }
182  }
183  }
184 }
185 
186 void acquire_model(CvCapture *capture, planar_object_recognizer &detector)
187 {
188 
189  const char *win = "Bazar";
190 
191  cvNamedWindow(win, CV_WINDOW_AUTOSIZE);
192 
193  bool pause=false;
194  IplImage *frame;
195  IplImage *shot=0;
196 
197  bool accepted =false;
198  while (!accepted) {
199 
200  if (!pause) {
201  frame = cvQueryFrame(capture);
202  cvShowImage(win, frame);
203  }
204 
205  int k = cvWaitKey(pause ? 50 : 1);
206  switch (k) {
207  case ' ':
208  pause = !pause;
209  if (pause) {
210  if (shot) cvCopy(frame,shot);
211  else shot = cvCloneImage(frame);
212  cvShowImage(win, shot);
213  }
214  break;
215  case 'y':
216  case '\n': if (pause && shot) accepted=true; break;
217  case 'q': exit(0); break;
218  }
219  }
220 
221  cvSaveImage(modelFile, shot);
222  detector.build(shot, 400, 32, 3, 16, 3);
223  detector.save(string(modelFile)+".classifier");
224  cvReleaseImage(&shot);
225 }