Visual Servoing Platform  version 3.6.1 under development (2024-11-15)
testKeyPoint.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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 keypoint matching.
32  */
33 
40 #include <iostream>
41 
42 #include <visp3/core/vpConfig.h>
43 
44 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_FEATURES2D) && defined(HAVE_OPENCV_VIDEO)
45 
46 #include <visp3/core/vpImage.h>
47 #include <visp3/core/vpIoTools.h>
48 #include <visp3/gui/vpDisplayGDI.h>
49 #include <visp3/gui/vpDisplayGTK.h>
50 #include <visp3/gui/vpDisplayOpenCV.h>
51 #include <visp3/gui/vpDisplayX.h>
52 #include <visp3/io/vpImageIo.h>
53 #include <visp3/io/vpParseArgv.h>
54 #include <visp3/io/vpVideoReader.h>
55 #include <visp3/vision/vpKeyPoint.h>
56 
57 // List of allowed command line options
58 #define GETOPTARGS "cdh"
59 
60 #ifdef ENABLE_VISP_NAMESPACE
61 using namespace VISP_NAMESPACE_NAME;
62 #endif
63 
64 void usage(const char *name, const char *badparam);
65 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
66 
75 void usage(const char *name, const char *badparam)
76 {
77  fprintf(stdout, "\n\
78  Test keypoints matching.\n\
79  \n\
80  SYNOPSIS\n\
81  %s [-c] [-d] [-h]\n",
82  name);
83 
84  fprintf(stdout, "\n\
85  OPTIONS: \n\
86  \n\
87  -c\n\
88  Disable the mouse click. Useful to automate the \n\
89  execution of this program without human intervention.\n\
90  \n\
91  -d \n\
92  Turn off the display.\n\
93  \n\
94  -h\n\
95  Print the help.\n");
96 
97  if (badparam)
98  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
99 }
100 
112 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
113 {
114  const char *optarg_;
115  int c;
116  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
117 
118  switch (c) {
119  case 'c':
120  click_allowed = false;
121  break;
122  case 'd':
123  display = false;
124  break;
125  case 'h':
126  usage(argv[0], nullptr);
127  return false;
128  break;
129 
130  default:
131  usage(argv[0], optarg_);
132  return false;
133  break;
134  }
135  }
136 
137  if ((c == 1) || (c == -1)) {
138  // standalone param or error
139  usage(argv[0], nullptr);
140  std::cerr << "ERROR: " << std::endl;
141  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
142  return false;
143  }
144 
145  return true;
146 }
147 
148 template <typename Type>
149 void run_test(const std::string &env_ipath, bool opt_click_allowed, bool opt_display, vpImage<Type> &Iref,
150  vpImage<Type> &Icur, vpImage<Type> &Imatch)
151 {
152 #if VISP_HAVE_DATASET_VERSION >= 0x030600
153  std::string ext("png");
154 #else
155  std::string ext("pgm");
156 #endif
157  // Set the path location of the image sequence
158  std::string dirname = vpIoTools::createFilePath(env_ipath, "mbt/cube");
159 
160  // Build the name of the image files
161  std::string filenameRef = vpIoTools::createFilePath(dirname, "image0000." + ext);
162  vpImageIo::read(Iref, filenameRef);
163  std::string filenameCur = vpIoTools::createFilePath(dirname, "image%04d." + ext);
164 
165  // Init keypoints
166  vpKeyPoint keypoints("ORB", "ORB", "BruteForce-Hamming");
167  std::cout << "Build " << keypoints.buildReference(Iref) << " reference points." << std::endl;
168 
169  vpVideoReader g;
170  g.setFileName(filenameCur);
171  g.open(Icur);
172  g.acquire(Icur);
173 
174  Imatch.resize(Icur.getHeight(), 2 * Icur.getWidth());
175  Imatch.insert(Iref, vpImagePoint(0, 0));
176 
177 #if defined(VISP_HAVE_X11)
178  vpDisplayX display;
179 #elif defined(VISP_HAVE_GTK)
180  vpDisplayGTK display;
181 #elif defined(VISP_HAVE_GDI)
182  vpDisplayGDI display;
183 #elif defined(HAVE_OPENCV_HIGHGUI)
184  vpDisplayOpenCV display;
185 #endif
186 
187  if (opt_display) {
188  display.setDownScalingFactor(vpDisplay::SCALE_AUTO);
189  display.init(Imatch, 0, 0, "ORB keypoints matching");
190  }
191 
192  bool opt_click = false;
194  while (!g.end()) {
195  g.acquire(Icur);
196  Imatch.insert(Icur, vpImagePoint(0, Icur.getWidth()));
197 
198  if (opt_display) {
199  vpDisplay::display(Imatch);
200  }
201 
202  // Match keypoints
203  keypoints.matchPoint(Icur);
204  // Display image with keypoints matched
205  keypoints.displayMatching(Iref, Imatch);
206 
207  if (opt_display) {
208  vpDisplay::flush(Imatch);
209  }
210 
211  // Click requested to process next image
212  if (opt_click_allowed && opt_display) {
213  if (opt_click) {
214  vpDisplay::getClick(Imatch, button, true);
215  if (button == vpMouseButton::button3) {
216  opt_click = false;
217  }
218  }
219  else {
220  // Use right click to enable/disable step by step tracking
221  if (vpDisplay::getClick(Imatch, button, false)) {
222  if (button == vpMouseButton::button3) {
223  opt_click = true;
224  }
225  else if (button == vpMouseButton::button1) {
226  break;
227  }
228  }
229  }
230  }
231  }
232 }
233 
234 int main(int argc, const char **argv)
235 {
236  try {
237  std::string env_ipath;
238  bool opt_click_allowed = true;
239  bool opt_display = true;
240 
241  // Read the command line options
242  if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
243  return EXIT_FAILURE;
244  }
245 
246  // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
247  // environment variable value
248  env_ipath = vpIoTools::getViSPImagesDataPath();
249 
250  if (env_ipath.empty()) {
251  std::cerr << "Please set the VISP_INPUT_IMAGE_PATH environment "
252  "variable value."
253  << std::endl;
254  return EXIT_FAILURE;
255  }
256 
257  {
258  vpImage<unsigned char> Iref, Icur, Imatch;
259 
260  std::cout << "-- Test on gray level images" << std::endl;
261  run_test(env_ipath, opt_click_allowed, opt_display, Iref, Icur, Imatch);
262  }
263 
264  {
265  vpImage<vpRGBa> Iref, Icur, Imatch;
266 
267  std::cout << "-- Test on color images" << std::endl;
268  run_test(env_ipath, opt_click_allowed, opt_display, Iref, Icur, Imatch);
269  }
270 
271  }
272  catch (const vpException &e) {
273  std::cerr << e.what() << std::endl;
274  return EXIT_FAILURE;
275  }
276 
277  std::cout << "testKeyPoint is ok !" << std::endl;
278  return EXIT_SUCCESS;
279 }
280 #else
281 int main()
282 {
283  std::cerr << "You need OpenCV library." << std::endl;
284 
285  return EXIT_SUCCESS;
286 }
287 
288 #endif
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:130
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:133
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
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)
@ SCALE_AUTO
Definition: vpDisplay.h:184
error that can be emitted by ViSP classes.
Definition: vpException.h:60
const char * what() const
Definition: vpException.cpp:71
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:147
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
Definition of the vpImage class member functions.
Definition: vpImage.h:131
unsigned int getWidth() const
Definition: vpImage.h:242
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:542
void insert(const vpImage< Type > &src, const vpImagePoint &topLeft)
Definition: vpImage.h:637
unsigned int getHeight() const
Definition: vpImage.h:181
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1053
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1427
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
Definition: vpKeyPoint.h:221
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:70
Class that enables to manipulate easily a video file or a sequence of images. As it inherits from the...
void acquire(vpImage< vpRGBa > &I)
void open(vpImage< vpRGBa > &I)
void setFileName(const std::string &filename)