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