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