ViSP
 All Classes Functions Variables Enumerations Enumerator Friends Groups Pages
testSurfKeyPoint.cpp
1 /****************************************************************************
2  *
3  * $Id: testSurfKeyPoint.cpp 4137 2013-02-14 06:56:53Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Test auto detection of dots.
36  *
37  * Authors:
38  * Nicolas Melchior
39  *
40  *****************************************************************************/
41 
42 
43 
44 #include <visp/vpDebug.h>
45 #include <visp/vpConfig.h>
46 #include <stdlib.h>
47 #include <stdio.h>
48 #include <sstream>
49 #include <iomanip>
50 #if ((defined (VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI)) && defined(VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION >= 0x010100)) // Require opencv >= 1.1.0
51 
52 #include <visp/vpKeyPointSurf.h>
53 #include <visp/vpImage.h>
54 #include <visp/vpImageIo.h>
55 #include <visp/vpDisplayX.h>
56 #include <visp/vpDisplayGTK.h>
57 #include <visp/vpDisplayGDI.h>
58 
59 
60 #include <visp/vpCameraParameters.h>
61 
62 #include <visp/vpParseArgv.h>
63 #include <visp/vpIoTools.h>
64 
71 // List of allowed command line options
72 #define GETOPTARGS "cdi:h"
73 
83 void usage(const char *name, const char *badparam, std::string ipath)
84 {
85  fprintf(stdout, "\n\
86 Test dot tracking.\n\
87 \n\
88 SYNOPSIS\n\
89  %s [-i <input image path>] [-c] [-d] [-h]\n", name);
90 
91  fprintf(stdout, "\n\
92 OPTIONS: Default\n\
93  -i <input image path> %s\n\
94  Set image input path.\n\
95  From this path read image \n\
96  \"ViSP-images/ellipse/ellipse.pgm\"\n\
97  Setting the VISP_INPUT_IMAGE_PATH environment\n\
98  variable produces the same behaviour than using\n\
99  this option.\n\
100 \n\
101  -c\n\
102  Disable the mouse click. Useful to automaze the \n\
103  execution of this program without humain intervention.\n\
104 \n\
105  -d \n\
106  Turn off the display.\n\
107 \n\
108  -h\n\
109  Print the help.\n",
110  ipath.c_str());
111 
112  if (badparam)
113  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
114 
115 }
128 bool getOptions(int argc, const char **argv, std::string &ipath,
129  bool &click_allowed, bool &display)
130 {
131  const char *optarg;
132  int c;
133  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg)) > 1) {
134 
135  switch (c) {
136  case 'c': click_allowed = false; break;
137  case 'd': display = false; break;
138  case 'i': ipath = optarg; break;
139  case 'h': usage(argv[0], NULL, ipath); return false; break;
140 
141  default:
142  usage(argv[0], optarg, ipath);
143  return false; break;
144  }
145  }
146 
147  if ((c == 1) || (c == -1)) {
148  // standalone param or error
149  usage(argv[0], NULL, ipath);
150  std::cerr << "ERROR: " << std::endl;
151  std::cerr << " Bad argument " << optarg << std::endl << std::endl;
152  return false;
153  }
154 
155  return true;
156 }
157 
158 
159 int
160 main(int argc, const char ** argv)
161 {
162  std::string env_ipath;
163  std::string opt_ipath;
164  std::string ipath;
165  std::string dirname;
166  std::string filenameRef;
167  std::string filenameCur;
168  bool opt_click_allowed = true;
169  bool opt_display = true;
170 
171  // Get the VISP_IMAGE_PATH environment variable value
172  char *ptenv = getenv("VISP_INPUT_IMAGE_PATH");
173  if (ptenv != NULL)
174  env_ipath = ptenv;
175 
176  // Set the default input path
177  if (! env_ipath.empty())
178  ipath = env_ipath;
179 
180 
181  // Read the command line options
182  if (getOptions(argc, argv, opt_ipath,
183  opt_click_allowed, opt_display) == false) {
184  exit (-1);
185  }
186 
187  // Get the option values
188  if (!opt_ipath.empty())
189  ipath = opt_ipath;
190 
191  // Compare ipath and env_ipath. If they differ, we take into account
192  // the input path comming from the command line option
193  if (!opt_ipath.empty() && !env_ipath.empty()) {
194  if (ipath != env_ipath) {
195  std::cout << std::endl
196  << "WARNING: " << std::endl;
197  std::cout << " Since -i <visp image path=" << ipath << "> "
198  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
199  << " we skip the environment variable." << std::endl;
200  }
201  }
202 
203  // Test if an input path is set
204  if (opt_ipath.empty() && env_ipath.empty()){
205  usage(argv[0], NULL, ipath);
206  std::cerr << std::endl
207  << "ERROR:" << std::endl;
208  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH "
209  << std::endl
210  << " environment variable to specify the location of the " << std::endl
211  << " image path where test images are located." << std::endl << std::endl;
212  exit(-1);
213  }
214 
215 
216  // Declare an image, this is a gray level image (unsigned char)
217  // it size is not defined yet, it will be defined when the image will
218  // read on the disk
221 
222  // Set the path location of the image sequence
223  dirname = ipath + vpIoTools::path("/ViSP-images/cube/");
224 
225  // Build the name of the image file
226  filenameRef = dirname + "image.0000.pgm";
227  filenameCur = dirname + "image.0079.pgm";
228 
229  // Read the PGM image named "filename" on the disk, and put the
230  // bitmap into the image structure I. I is initialized to the
231  // correct size
232  //
233  // exception readPGM may throw various exception if, for example,
234  // the file does not exist, or if the memory cannot be allocated
235  try{
236  vpCTRACE << "Load: " << filenameRef << std::endl;
237 
238  vpImageIo::readPGM(Iref, filenameRef) ;
239 
240  vpCTRACE << "Load: " << filenameCur << std::endl;
241 
242  vpImageIo::readPGM(Icur, filenameCur) ;
243  }
244  catch(...)
245  {
246  // an exception is throwned if an exception from readPGM has been catched
247  // here this will result in the end of the program
248  // Note that another error message has been printed from readPGM
249  // to give more information about the error
250  std::cerr << std::endl
251  << "ERROR:" << std::endl;
252  std::cerr << " Cannot read " << filenameRef << "or" << filenameCur <<std::endl;
253  std::cerr << " Check your -i " << ipath << " option " << std::endl
254  << " or VISP_INPUT_IMAGE_PATH environment variable."
255  << std::endl;
256  exit(-1);
257  }
258 
259  // We open a window using either X11, GTK or GDI.
260 #if defined VISP_HAVE_X11
261  vpDisplayX display[2];
262 #elif defined VISP_HAVE_GTK
263  vpDisplayGTK display[2];
264 #elif defined VISP_HAVE_GDI
265  vpDisplayGDI display[2];
266 #endif
267 
268  if (opt_display) {
269  try{
270  // Display size is automatically defined by the image (I) size
271  display[0].init(Iref, 100, 100, "Reference image") ;
272  // Display the image
273  // The image class has a member that specify a pointer toward
274  // the display that has been initialized in the display declaration
275  // therefore is is no longuer necessary to make a reference to the
276  // display variable.
277  vpDisplay::display(Iref) ;
278  //Flush the display
279  vpDisplay::flush(Iref) ;
280  }
281  catch(...)
282  {
283  vpERROR_TRACE("Error while displaying the image") ;
284  exit(-1);
285  }
286  }
287 
288  vpKeyPointSurf surf;
289  unsigned int nbrRef;
290 
291  if (opt_click_allowed && opt_display)
292  {
293  std::cout << "Select a part of the image where the reference points will be computed. This part is a rectangle." << std::endl;
294  std::cout << "Click first on the top left corner and then on the bottom right corner." << std::endl;
295  vpImagePoint corners[2];
296  for (int i=0 ; i < 2 ; i++)
297  {
298  vpDisplay::getClick(Iref, corners[i]);
299  }
300 
301  vpDisplay::displayRectangle(Iref, corners[0], corners[1], vpColor::red);
302  vpDisplay::flush(Iref);
303  unsigned int height, width;
304  height = (unsigned int)(corners[1].get_i() - corners[0].get_i());
305  width = (unsigned int)(corners[1].get_j() - corners[0].get_j());
306 
307  //Computes the reference points
308  nbrRef = surf.buildReference(Iref, corners[0], height, width);
309  }
310 
311  else
312  {
313  nbrRef = surf.buildReference(Iref);
314  }
315 
316  if(nbrRef < 1)
317  {
318  vpTRACE("No reference point");
319  exit(-1);
320  }
321 
322 
323  unsigned int nbrPair;
324  if (opt_display) {
325  display[1].init(Icur, (int)(100+Iref.getWidth()), 100, "Current image") ;
326  // display variable.
327  vpDisplay::display(Icur) ;
328  //Flush the display
329  vpDisplay::flush(Icur) ;
330  }
331 
332  if (opt_click_allowed && opt_display)
333  {
334  std::cout << "Select a part of the current image where the reference will be search. This part is a rectangle." << std::endl;
335  std::cout << "Click first on the top left corner and then on the bottom right corner." << std::endl;
336  vpImagePoint corners[2];
337  for (int i=0 ; i < 2 ; i++)
338  {
339  vpDisplay::getClick(Icur, corners[i]);
340  }
341  vpDisplay::displayRectangle(Icur, corners[0], corners[1], vpColor::green);
342  vpDisplay::flush(Icur);
343  unsigned int height, width;
344  height = (unsigned int)(corners[1].get_i() - corners[0].get_i());
345  width = (unsigned int)(corners[1].get_j() - corners[0].get_j());
346 
347  //Computes the reference points
348  nbrPair = surf.matchPoint(Icur, corners[0], height, width);
349  }
350 
351  else
352  {
353  nbrPair = surf.matchPoint(Icur);
354  }
355 
356  if(nbrPair < 1)
357  {
358  vpTRACE("No point matched");
359  }
360 
361  if (opt_display)
362  {
363  surf.display(Iref, Icur, 7);
364  vpDisplay::flush(Iref) ;
365  vpDisplay::flush(Icur) ;
366  if (opt_click_allowed)
367  {
368  std::cout << "A click on the reference image to exit..." << std::endl;
369  vpDisplay::getClick(Iref);
370  }
371  }
372 
373  return (0);
374 }
375 #else
376 int
377 main()
378 {
379 #if ( ! (defined (VISP_HAVE_X11) || defined(VISP_HAVE_GTK) || defined(VISP_HAVE_GDI)) )
380  vpERROR_TRACE("You do not have X11, GTK or GDI display functionalities...");
381 #else
382  vpERROR_TRACE("You do not have OpenCV-1.1.0 or a more recent release that contains opencv_nonfree component...");
383 #endif
384 }
385 
386 #endif