Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
testKeyPoint-6.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2023 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 descriptor computation.
32 */
33
34#include <iostream>
35
36#include <visp3/core/vpConfig.h>
37
38#if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGPROC) && defined(HAVE_OPENCV_FEATURES2D) && defined(HAVE_OPENCV_VIDEO)
39
40#include <visp3/core/vpImage.h>
41#include <visp3/core/vpIoTools.h>
42#include <visp3/gui/vpDisplayGDI.h>
43#include <visp3/gui/vpDisplayGTK.h>
44#include <visp3/gui/vpDisplayOpenCV.h>
45#include <visp3/gui/vpDisplayX.h>
46#include <visp3/io/vpImageIo.h>
47#include <visp3/io/vpParseArgv.h>
48#include <visp3/vision/vpKeyPoint.h>
49
50// List of allowed command line options
51#define GETOPTARGS "cdh"
52
53void usage(const char *name, const char *badparam);
54bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display);
55
62void usage(const char *name, const char *badparam)
63{
64 fprintf(stdout, "\n\
65Test keypoint descriptor extraction.\n\
66\n\
67SYNOPSIS\n\
68 %s [-c] [-d] [-h]\n",
69 name);
70
71 fprintf(stdout, "\n\
72OPTIONS: \n\
73\n\
74 -c\n\
75 Disable the mouse click. Useful to automate the \n\
76 execution of this program without human intervention.\n\
77\n\
78 -d \n\
79 Turn off the display.\n\
80\n\
81 -h\n\
82 Print the help.\n");
83
84 if (badparam)
85 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
86}
87
99bool getOptions(int argc, const char **argv, bool &click_allowed, bool &display)
100{
101 const char *optarg_;
102 int c;
103 while ((c = vpParseArgv::parse(argc, argv, GETOPTARGS, &optarg_)) > 1) {
104
105 switch (c) {
106 case 'c':
107 click_allowed = false;
108 break;
109 case 'd':
110 display = false;
111 break;
112 case 'h':
113 usage(argv[0], NULL);
114 return false;
115 break;
116
117 default:
118 usage(argv[0], optarg_);
119 return false;
120 break;
121 }
122 }
123
124 if ((c == 1) || (c == -1)) {
125 // standalone param or error
126 usage(argv[0], NULL);
127 std::cerr << "ERROR: " << std::endl;
128 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
129 return false;
130 }
131
132 return true;
133}
134
143std::string getOpenCVType(int type)
144{
145 std::string type_string = "";
146
147 switch (type) {
148 case CV_8U:
149 type_string = "CV_8U";
150 break;
151
152 case CV_8S:
153 type_string = "CV_8S";
154 break;
155
156 case CV_16U:
157 type_string = "CV_16U";
158 break;
159
160 case CV_16S:
161 type_string = "CV_16S";
162 break;
163
164 case CV_32S:
165 type_string = "CV_32S";
166 break;
167
168 case CV_32F:
169 type_string = "CV_32F";
170 break;
171
172 case CV_64F:
173 type_string = "CV_64F";
174 break;
175
176 default:
177 type_string = "Problem with type !";
178 break;
179 }
180
181 return type_string;
182}
183
184template <typename Type>
185void run_test(const std::string &env_ipath, bool opt_click_allowed, bool opt_display, vpImage<Type> &Iinput,
186 vpImage<Type> &I)
187{
188 // Set the path location of the image sequence
189 std::string dirname = vpIoTools::createFilePath(env_ipath, "Klimt");
190
191 // Build the name of the image files
192 std::string filename = vpIoTools::createFilePath(dirname, "/Klimt.png");
193 vpImageIo::read(Iinput, filename);
194 Iinput.quarterSizeImage(I);
195
196#if defined(VISP_HAVE_X11)
197 vpDisplayX display;
198#elif defined(VISP_HAVE_GTK)
199 vpDisplayGTK display;
200#elif defined(VISP_HAVE_GDI)
201 vpDisplayGDI display;
202#elif defined(HAVE_OPENCV_HIGHGUI)
203 vpDisplayOpenCV display;
204#endif
205
206 if (opt_display) {
207 display.init(I, 0, 0, "KeyPoints detection.");
208 }
209
210 vpKeyPoint keyPoints;
211
212 std::vector<std::string> descriptorNames;
213#if defined(VISP_HAVE_OPENCV_NONFREE) || defined(VISP_HAVE_OPENCV_XFEATURES2D) || \
214 (VISP_HAVE_OPENCV_VERSION >= 0x030411 && CV_MAJOR_VERSION < 4) || (VISP_HAVE_OPENCV_VERSION >= 0x040400)
215 descriptorNames.push_back("SIFT");
216#endif
217#if defined(VISP_HAVE_OPENCV_NONFREE) || defined(VISP_HAVE_OPENCV_XFEATURES2D)
218 descriptorNames.push_back("SURF");
219#endif
220 descriptorNames.push_back("ORB");
221#if (VISP_HAVE_OPENCV_VERSION >= 0x020403)
222 descriptorNames.push_back("BRISK");
223#endif
224#if defined(VISP_HAVE_OPENCV_XFEATURES2D) || (VISP_HAVE_OPENCV_VERSION < 0x030000)
225 descriptorNames.push_back("BRIEF");
226#if (VISP_HAVE_OPENCV_VERSION >= 0x020402)
227 descriptorNames.push_back("FREAK");
228#endif
229#endif
230#if defined(VISP_HAVE_OPENCV_XFEATURES2D)
231 descriptorNames.push_back("DAISY");
232 descriptorNames.push_back("LATCH");
233#endif
234#if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
235 descriptorNames.push_back("VGG");
236 descriptorNames.push_back("BoostDesc");
237#endif
238#if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
239 descriptorNames.push_back("KAZE");
240 descriptorNames.push_back("AKAZE");
241#endif
242
243 std::string detectorName = "FAST";
244 keyPoints.setDetector(detectorName);
245 std::vector<cv::KeyPoint> kpts;
246
247 keyPoints.detect(I, kpts);
248 std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
249 if (kpts.empty()) {
250 std::stringstream ss;
251 ss << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
252 throw(vpException(vpException::fatalError, ss.str()));
253 }
254
255 for (std::vector<std::string>::const_iterator itd = descriptorNames.begin(); itd != descriptorNames.end(); ++itd) {
256 keyPoints.setExtractor(*itd);
257
258 if (*itd == "KAZE") {
259 detectorName = "KAZE";
260 keyPoints.setDetector(detectorName);
261 keyPoints.detect(I, kpts);
262 std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
263 if (kpts.empty()) {
264 std::stringstream ss;
265 ss << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
266 throw(vpException(vpException::fatalError, ss.str()));
267 }
268 } else if (*itd == "AKAZE") {
269 detectorName = "AKAZE";
270 keyPoints.setDetector(detectorName);
271 keyPoints.detect(I, kpts);
272 std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
273 if (kpts.empty()) {
274 std::stringstream ss;
275 ss << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
276 throw(vpException(vpException::fatalError, ss.str()));
277 }
278 } else if (*itd == "BoostDesc") {
279#if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
280 cv::Ptr<cv::Feature2D> boostDesc = keyPoints.getExtractor("BoostDesc");
281 // Init BIN BOOST descriptor for FAST keypoints
282 boostDesc = cv::xfeatures2d::BoostDesc::create(cv::xfeatures2d::BoostDesc::BINBOOST_256, true, 5.0f);
283#endif
284 }
285
286 double t = vpTime::measureTimeMs();
287 cv::Mat descriptor;
288 keyPoints.extract(I, kpts, descriptor);
289 t = vpTime::measureTimeMs() - t;
290
291 std::cout << "Descriptor: " << descriptor.rows << "x" << descriptor.cols
292 << " (rows x cols) ; type=" << getOpenCVType(descriptor.type()) << " for " << *itd << " method in " << t
293 << " ms." << std::endl;
294 if (descriptor.empty()) {
295 std::stringstream ss;
296 ss << "No descriptor extracted with " << *itd << " and image:" << filename << "." << std::endl;
297 throw(vpException(vpException::fatalError, ss.str()));
298 }
299
300 if (opt_display) {
302
303 for (std::vector<cv::KeyPoint>::const_iterator it = kpts.begin(); it != kpts.end(); ++it) {
304 vpImagePoint imPt;
305 imPt.set_uv(it->pt.x, it->pt.y);
306
308 }
309
311
312 if (opt_click_allowed) {
314 }
315 }
316 }
317
318 std::cout << "\n\n";
319
320 std::map<vpKeyPoint::vpFeatureDescriptorType, std::string> mapOfDescriptorNames = keyPoints.getExtractorNames();
321
322 for (int i = 0; i < vpKeyPoint::DESCRIPTOR_TYPE_SIZE; i++) {
324
325 if (mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType)i] == "KAZE") {
326 detectorName = "KAZE";
327 keyPoints.setDetector(detectorName);
328 keyPoints.detect(I, kpts);
329 std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
330 if (kpts.empty()) {
331 std::stringstream ss;
332 ss << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
333 throw(vpException(vpException::fatalError, ss.str()));
334 }
335 } else if (mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType)i] == "AKAZE") {
336 detectorName = "AKAZE";
337 keyPoints.setDetector(detectorName);
338 keyPoints.detect(I, kpts);
339 std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
340 if (kpts.empty()) {
341 std::stringstream ss;
342 ss << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
343 throw(vpException(vpException::fatalError, ss.str()));
344 }
345 } else if (mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType)i] == "BoostDesc") {
346#if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
347 detectorName = "FAST";
348 keyPoints.setDetector(detectorName);
349 keyPoints.detect(I, kpts);
350 std::cout << "Nb keypoints detected: " << kpts.size() << " for " << detectorName << " method." << std::endl;
351 if (kpts.empty()) {
352 std::stringstream ss;
353 ss << "No keypoints detected with " << detectorName << " and image:" << filename << "." << std::endl;
354 throw(vpException(vpException::fatalError, ss.str()));
355 }
356
357 cv::Ptr<cv::Feature2D> boostDesc = keyPoints.getExtractor("BoostDesc");
358 // Init BIN BOOST descriptor for FAST keypoints
359 boostDesc = cv::xfeatures2d::BoostDesc::create(cv::xfeatures2d::BoostDesc::BINBOOST_256, true, 5.0f);
360#endif
361 }
362
363 double t = vpTime::measureTimeMs();
364 cv::Mat descriptor;
365 keyPoints.extract(I, kpts, descriptor);
366 t = vpTime::measureTimeMs() - t;
367
368 std::cout << "Descriptor: " << descriptor.rows << "x" << descriptor.cols
369 << " (rows x cols) ; type=" << getOpenCVType(descriptor.type()) << " for "
370 << mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType)i] << " method in " << t << " ms."
371 << std::endl;
372 if (descriptor.empty()) {
373 std::stringstream ss;
374 ss << "No descriptor extracted with " << mapOfDescriptorNames[(vpKeyPoint::vpFeatureDescriptorType)i]
375 << " and image:" << filename << "." << std::endl;
376 throw(vpException(vpException::fatalError, ss.str()));
377 }
378
379 if (opt_display) {
381
382 for (std::vector<cv::KeyPoint>::const_iterator it = kpts.begin(); it != kpts.end(); ++it) {
383 vpImagePoint imPt;
384 imPt.set_uv(it->pt.x, it->pt.y);
385
387 }
388
390
391 if (opt_click_allowed) {
393 }
394 }
395 }
396}
397
403int main(int argc, const char **argv)
404{
405 try {
406 std::string env_ipath;
407 bool opt_click_allowed = true;
408 bool opt_display = true;
409
410 // Read the command line options
411 if (getOptions(argc, argv, opt_click_allowed, opt_display) == false) {
412 exit(EXIT_FAILURE);
413 }
414
415 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
416 // environment variable value
418
419 if (env_ipath.empty()) {
420 std::cerr << "Please set the VISP_INPUT_IMAGE_PATH environment "
421 "variable value."
422 << std::endl;
423 return EXIT_FAILURE;
424 }
425
426 {
427 vpImage<unsigned char> Iinput, I;
428
429 std::cout << "-- Test on gray level images" << std::endl;
430 run_test(env_ipath, opt_click_allowed, opt_display, Iinput, I);
431 }
432
433 {
434 vpImage<vpRGBa> Iinput, I;
435
436 std::cout << "-- Test on color images" << std::endl;
437 run_test(env_ipath, opt_click_allowed, opt_display, Iinput, I);
438 }
439
440 } catch (const vpException &e) {
441 std::cerr << e.what() << std::endl;
442 return EXIT_FAILURE;
443 }
444
445 std::cout << "testKeyPoint-6 is ok !" << std::endl;
446 return EXIT_SUCCESS;
447}
448#else
449#include <cstdlib>
450
451int main()
452{
453 std::cerr << "You need OpenCV library." << std::endl;
454
455 return EXIT_SUCCESS;
456}
457
458#endif
static const vpColor red
Definition vpColor.h:211
Display for windows using GDI (available on any windows 32 platform).
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
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:132
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static void displayCross(const vpImage< unsigned char > &I, const vpImagePoint &ip, unsigned int size, const vpColor &color, unsigned int thickness=1)
static void flush(const vpImage< unsigned char > &I)
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ fatalError
Fatal error.
Definition vpException.h:84
const char * what() const
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
void set_uv(double u, double v)
Definition of the vpImage class member functions.
Definition vpImage.h:135
void quarterSizeImage(vpImage< Type > &res) const
Definition vpImage.h:1502
static std::string getViSPImagesDataPath()
static std::string createFilePath(const std::string &parent, const std::string &child)
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
Definition vpKeyPoint.h:212
void setExtractor(const vpFeatureDescriptorType &extractorType)
Definition vpKeyPoint.h:823
cv::Ptr< cv::DescriptorExtractor > getExtractor(const vpFeatureDescriptorType &type) const
Definition vpKeyPoint.h:536
void extract(const vpImage< unsigned char > &I, std::vector< cv::KeyPoint > &keyPoints, cv::Mat &descriptors, std::vector< cv::Point3f > *trainPoints=NULL)
void detect(const vpImage< unsigned char > &I, std::vector< cv::KeyPoint > &keyPoints, const vpRect &rectangle=vpRect())
vpFeatureDescriptorType
Definition vpKeyPoint.h:278
@ DESCRIPTOR_TYPE_SIZE
Definition vpKeyPoint.h:306
std::map< vpFeatureDescriptorType, std::string > getExtractorNames() const
Definition vpKeyPoint.h:576
void setDetector(const vpFeatureDetectorType &detectorType)
Definition vpKeyPoint.h:765
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
VISP_EXPORT double measureTimeMs()