Visual Servoing Platform version 3.5.0
testKeyPoint-7.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 saving / loading learning files for vpKeyPoint class.
33 *
34 * Authors:
35 * Souriya Trinh
36 *
37 *****************************************************************************/
38
39#include <iomanip>
40#include <iostream>
41
42#include <visp3/core/vpConfig.h>
43
44#if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020301)
45
46#include <visp3/core/vpException.h>
47#include <visp3/core/vpImage.h>
48#include <visp3/core/vpIoTools.h>
49#include <visp3/io/vpImageIo.h>
50#include <visp3/io/vpParseArgv.h>
51#include <visp3/vision/vpKeyPoint.h>
52
53// List of allowed command line options
54#define GETOPTARGS "cdo:h"
55
64void usage(const char *name, const char *badparam, const std::string &opath, const std::string &user)
65{
66 fprintf(stdout, "\n\
67Test save / load learning files for vpKeyPoint class.\n\
68\n\
69SYNOPSIS\n\
70 %s [-c] [-d] [-h]\n", name);
71
72 fprintf(stdout, "\n\
73OPTIONS: \n\
74\n\
75 -o <output image path> %s\n\
76 Set image output path.\n\
77 From this directory, creates the \"%s\"\n\
78 subdirectory depending on the username, where \n\
79 learning files will be written.\n\
80\n\
81 -h\n\
82 Print the help.\n", opath.c_str(), user.c_str());
83
84 if (badparam)
85 fprintf(stdout, "\nERROR: Bad parameter [%s]\n", badparam);
86}
87
99bool getOptions(int argc, const char **argv, std::string &opath, const std::string &user)
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 break; // not used, to avoid error with default arguments ctest
108 case 'd':
109 break; // not used, to avoid error with default arguments ctest
110 case 'o':
111 opath = optarg_;
112 break;
113 case 'h':
114 usage(argv[0], NULL, opath, user);
115 return false;
116 break;
117
118 default:
119 usage(argv[0], optarg_, opath, user);
120 return false;
121 break;
122 return false;
123 break;
124 }
125 }
126
127 if ((c == 1) || (c == -1)) {
128 // standalone param or error
129 usage(argv[0], NULL, opath, user);
130 std::cerr << "ERROR: " << std::endl;
131 std::cerr << " Bad argument " << optarg_ << std::endl << std::endl;
132 return false;
133 }
134
135 return true;
136}
137
146bool compareKeyPoints(const std::vector<cv::KeyPoint> &keypoints1, const std::vector<cv::KeyPoint> &keypoints2)
147{
148 if (keypoints1.size() != keypoints2.size()) {
149 return false;
150 }
151
152 for (size_t cpt = 0; cpt < keypoints1.size(); cpt++) {
153 if (!vpMath::equal(keypoints1[cpt].angle, keypoints2[cpt].angle, std::numeric_limits<float>::epsilon())) {
154 std::cerr << std::fixed << std::setprecision(9) << "keypoints1[cpt].angle=" << keypoints1[cpt].angle
155 << " ; keypoints2[cpt].angle=" << keypoints2[cpt].angle << std::endl;
156 return false;
157 }
158
159 if (keypoints1[cpt].class_id != keypoints2[cpt].class_id) {
160 std::cerr << "keypoints1[cpt].class_id=" << keypoints1[cpt].class_id
161 << " ; keypoints2[cpt].class_id=" << keypoints2[cpt].class_id << std::endl;
162 return false;
163 }
164
165 if (keypoints1[cpt].octave != keypoints2[cpt].octave) {
166 std::cerr << "keypoints1[cpt].octave=" << keypoints1[cpt].octave
167 << " ; keypoints2[cpt].octave=" << keypoints2[cpt].octave << std::endl;
168 return false;
169 }
170
171 if (!vpMath::equal(keypoints1[cpt].pt.x, keypoints2[cpt].pt.x, std::numeric_limits<float>::epsilon())) {
172 std::cerr << std::fixed << std::setprecision(9) << "keypoints1[cpt].pt.x=" << keypoints1[cpt].pt.x
173 << " ; keypoints2[cpt].pt.x=" << keypoints2[cpt].pt.x << std::endl;
174 return false;
175 }
176
177 if (!vpMath::equal(keypoints1[cpt].pt.y, keypoints2[cpt].pt.y, std::numeric_limits<float>::epsilon())) {
178 std::cerr << std::fixed << std::setprecision(9) << "keypoints1[cpt].pt.y=" << keypoints1[cpt].pt.y
179 << " ; keypoints2[cpt].pt.y=" << keypoints2[cpt].pt.y << std::endl;
180 return false;
181 }
182
183 if (!vpMath::equal(keypoints1[cpt].response, keypoints2[cpt].response, std::numeric_limits<float>::epsilon())) {
184 std::cerr << std::fixed << std::setprecision(9) << "keypoints1[cpt].response=" << keypoints1[cpt].response
185 << " ; keypoints2[cpt].response=" << keypoints2[cpt].response << std::endl;
186 return false;
187 }
188
189 if (!vpMath::equal(keypoints1[cpt].size, keypoints2[cpt].size, std::numeric_limits<float>::epsilon())) {
190 std::cerr << std::fixed << std::setprecision(9) << "keypoints1[cpt].size=" << keypoints1[cpt].size
191 << " ; keypoints2[cpt].size=" << keypoints2[cpt].size << std::endl;
192 return false;
193 }
194 }
195
196 return true;
197}
198
207bool compareDescriptors(const cv::Mat &descriptors1, const cv::Mat &descriptors2)
208{
209 if (descriptors1.rows != descriptors2.rows || descriptors1.cols != descriptors2.cols ||
210 descriptors1.type() != descriptors2.type()) {
211 return false;
212 }
213
214 for (int i = 0; i < descriptors1.rows; i++) {
215 for (int j = 0; j < descriptors1.cols; j++) {
216 switch (descriptors1.type()) {
217 case CV_8U:
218 if (descriptors1.at<unsigned char>(i, j) != descriptors2.at<unsigned char>(i, j)) {
219 std::cerr << "descriptors1.at<unsigned char>(i,j)=" << descriptors1.at<unsigned char>(i, j)
220 << " ; descriptors2.at<unsigned char>(i,j)=" << descriptors2.at<unsigned char>(i, j) << std::endl;
221 return false;
222 }
223 break;
224
225 case CV_8S:
226 if (descriptors1.at<char>(i, j) != descriptors2.at<char>(i, j)) {
227 std::cerr << "descriptors1.at<char>(i,j)=" << descriptors1.at<char>(i, j)
228 << " ; descriptors2.at<char>(i,j)=" << descriptors2.at<char>(i, j) << std::endl;
229 return false;
230 }
231 break;
232
233 case CV_16U:
234 if (descriptors1.at<unsigned short>(i, j) != descriptors2.at<unsigned short>(i, j)) {
235 std::cerr << "descriptors1.at<unsigned short>(i,j)=" << descriptors1.at<unsigned short>(i, j)
236 << " ; descriptors2.at<unsigned short>(i,j)=" << descriptors2.at<unsigned short>(i, j) << std::endl;
237 return false;
238 }
239 break;
240
241 case CV_16S:
242 if (descriptors1.at<short>(i, j) != descriptors2.at<short>(i, j)) {
243 std::cerr << "descriptors1.at<short>(i,j)=" << descriptors1.at<short>(i, j)
244 << " ; descriptors2.at<short>(i,j)=" << descriptors2.at<short>(i, j) << std::endl;
245 return false;
246 }
247 break;
248
249 case CV_32S:
250 if (descriptors1.at<int>(i, j) != descriptors2.at<int>(i, j)) {
251 std::cerr << "descriptors1.at<int>(i,j)=" << descriptors1.at<int>(i, j)
252 << " ; descriptors2.at<int>(i,j)=" << descriptors2.at<int>(i, j) << std::endl;
253 return false;
254 }
255 break;
256
257 case CV_32F:
258 if (!vpMath::equal(descriptors1.at<float>(i, j), descriptors2.at<float>(i, j),
259 std::numeric_limits<float>::epsilon())) {
260 std::cerr << std::fixed << std::setprecision(9)
261 << "descriptors1.at<float>(i,j)=" << descriptors1.at<float>(i, j)
262 << " ; descriptors2.at<float>(i,j)=" << descriptors2.at<float>(i, j) << std::endl;
263 return false;
264 }
265 break;
266
267 case CV_64F:
268 if (!vpMath::equal(descriptors1.at<double>(i, j), descriptors2.at<double>(i, j),
269 std::numeric_limits<double>::epsilon())) {
270 std::cerr << std::fixed << std::setprecision(17)
271 << "descriptors1.at<double>(i,j)=" << descriptors1.at<double>(i, j)
272 << " ; descriptors2.at<double>(i,j)=" << descriptors2.at<double>(i, j) << std::endl;
273 return false;
274 }
275 break;
276
277 default:
278 return false;
279 break;
280 }
281 }
282 }
283
284 return true;
285}
286
287template<typename Type>
288void run_test(const std::string &env_ipath, const std::string &opath, vpImage<Type> &I)
289{
290 std::string filename;
291 // Set the path location of the image sequence
292 std::string dirname = vpIoTools::createFilePath(env_ipath, "Klimt");
293
294 // Build the name of the image files
295 std::string img_filename = vpIoTools::createFilePath(dirname, "/Klimt.ppm");
296 vpImageIo::read(I, img_filename);
297
298 vpKeyPoint keyPoints;
299
300 // Test with binary descriptor
301 {
302 std::string keypointName = "ORB";
303 keyPoints.setDetector(keypointName);
304 keyPoints.setExtractor(keypointName);
305
306 keyPoints.buildReference(I);
307
308 std::vector<cv::KeyPoint> trainKeyPoints;
309 keyPoints.getTrainKeyPoints(trainKeyPoints);
310 cv::Mat trainDescriptors = keyPoints.getTrainDescriptors();
311 if (trainKeyPoints.empty() || trainDescriptors.empty() || (int)trainKeyPoints.size() != trainDescriptors.rows) {
312 throw vpException(vpException::fatalError, "Problem when detecting "
313 "keypoints or when "
314 "computing descriptors !");
315 }
316
317 // Save in binary with training images
318 filename = vpIoTools::createFilePath(opath, "bin_with_img");
319 vpIoTools::makeDirectory(filename);
320 filename = vpIoTools::createFilePath(filename, "test_save_in_bin_with_img.bin");
321 keyPoints.saveLearningData(filename, true, true);
322
323 // Test if save is ok
324 if (!vpIoTools::checkFilename(filename)) {
325 std::stringstream ss;
326 ss << "Problem when saving file=" << filename;
327 throw vpException(vpException::ioError, ss.str().c_str());
328 }
329
330 // Test if read is ok
331 vpKeyPoint read_keypoint1;
332 read_keypoint1.loadLearningData(filename, true);
333 std::vector<cv::KeyPoint> trainKeyPoints_read;
334 read_keypoint1.getTrainKeyPoints(trainKeyPoints_read);
335 cv::Mat trainDescriptors_read = read_keypoint1.getTrainDescriptors();
336
337 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
338 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved "
339 "in binary with train images saved !");
340 }
341
342 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
343 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
344 "learning file saved in "
345 "binary with train images saved !");
346 }
347
348 // Save in binary with no training images
349 filename = vpIoTools::createFilePath(opath, "bin_without_img");
350 vpIoTools::makeDirectory(filename);
351 filename = vpIoTools::createFilePath(filename, "test_save_in_bin_without_img.bin");
352 keyPoints.saveLearningData(filename, true, false);
353
354 // Test if save is ok
355 if (!vpIoTools::checkFilename(filename)) {
356 std::stringstream ss;
357 ss << "Problem when saving file=" << filename;
358 throw vpException(vpException::ioError, ss.str().c_str());
359 }
360
361 // Test if read is ok
362 vpKeyPoint read_keypoint2;
363 read_keypoint2.loadLearningData(filename, true);
364 trainKeyPoints_read.clear();
365 read_keypoint2.getTrainKeyPoints(trainKeyPoints_read);
366 trainDescriptors_read = read_keypoint2.getTrainDescriptors();
367
368 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
369 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved in "
370 "binary without train images !");
371 }
372
373 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
374 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
375 "learning file saved in "
376 "binary without train images !");
377 }
378
379 // Save in xml with training images
380 filename = vpIoTools::createFilePath(opath, "xml_with_img");
381 vpIoTools::makeDirectory(filename);
382 filename = vpIoTools::createFilePath(filename, "test_save_in_xml_with_img.xml");
383 keyPoints.saveLearningData(filename, false, true);
384
385 // Test if save is ok
386 if (!vpIoTools::checkFilename(filename)) {
387 std::stringstream ss;
388 ss << "Problem when saving file=" << filename;
389 throw vpException(vpException::ioError, ss.str().c_str());
390 }
391
392 // Test if read is ok
393 vpKeyPoint read_keypoint3;
394 read_keypoint3.loadLearningData(filename, false);
395 trainKeyPoints_read.clear();
396 read_keypoint3.getTrainKeyPoints(trainKeyPoints_read);
397 trainDescriptors_read = read_keypoint3.getTrainDescriptors();
398
399 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
400 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved in "
401 "xml with train images saved !");
402 }
403
404 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
405 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
406 "learning file saved in "
407 "xml with train images saved !");
408 }
409
410 // Save in xml without training images
411 filename = vpIoTools::createFilePath(opath, "xml_without_img");
412 vpIoTools::makeDirectory(filename);
413 filename = vpIoTools::createFilePath(filename, "test_save_in_xml_without_img.xml");
414 keyPoints.saveLearningData(filename, false, false);
415
416 // Test if save is ok
417 if (!vpIoTools::checkFilename(filename)) {
418 std::stringstream ss;
419 ss << "Problem when saving file=" << filename;
420 throw vpException(vpException::ioError, ss.str().c_str());
421 }
422
423 // Test if read is ok
424 vpKeyPoint read_keypoint4;
425 read_keypoint4.loadLearningData(filename, false);
426 trainKeyPoints_read.clear();
427 read_keypoint4.getTrainKeyPoints(trainKeyPoints_read);
428 trainDescriptors_read = read_keypoint4.getTrainDescriptors();
429
430 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
431 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved in "
432 "xml without train images saved !");
433 }
434
435 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
436 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
437 "learning file saved in "
438 "xml without train images saved !");
439 }
440
441 std::cout << "Saving / loading learning files with binary descriptor are ok !" << std::endl;
442 }
443
444
445// Test with floating point descriptor
446#if defined(VISP_HAVE_OPENCV_NONFREE) || \
447 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(VISP_HAVE_OPENCV_XFEATURES2D) || \
448 (VISP_HAVE_OPENCV_VERSION >= 0x030411 && CV_MAJOR_VERSION < 4) || (VISP_HAVE_OPENCV_VERSION >= 0x040400))
449 {
450#if !((VISP_HAVE_OPENCV_VERSION == 0x040504) && (defined(__APPLE__) && defined(__MACH__))) // OpenCV != 4.5.4 on macOS
451 std::string keypointName = "SIFT"; // SIFT is known unstable with OpenCV 4.5.4
452 keyPoints.setDetector(keypointName);
453 keyPoints.setExtractor(keypointName);
454
455 keyPoints.buildReference(I);
456
457 std::vector<cv::KeyPoint> trainKeyPoints;
458 keyPoints.getTrainKeyPoints(trainKeyPoints);
459 cv::Mat trainDescriptors = keyPoints.getTrainDescriptors();
460 if (trainKeyPoints.empty() || trainDescriptors.empty() || (int)trainKeyPoints.size() != trainDescriptors.rows) {
461 throw vpException(vpException::fatalError, "Problem when detecting keypoints or when "
462 "computing descriptors (SIFT) !");
463 }
464
465 // Save in binary with training images
466 filename = vpIoTools::createFilePath(opath, "bin_with_img");
467 vpIoTools::makeDirectory(filename);
468 filename = vpIoTools::createFilePath(filename, "test_save_in_bin_with_img.bin");
469 keyPoints.saveLearningData(filename, true, true);
470
471 // Test if save is ok
472 if (!vpIoTools::checkFilename(filename)) {
473 std::stringstream ss;
474 ss << "Problem when saving file=" << filename;
475 throw vpException(vpException::ioError, ss.str().c_str());
476 }
477
478 // Test if read is ok
479 vpKeyPoint read_keypoint1;
480 read_keypoint1.loadLearningData(filename, true);
481 std::vector<cv::KeyPoint> trainKeyPoints_read;
482 read_keypoint1.getTrainKeyPoints(trainKeyPoints_read);
483 cv::Mat trainDescriptors_read = read_keypoint1.getTrainDescriptors();
484
485 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
486 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved in "
487 "binary with train images saved !");
488 }
489
490 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
491 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
492 "learning file saved in "
493 "binary with train images saved !");
494 }
495
496 // Save in binary with no training images
497 filename = vpIoTools::createFilePath(opath, "bin_without_img");
498 vpIoTools::makeDirectory(filename);
499 filename = vpIoTools::createFilePath(filename, "test_save_in_bin_without_img.bin");
500 keyPoints.saveLearningData(filename, true, false);
501
502 // Test if save is ok
503 if (!vpIoTools::checkFilename(filename)) {
504 std::stringstream ss;
505 ss << "Problem when saving file=" << filename;
506 throw vpException(vpException::ioError, ss.str().c_str());
507 }
508
509 // Test if read is ok
510 vpKeyPoint read_keypoint2;
511 read_keypoint2.loadLearningData(filename, true);
512 trainKeyPoints_read.clear();
513 read_keypoint2.getTrainKeyPoints(trainKeyPoints_read);
514 trainDescriptors_read = read_keypoint2.getTrainDescriptors();
515
516 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
517 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved in "
518 "binary without train images saved !");
519 }
520
521 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
522 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
523 "learning file saved in "
524 "binary without train images saved !");
525 }
526
527 // Save in xml with training images
528 filename = vpIoTools::createFilePath(opath, "xml_with_img");
529 vpIoTools::makeDirectory(filename);
530 filename = vpIoTools::createFilePath(filename, "test_save_in_xml_with_img.xml");
531 keyPoints.saveLearningData(filename, false, true);
532
533 // Test if save is ok
534 if (!vpIoTools::checkFilename(filename)) {
535 std::stringstream ss;
536 ss << "Problem when saving file=" << filename;
537 throw vpException(vpException::ioError, ss.str().c_str());
538 }
539
540 // Test if read is ok
541 vpKeyPoint read_keypoint3;
542 read_keypoint3.loadLearningData(filename, false);
543 trainKeyPoints_read.clear();
544 read_keypoint3.getTrainKeyPoints(trainKeyPoints_read);
545 trainDescriptors_read = read_keypoint3.getTrainDescriptors();
546
547 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
548 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved in "
549 "xml with train images saved !");
550 }
551
552 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
553 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
554 "learning file saved in "
555 "xml with train images saved !");
556 }
557
558 // Save in xml without training images
559 filename = vpIoTools::createFilePath(opath, "xml_without_img");
560 vpIoTools::makeDirectory(filename);
561 filename = vpIoTools::createFilePath(filename, "test_save_in_xml_without_img.xml");
562 keyPoints.saveLearningData(filename, false, false);
563
564 // Test if save is ok
565 if (!vpIoTools::checkFilename(filename)) {
566 std::stringstream ss;
567 ss << "Problem when saving file=" << filename;
568 throw vpException(vpException::ioError, ss.str().c_str());
569 }
570
571 // Test if read is ok
572 vpKeyPoint read_keypoint4;
573 read_keypoint4.loadLearningData(filename, false);
574 trainKeyPoints_read.clear();
575 read_keypoint4.getTrainKeyPoints(trainKeyPoints_read);
576 trainDescriptors_read = read_keypoint4.getTrainDescriptors();
577
578 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
579 throw vpException(vpException::fatalError, "Problem with trainKeyPoints when reading learning file saved in "
580 "xml without train images saved !");
581 }
582
583 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
584 throw vpException(vpException::fatalError, "Problem with trainDescriptors when reading "
585 "learning file saved in "
586 "xml without train images saved !");
587 }
588
589 std::cout << "Saving / loading learning files with floating point "
590 "descriptor are ok !"
591 << std::endl;
592
593 // Test vpKeyPoint::reset()
594 vpKeyPoint keypoint_reset;
595
596 keypointName = "ORB";
597 keypoint_reset.setDetector(keypointName);
598 keypoint_reset.setExtractor(keypointName);
599
600 keypoint_reset.buildReference(I);
601
602 // reset
603 keypoint_reset.reset();
604
605 keypointName = "SIFT";
606 keypoint_reset.setDetector(keypointName);
607 keypoint_reset.setExtractor(keypointName);
608
609 keypoint_reset.buildReference(I);
610
611 std::vector<cv::KeyPoint> trainKeyPoints_reset;
612 keypoint_reset.getTrainKeyPoints(trainKeyPoints_reset);
613 cv::Mat trainDescriptors_reset = keypoint_reset.getTrainDescriptors();
614
615 // If reset is ok, we should get the same keypoints and the same
616 // descriptors
617 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_reset)) {
618 throw vpException(vpException::fatalError, "Problem with vpKeyPoint::reset() and trainKeyPoints !");
619 }
620
621 if (!compareDescriptors(trainDescriptors, trainDescriptors_reset)) {
622 throw vpException(vpException::fatalError, "Problem with vpKeyPoint::reset() and trainDescriptors !");
623 }
624
625 std::cout << "vpKeyPoint::reset() is ok with trainKeyPoints and "
626 "trainDescriptors !"
627 << std::endl;
628#endif // OpenCV != 4.5.4 on macOS
629 }
630#endif
631}
632
638int main(int argc, const char **argv)
639{
640 try {
641 std::string env_ipath;
642 std::string opt_opath;
643 std::string username;
644 std::string opath;
645
646 // Get the visp-images-data package path or VISP_INPUT_IMAGE_PATH
647 // environment variable value
649
650 if (env_ipath.empty()) {
651 throw vpException(vpException::ioError, "Please set the VISP_INPUT_IMAGE_PATH environment variable value.");
652 }
653
654// Set the default output path
655#if defined(_WIN32)
656 opt_opath = "C:/temp";
657#else
658 opt_opath = "/tmp";
659#endif
660
661 // Get the user login name
662 vpIoTools::getUserName(username);
663
664 // Read the command line options
665 if (getOptions(argc, argv, opt_opath, username) == false) {
666 throw vpException(vpException::fatalError, "getOptions(argc, argv, opt_opath, username) == false");
667 }
668
669 // Get the option values
670 if (!opt_opath.empty()) {
671 opath = opt_opath;
672 }
673
674 // Append to the output path string, the login name of the user
675 opath = vpIoTools::createFilePath(opath, username);
676
677 {
679
680 std::cout << "-- Test on gray level images" << std::endl;
681 run_test(env_ipath, opath, I);
682 }
683
684 {
686
687 std::cout << "-- Test on color images" << std::endl;
688 run_test(env_ipath, opath, I);
689 }
690
691 } catch (const vpException &e) {
692 std::cerr << e.what() << std::endl;
693 return -1;
694 }
695
696 std::cout << "Saving / loading learning files are ok !" << std::endl;
697 std::cout << "testKeyPoint-7 is ok !" << std::endl;
698 return 0;
699}
700#else
701int main()
702{
703 std::cerr << "You need OpenCV library." << std::endl;
704
705 return 0;
706}
707
708#endif
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ ioError
I/O error.
Definition: vpException.h:91
@ fatalError
Fatal error.
Definition: vpException.h:96
const char * what() const
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:149
Definition of the vpImage class member functions.
Definition: vpImage.h:139
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:802
static std::string getUserName()
Definition: vpIoTools.cpp:316
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1670
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:570
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
Definition: vpKeyPoint.h:223
void getTrainKeyPoints(std::vector< cv::KeyPoint > &keyPoints) const
cv::Mat getTrainDescriptors() const
Definition: vpKeyPoint.h:688
void setExtractor(const vpFeatureDescriptorType &extractorType)
Definition: vpKeyPoint.h:840
void reset()
void loadLearningData(const std::string &filename, bool binaryMode=false, bool append=false)
void saveLearningData(const std::string &filename, bool binaryMode=false, bool saveTrainingImages=true)
void setDetector(const vpFeatureDetectorType &detectorType)
Definition: vpKeyPoint.h:782
unsigned int buildReference(const vpImage< unsigned char > &I)
Definition: vpKeyPoint.cpp:238
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:295
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
Definition: vpParseArgv.cpp:69