Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
testKeyPoint-6.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 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 descriptor computation.
32  *
33  * Authors:
34  * Souriya Trinh
35  *
36  *****************************************************************************/
37 
38 #include <iostream>
39 
40 #include <visp3/core/vpConfig.h>
41 
42 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020301)
43 
44 #include <visp3/core/vpImage.h>
45 #include <visp3/io/vpImageIo.h>
46 #include <visp3/gui/vpDisplayX.h>
47 #include <visp3/gui/vpDisplayGTK.h>
48 #include <visp3/gui/vpDisplayGDI.h>
49 #include <visp3/gui/vpDisplayOpenCV.h>
50 #include <visp3/core/vpIoTools.h>
51 #include <visp3/io/vpParseArgv.h>
52 #include <visp3/vision/vpKeyPoint.h>
53 
54 // List of allowed command line options
55 #define GETOPTARGS "cdh"
56 
57 void usage(const char *name, const char *badparam);
58 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
59 
66 void usage(const char *name, const char *badparam)
67 {
68  fprintf(stdout, "\n\
69 Test keypoint descriptor extraction.\n\
70 \n\
71 SYNOPSIS\n\
72  %s [-c] [-d] [-h]\n", name);
73 
74  fprintf(stdout, "\n\
75 OPTIONS: \n\
76 \n\
77  -c\n\
78  Disable the mouse click. Useful to automaze the \n\
79  execution of this program without humain intervention.\n\
80 \n\
81  -d \n\
82  Turn off the display.\n\
83 \n\
84  -h\n\
85  Print the help.\n");
86 
87  if (badparam)
88  fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
89 }
90 
102 bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
103 {
104  const char *optarg_;
105  int c;
106  while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
107 
108  switch (c) {
109  case 'c': click_allowed = false; break;
110  case 'd': display = false; break;
111  case 'h': usage(argv[0], NULL); return false; break;
112 
113  default:
114  usage(argv[0], optarg_);
115  return false; break;
116  }
117  }
118 
119  if ((c == 1) || (c == -1)) {
120  // standalone param or error
121  usage(argv[0], NULL);
122  std::cerr << "ERROR: " << std::endl;
123  std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
124  return false;
125  }
126 
127  return true;
128 }
129 
138 std::string getOpenCVType(const int type) {
139  std::string type_string = "";
140 
141  switch(type) {
142  case CV_8U:
143  type_string = "CV_8U";
144  break;
145 
146  case CV_8S:
147  type_string = "CV_8S";
148  break;
149 
150  case CV_16U:
151  type_string = "CV_16U";
152  break;
153 
154  case CV_16S:
155  type_string = "CV_16S";
156  break;
157 
158  case CV_32S:
159  type_string = "CV_32S";
160  break;
161 
162  case CV_32F:
163  type_string = "CV_32F";
164  break;
165 
166  case CV_64F:
167  type_string = "CV_64F";
168  break;
169 
170  default:
171  type_string = "Problem with type !";
172  break;
173  }
174 
175  return type_string;
176 }
177 
183 int main(int argc, const char ** argv) {
184  try {
185  std::string env_ipath;
186  bool opt_click_allowed = true;
187  bool opt_display = true;
188 
189  // Read the command line options
190  if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
191  exit (EXIT_FAILURE);
192  }
193 
194  //Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH environment variable value
195  env_ipath = vpIoTools::getViSPImagesDataPath();
196 
197  if(env_ipath.empty()) {
198  std::cerr << "Please set the VISP_INPUT_IMAGE_PATH environment variable value." << std::endl;
199  return EXIT_FAILURE;
200  }
201 
203 
204  //Set the path location of the image sequence
205  std::string dirname = vpIoTools::createFilePath(env_ipath, "ViSP-images/Klimt");
206 
207  //Build the name of the image files
208  std::string filename = vpIoTools::createFilePath(dirname, "/Klimt.png");
209  vpImageIo::read(I, filename);
210 
211 #if defined VISP_HAVE_X11
212  vpDisplayX display;
213 #elif defined VISP_HAVE_GTK
214  vpDisplayGTK display;
215 #elif defined VISP_HAVE_GDI
216  vpDisplayGDI display;
217 #else
218  vpDisplayOpenCV display;
219 #endif
220 
221  if (opt_display) {
222  display.init(I, 0, 0, "KeyPoints detection.");
223  }
224 
225  vpKeyPoint keyPoints;
226 
227  std::vector<std::string> descriptorNames;
228 #if defined(VISP_HAVE_OPENCV_NONFREE) || defined(VISP_HAVE_OPENCV_XFEATURES2D)
229  descriptorNames.push_back("SIFT");
230  descriptorNames.push_back("SURF");
231 #endif
232  descriptorNames.push_back("ORB");
233 #if (VISP_HAVE_OPENCV_VERSION >= 0x020403)
234  descriptorNames.push_back("BRISK");
235 #endif
236 #if defined(VISP_HAVE_OPENCV_XFEATURES2D) || (VISP_HAVE_OPENCV_VERSION < 0x030000)
237  descriptorNames.push_back("BRIEF");
238 #if (VISP_HAVE_OPENCV_VERSION >= 0x020402)
239  descriptorNames.push_back("FREAK");
240 #endif
241 #endif
242 #if defined(VISP_HAVE_OPENCV_XFEATURES2D)
243  descriptorNames.push_back("DAISY");
244  descriptorNames.push_back("LATCH");
245 #endif
246 #if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
247  descriptorNames.push_back("VGG");
248  descriptorNames.push_back("BoostDesc");
249 #endif
250 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
251  descriptorNames.push_back("KAZE");
252  descriptorNames.push_back("AKAZE");
253 #endif
254 
255  std::string detectorName = "FAST";
256  keyPoints.setDetector(detectorName);
257  std::vector<cv::KeyPoint> kpts;
258 
259  keyPoints.detect(I, kpts);
260  std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
261  if (kpts.empty()) {
262  std::cerr << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
263  return EXIT_FAILURE;
264  }
265 
266  for(std::vector<std::string>::const_iterator itd = descriptorNames.begin(); itd != descriptorNames.end(); ++itd) {
267  keyPoints.setExtractor(*itd);
268 
269  if (*itd == "KAZE") {
270  detectorName = "KAZE";
271  keyPoints.setDetector(detectorName);
272  keyPoints.detect(I, kpts);
273  std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
274  if (kpts.empty()) {
275  std::cerr << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
276  return EXIT_FAILURE;
277  }
278  } else if (*itd == "AKAZE") {
279  detectorName = "AKAZE";
280  keyPoints.setDetector(detectorName);
281  keyPoints.detect(I, kpts);
282  std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
283  if (kpts.empty()) {
284  std::cerr << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
285  return EXIT_FAILURE;
286  }
287  } else if (*itd == "BoostDesc") {
288 #if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
289  cv::Ptr<cv::Feature2D> boostDesc = keyPoints.getExtractor("BoostDesc");
290  //Init BIN BOOST descriptor for FAST keypoints
291  boostDesc = cv::xfeatures2d::BoostDesc::create(cv::xfeatures2d::BoostDesc::BINBOOST_256, true, 5.0f);
292 #endif
293  }
294 
295  double t = vpTime::measureTimeMs();
296  cv::Mat descriptor;
297  keyPoints.extract(I, kpts, descriptor);
298  t = vpTime::measureTimeMs() - t;
299 
300  std::cout << "Descriptor: " << descriptor.rows << "x" << descriptor.cols << " (rows x cols) ; type="
301  << getOpenCVType(descriptor.type()) << " for " << *itd << " method in " << t << " ms." << std::endl;
302  if(descriptor.empty()) {
303  std::cerr << "No descriptor extracted with " << *itd << " and image:" << filename << "." << std::endl;
304  return EXIT_FAILURE;
305  }
306 
307  if (opt_display) {
309 
310  for(std::vector<cv::KeyPoint>::const_iterator it = kpts.begin(); it != kpts.end(); ++it) {
311  vpImagePoint imPt;
312  imPt.set_uv(it->pt.x, it->pt.y);
313 
315  }
316 
317  vpDisplay::flush(I);
318 
319  if(opt_click_allowed) {
321  }
322  }
323  }
324 
325  std::cout << "\n\n";
326 
327  std::map<vpKeyPoint::vpFeatureDescriptorType, std::string> mapOfDescriptorNames = keyPoints.getExtractorNames();
328 
329  for (int i = 0; i < vpKeyPoint::DESCRIPTOR_TYPE_SIZE; i++) {
331 
332  if (mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType) i] == "KAZE") {
333  detectorName = "KAZE";
334  keyPoints.setDetector(detectorName);
335  keyPoints.detect(I, kpts);
336  std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
337  if (kpts.empty()) {
338  std::cerr << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
339  return EXIT_FAILURE;
340  }
341  } else if (mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType) i] == "AKAZE") {
342  detectorName = "AKAZE";
343  keyPoints.setDetector(detectorName);
344  keyPoints.detect(I, kpts);
345  std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
346  if (kpts.empty()) {
347  std::cerr << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
348  return EXIT_FAILURE;
349  }
350  } else if (mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType) i] == "BoostDesc") {
351 #if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
352  detectorName = "FAST";
353  keyPoints.setDetector(detectorName);
354  keyPoints.detect(I, kpts);
355  std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
356  if (kpts.empty()) {
357  std::cerr << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
358  return EXIT_FAILURE;
359  }
360 
361  cv::Ptr<cv::Feature2D> boostDesc = keyPoints.getExtractor("BoostDesc");
362  //Init BIN BOOST descriptor for FAST keypoints
363  boostDesc = cv::xfeatures2d::BoostDesc::create(cv::xfeatures2d::BoostDesc::BINBOOST_256, true, 5.0f);
364 #endif
365  }
366 
367  double t = vpTime::measureTimeMs();
368  cv::Mat descriptor;
369  keyPoints.extract(I, kpts, descriptor);
370  t = vpTime::measureTimeMs() - t;
371 
372  std::cout << "Descriptor: " << descriptor.rows << "x" << descriptor.cols << " (rows x cols) ; type="
373  << getOpenCVType(descriptor.type()) << " for " << mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType) i]
374  << " method in " << t << " ms." << std::endl;
375  if(descriptor.empty()) {
376  std::cerr << "No descriptor extracted with " << mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType) i] << " and image:" << filename << "." << std::endl;
377  return EXIT_FAILURE;
378  }
379 
380  if (opt_display) {
382 
383  for(std::vector<cv::KeyPoint>::const_iterator it = kpts.begin(); it != kpts.end(); ++it) {
384  vpImagePoint imPt;
385  imPt.set_uv(it->pt.x, it->pt.y);
386 
388  }
389 
390  vpDisplay::flush(I);
391 
392  if(opt_click_allowed) {
394  }
395  }
396  }
397 
398  } catch(vpException &e) {
399  std::cerr << e.what() << std::endl;
400  return EXIT_FAILURE;
401  }
402 
403  std::cout << "testKeyPoint-6 is ok !" << std::endl;
404  return EXIT_SUCCESS;
405 }
406 #else
407 #include <cstdlib>
408 
409 int main() {
410  std::cerr << "You need OpenCV library." << std::endl;
411 
412  return EXIT_SUCCESS;
413 }
414 
415 #endif
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1157
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:153
error that can be emited by ViSP classes.
Definition: vpException.h:73
void init(vpImage< unsigned char > &I, int winx=-1, int winy=-1, const std::string &title="")
static void flush(const vpImage< unsigned char > &I)
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:93
cv::Ptr< cv::DescriptorExtractor > getExtractor(const vpFeatureDescriptorType &type) const
Definition: vpKeyPoint.h:478
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:76
static const vpColor red
Definition: vpColor.h:163
const char * what() const
static std::string createFilePath(const std::string &parent, const std::string child)
Definition: vpIoTools.cpp:1366
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
vpFeatureDescriptorType
Definition: vpKeyPoint.h:274
void setDetector(const vpFeatureDetectorType &detectorType)
Definition: vpKeyPoint.h:700
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:138
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
std::map< vpFeatureDescriptorType, std::string > getExtractorNames() const
Definition: vpKeyPoint.h:512
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:205
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
Definition: vpKeyPoint.h:217
void set_uv(const double u, const double v)
Definition: vpImagePoint.h:243
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void setExtractor(const vpFeatureDescriptorType &extractorType)
Definition: vpKeyPoint.h:752
void detect(const vpImage< unsigned char > &I, std::vector< cv::KeyPoint > &keyPoints, const vpRect &rectangle=vpRect())
void extract(const vpImage< unsigned char > &I, std::vector< cv::KeyPoint > &keyPoints, cv::Mat &descriptors, std::vector< cv::Point3f > *trainPoints=NULL)