42 #include <visp3/core/vpConfig.h> 44 #if defined(VISP_HAVE_OPENCV) && (VISP_HAVE_OPENCV_VERSION >= 0x020301) 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> 54 #define GETOPTARGS "cdo:h" 64 void usage(
const char *name,
const char *badparam,
const std::string &opath,
const std::string &user)
67 Test save / load learning files for vpKeyPoint class.\n\ 70 %s [-c] [-d] [-h]\n", name);
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\ 82 Print the help.\n", opath.c_str(), user.c_str());
85 fprintf(stdout,
"\nERROR: Bad parameter [%s]\n", badparam);
99 bool getOptions(
int argc,
const char **argv, std::string &opath,
const std::string &user)
114 usage(argv[0], NULL, opath, user);
119 usage(argv[0], optarg_, opath, user);
127 if ((c == 1) || (c == -1)) {
129 usage(argv[0], NULL, opath, user);
130 std::cerr <<
"ERROR: " << std::endl;
131 std::cerr <<
" Bad argument " << optarg_ << std::endl << std::endl;
146 bool compareKeyPoints(
const std::vector<cv::KeyPoint> &keypoints1,
const std::vector<cv::KeyPoint> &keypoints2)
148 if (keypoints1.size() != keypoints2.size()) {
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;
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;
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;
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;
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;
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;
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;
207 bool compareDescriptors(
const cv::Mat &descriptors1,
const cv::Mat &descriptors2)
209 if (descriptors1.rows != descriptors2.rows || descriptors1.cols != descriptors2.cols ||
210 descriptors1.type() != descriptors2.type()) {
214 for (
int i = 0; i < descriptors1.rows; i++) {
215 for (
int j = 0; j < descriptors1.cols; j++) {
216 switch (descriptors1.type()) {
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;
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;
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;
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;
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;
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;
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;
287 template<
typename Type>
288 void run_test(
const std::string &env_ipath,
const std::string &opath,
vpImage<Type> &I)
290 std::string filename;
302 std::string keypointName =
"ORB";
308 std::vector<cv::KeyPoint> trainKeyPoints;
311 if (trainKeyPoints.empty() || trainDescriptors.empty() || (int)trainKeyPoints.size() != trainDescriptors.rows) {
314 "computing descriptors !");
325 std::stringstream ss;
326 ss <<
"Problem when saving file=" << filename;
333 std::vector<cv::KeyPoint> trainKeyPoints_read;
334 read_keypoint1.getTrainKeyPoints(trainKeyPoints_read);
335 cv::Mat trainDescriptors_read = read_keypoint1.getTrainDescriptors();
337 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
339 "in binary with train images saved !");
342 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
344 "learning file saved in " 345 "binary with train images saved !");
356 std::stringstream ss;
357 ss <<
"Problem when saving file=" << filename;
364 trainKeyPoints_read.clear();
365 read_keypoint2.getTrainKeyPoints(trainKeyPoints_read);
366 trainDescriptors_read = read_keypoint2.getTrainDescriptors();
368 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
370 "binary without train images !");
373 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
375 "learning file saved in " 376 "binary without train images !");
387 std::stringstream ss;
388 ss <<
"Problem when saving file=" << filename;
395 trainKeyPoints_read.clear();
396 read_keypoint3.getTrainKeyPoints(trainKeyPoints_read);
397 trainDescriptors_read = read_keypoint3.getTrainDescriptors();
399 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
401 "xml with train images saved !");
404 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
406 "learning file saved in " 407 "xml with train images saved !");
418 std::stringstream ss;
419 ss <<
"Problem when saving file=" << filename;
426 trainKeyPoints_read.clear();
427 read_keypoint4.getTrainKeyPoints(trainKeyPoints_read);
428 trainDescriptors_read = read_keypoint4.getTrainDescriptors();
430 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
432 "xml without train images saved !");
435 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
437 "learning file saved in " 438 "xml without train images saved !");
441 std::cout <<
"Saving / loading learning files with binary descriptor are ok !" << std::endl;
445 #if defined(VISP_HAVE_OPENCV_NONFREE) || \ 446 ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(VISP_HAVE_OPENCV_XFEATURES2D) || \ 447 (VISP_HAVE_OPENCV_VERSION >= 0x030411 && CV_MAJOR_VERSION < 4) || (VISP_HAVE_OPENCV_VERSION >= 0x040400)) 449 std::string keypointName =
"SIFT";
455 std::vector<cv::KeyPoint> trainKeyPoints;
458 if (trainKeyPoints.empty() || trainDescriptors.empty() || (int)trainKeyPoints.size() != trainDescriptors.rows) {
460 "computing descriptors (SIFT) !");
471 std::stringstream ss;
472 ss <<
"Problem when saving file=" << filename;
479 std::vector<cv::KeyPoint> trainKeyPoints_read;
480 read_keypoint1.getTrainKeyPoints(trainKeyPoints_read);
481 cv::Mat trainDescriptors_read = read_keypoint1.getTrainDescriptors();
483 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
485 "binary with train images saved !");
488 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
490 "learning file saved in " 491 "binary with train images saved !");
502 std::stringstream ss;
503 ss <<
"Problem when saving file=" << filename;
510 trainKeyPoints_read.clear();
511 read_keypoint2.getTrainKeyPoints(trainKeyPoints_read);
512 trainDescriptors_read = read_keypoint2.getTrainDescriptors();
514 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
516 "binary without train images saved !");
519 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
521 "learning file saved in " 522 "binary without train images saved !");
533 std::stringstream ss;
534 ss <<
"Problem when saving file=" << filename;
541 trainKeyPoints_read.clear();
542 read_keypoint3.getTrainKeyPoints(trainKeyPoints_read);
543 trainDescriptors_read = read_keypoint3.getTrainDescriptors();
545 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
547 "xml with train images saved !");
550 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
552 "learning file saved in " 553 "xml with train images saved !");
564 std::stringstream ss;
565 ss <<
"Problem when saving file=" << filename;
572 trainKeyPoints_read.clear();
573 read_keypoint4.getTrainKeyPoints(trainKeyPoints_read);
574 trainDescriptors_read = read_keypoint4.getTrainDescriptors();
576 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_read)) {
578 "xml without train images saved !");
581 if (!compareDescriptors(trainDescriptors, trainDescriptors_read)) {
583 "learning file saved in " 584 "xml without train images saved !");
587 std::cout <<
"Saving / loading learning files with floating point " 588 "descriptor are ok !" 594 keypointName =
"ORB";
601 keypoint_reset.
reset();
603 keypointName =
"SIFT";
609 std::vector<cv::KeyPoint> trainKeyPoints_reset;
615 if (!compareKeyPoints(trainKeyPoints, trainKeyPoints_reset)) {
619 if (!compareDescriptors(trainDescriptors, trainDescriptors_reset)) {
623 std::cout <<
"vpKeyPoint::reset() is ok with trainKeyPoints and " 635 int main(
int argc,
const char **argv)
638 std::string env_ipath;
639 std::string opt_opath;
640 std::string username;
647 if (env_ipath.empty()) {
653 opt_opath =
"C:/temp";
662 if (getOptions(argc, argv, opt_opath, username) ==
false) {
667 if (!opt_opath.empty()) {
677 std::cout <<
"-- Test on gray level images" << std::endl;
678 run_test(env_ipath, opath, I);
684 std::cout <<
"-- Test on color images" << std::endl;
685 run_test(env_ipath, opath, I);
689 std::cerr << e.
what() << std::endl;
693 std::cout <<
"Saving / loading learning files are ok !" << std::endl;
694 std::cout <<
"testKeyPoint-7 is ok !" << std::endl;
700 std::cerr <<
"You need OpenCV library." << std::endl;
void getTrainKeyPoints(std::vector< cv::KeyPoint > &keyPoints) const
void loadLearningData(const std::string &filename, bool binaryMode=false, bool append=false)
static bool equal(double x, double y, double s=0.001)
error that can be emited by ViSP classes.
static bool parse(int *argcPtr, const char **argv, vpArgvInfo *argTable, int flags)
const char * what() const
void setDetector(const vpFeatureDetectorType &detectorType)
unsigned int buildReference(const vpImage< unsigned char > &I)
void saveLearningData(const std::string &filename, bool binaryMode=false, bool saveTrainingImages=true)
static void read(vpImage< unsigned char > &I, const std::string &filename)
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
cv::Mat getTrainDescriptors() const
void setExtractor(const vpFeatureDescriptorType &extractorType)
Definition of the vpImage class member functions.