Visual Servoing Platform  version 3.5.1 under development (2023-06-19)
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>
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 #if VISP_HAVE_DATASET_VERSION >= 0x030600
84  std::string ext("png");
85 #else
86  std::string ext("pgm");
87 #endif
88  fprintf(stdout, "\n\
89 Test dot tracking.\n\
90 \n\
91 SYNOPSIS\n\
92  %s [-i <input image path>] [-c] [-d] [-h]\n",
93  name);
94 
95  fprintf(stdout, "\n\
96 OPTIONS: Default\n\
97  -i <input image path> %s\n\
98  Set image input path.\n\
99  From this path read image \n\
100  \"cube/image.0000.%s\"\n\
101  Setting the VISP_INPUT_IMAGE_PATH environment\n\
102  variable produces the same behaviour than using\n\
103  this option.\n\
104 \n\
105  -c\n\
106  Disable the mouse click. Useful to automaze the \n\
107  execution of this program without humain intervention.\n\
108 \n\
109  -d \n\
110  Turn off the display.\n\
111 \n\
112  -h\n\
113  Print the help.\n",
114  ipath.c_str(), ext.c_str());
115 
116  if (badparam)
117  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
118 }
131 bool getOptions(int argc, const char **argv, std::string &ipath, bool &click_allowed, bool &display)
132 {
133  const char *optarg_;
134  int c;
135  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
136 
137  switch (c) {
138  case 'c':
139  click_allowed = false;
140  break;
141  case 'd':
142  display = false;
143  break;
144  case 'i':
145  ipath = optarg_;
146  break;
147  case 'h':
148  usage(argv[0], NULL, ipath);
149  return false;
150  break;
151 
152  default:
153  usage(argv[0], optarg_, ipath);
154  return false;
155  break;
156  }
157  }
158 
159  if ((c == 1) || (c == -1)) {
160  // standalone param or error
161  usage(argv[0], NULL, ipath);
162  std::cerr << "ERROR: " << std::endl;
163  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
164  return false;
165  }
166 
167  return true;
168 }
169 
170 int main(int argc, const char **argv)
171 {
172  try {
173  std::string env_ipath;
174  std::string opt_ipath;
175  std::string ipath;
176  std::string dirname;
177  std::string filenameRef;
178  std::string filenameCur;
179  bool opt_click_allowed = true;
180  bool opt_display = true;
181 
182 #if VISP_HAVE_DATASET_VERSION >= 0x030600
183  std::string ext("png");
184 #else
185  std::string ext("pgm");
186 #endif
187  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
188  // environment variable value
189  env_ipath = vpIoTools::getViSPImagesDataPath();
190 
191  // Set the default input path
192  if (!env_ipath.empty())
193  ipath = env_ipath;
194 
195  // Read the command line options
196  if (getOptions(argc, argv, opt_ipath, opt_click_allowed, opt_display) == false) {
197  return EXIT_FAILURE;
198  }
199 
200  // Get the option values
201  if (!opt_ipath.empty())
202  ipath = opt_ipath;
203 
204  // Compare ipath and env_ipath. If they differ, we take into account
205  // the input path comming from the command line option
206  if (!opt_ipath.empty() && !env_ipath.empty()) {
207  if (ipath != env_ipath) {
208  std::cout << std::endl << "WARNING: " << std::endl;
209  std::cout << " Since -i <visp image path=" << ipath << "> "
210  << " is different from VISP_IMAGE_PATH=" << env_ipath << std::endl
211  << " we skip the environment variable." << std::endl;
212  }
213  }
214 
215  // Test if an input path is set
216  if (opt_ipath.empty() && env_ipath.empty()) {
217  usage(argv[0], NULL, ipath);
218  std::cerr << std::endl << "ERROR:" << std::endl;
219  std::cerr << " Use -i <visp image path> option or set VISP_INPUT_IMAGE_PATH " << std::endl
220  << " environment variable to specify the location of the " << std::endl
221  << " image path where test images are located." << std::endl
222  << std::endl;
223  return EXIT_FAILURE;
224  }
225 
226  // Declare an image, this is a gray level image (unsigned char)
227  // it size is not defined yet, it will be defined when the image will
228  // read on the disk
231 
232  // Set the path location of the image sequence
233  dirname = vpIoTools::createFilePath(ipath, "cube");
234 
235  // Build the name of the image file
236  filenameRef = vpIoTools::createFilePath(dirname, "image.0000." + ext);
237  filenameCur = vpIoTools::createFilePath(dirname, "image.0079." + ext);
238 
239  // Read image named "filename" and put the bitmap in I
240  try {
241  std::cout << "Load: " << filenameRef << std::endl;
242 
243  vpImageIo::read(Iref, filenameRef);
244 
245  std::cout << "Load: " << filenameCur << std::endl;
246 
247  vpImageIo::read(Icur, filenameCur);
248  } catch (...) {
249  std::cerr << std::endl << "ERROR:" << std::endl;
250  std::cerr << " Cannot read " << filenameRef << "or" << filenameCur << std::endl;
251  std::cerr << " Check your -i " << ipath << " option " << std::endl
252  << " or VISP_INPUT_IMAGE_PATH environment variable." << std::endl;
253  return EXIT_FAILURE;
254  }
255 
256 // We open a window using either X11, GTK or GDI.
257 #if defined VISP_HAVE_X11
258  vpDisplayX display[2];
259 #elif defined VISP_HAVE_GTK
260  vpDisplayGTK display[2];
261 #elif defined VISP_HAVE_GDI
262  vpDisplayGDI display[2];
263 #else
264  vpDisplayOpenCV display[2];
265 #endif
266 
267  if (opt_display) {
268  // Display size is automatically defined by the image (I) size
269  display[0].init(Iref, 100, 100, "Reference image");
270  // Display the image
271  // The image class has a member that specify a pointer toward
272  // the display that has been initialized in the display declaration
273  // therefore is is no longer necessary to make a reference to the
274  // display variable.
275  vpDisplay::display(Iref);
276  // Flush the display
277  vpDisplay::flush(Iref);
278  }
279 
280  vpKeyPointSurf surf;
281  unsigned int nbrRef;
282 
283  if (opt_click_allowed && opt_display) {
284  std::cout << "Select a part of the image where the reference points "
285  "will be computed. This part is a rectangle."
286  << std::endl;
287  std::cout << "Click first on the top left corner and then on the "
288  "bottom right corner."
289  << std::endl;
290  vpImagePoint corners[2];
291  for (int i = 0; i < 2; i++) {
292  vpDisplay::getClick(Iref, corners[i]);
293  }
294 
295  vpDisplay::displayRectangle(Iref, corners[0], corners[1], vpColor::red);
296  vpDisplay::flush(Iref);
297  unsigned int height, width;
298  height = (unsigned int)(corners[1].get_i() - corners[0].get_i());
299  width = (unsigned int)(corners[1].get_j() - corners[0].get_j());
300 
301  // Computes the reference points
302  nbrRef = surf.buildReference(Iref, corners[0], height, width);
303  }
304 
305  else {
306  nbrRef = surf.buildReference(Iref);
307  }
308 
309  if (nbrRef < 1) {
310  std::cerr << "No reference point" << std::endl;
311  return EXIT_FAILURE;
312  }
313 
314  unsigned int nbrPair;
315  if (opt_display) {
316  display[1].init(Icur, (int)(100 + Iref.getWidth()), 100, "Current image");
317  // display variable.
318  vpDisplay::display(Icur);
319  // Flush the display
320  vpDisplay::flush(Icur);
321  }
322 
323  if (opt_click_allowed && opt_display) {
324  std::cout << "Select a part of the current image where the reference "
325  "will be search. This part is a rectangle."
326  << std::endl;
327  std::cout << "Click first on the top left corner and then on the "
328  "bottom right corner."
329  << std::endl;
330  vpImagePoint corners[2];
331  for (int i = 0; i < 2; i++) {
332  vpDisplay::getClick(Icur, corners[i]);
333  }
334  vpDisplay::displayRectangle(Icur, corners[0], corners[1], vpColor::green);
335  vpDisplay::flush(Icur);
336  unsigned int height, width;
337  height = (unsigned int)(corners[1].get_i() - corners[0].get_i());
338  width = (unsigned int)(corners[1].get_j() - corners[0].get_j());
339 
340  // Computes the reference points
341  nbrPair = surf.matchPoint(Icur, corners[0], height, width);
342  }
343 
344  else {
345  nbrPair = surf.matchPoint(Icur);
346  }
347 
348  if (nbrPair < 1) {
349  std::cout << "No point matched" << std::endl;
350  }
351 
352  if (opt_display) {
353  surf.display(Iref, Icur, 7);
354  vpDisplay::flush(Iref);
355  vpDisplay::flush(Icur);
356  if (opt_click_allowed) {
357  std::cout << "A click on the reference image to exit..." << std::endl;
358  vpDisplay::getClick(Iref);
359  }
360  }
361  } catch (const vpException &e) {
362  std::cout << "Catch an exception: " << e << std::endl;
363  return EXIT_FAILURE;
364  }
365  return EXIT_SUCCESS;
366 }
367 #else
368 int main()
369 {
370  std::cerr << "You do not have 1.1.0 <= OpenCV < 2.3.0 that contains "
371  "opencv_nonfree component..."
372  << std::endl;
373  return EXIT_SUCCESS;
374 }
375 
376 #endif
static const vpColor red
Definition: vpColor.h:217
static const vpColor green
Definition: vpColor.h:220
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:129
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:135
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:135
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void flush(const vpImage< unsigned char > &I)
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)
error that can be emited by ViSP classes.
Definition: vpException.h:72
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:148
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:89
double get_j() const
Definition: vpImagePoint.h:132
double get_i() const
Definition: vpImagePoint.h:121
unsigned int getWidth() const
Definition: vpImage.h:247
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1399
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1764
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69
Class that implements the SURF key points and technics thanks to the OpenCV library.