From 4bb6f58c6bcd747746b5247814589b6570e3bc31 Mon Sep 17 00:00:00 2001 From: matlabbe Date: Fri, 6 Nov 2020 15:35:20 -0500 Subject: [PATCH] Fixed NN strategy on loading ini file if falling on ORB when descriptor is not available. If nonfree is not detected, falling back on SIFT (OpenCV>=4.4 >=3.4.111) or KAZE (OpenCV>=3) or ORB(OpenCV<3) --- include/find_object/Settings.h | 15 +++++++++++--- src/Settings.cpp | 38 ++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/include/find_object/Settings.h b/include/find_object/Settings.h index e2126701..ccf70015 100644 --- a/include/find_object/Settings.h +++ b/include/find_object/Settings.h @@ -112,9 +112,18 @@ class FINDOBJECT_EXP Settings PARAMETER(Camera, 9queueSize, int, 1, "Maximum images buffered from TCP. If 0, all images are buffered."); //List format : [Index:item0;item1;item3;...] - +#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) +#if CV_MAJOR_VERSION >= 3 // NONFREE=SURF, DEFAULT=KAZE + PARAMETER_COND(Feature2D, 1Detector, QString, FINDOBJECT_NONFREE, "7:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK;AGAST;KAZE;AKAZE;SuperPointTorch" , "10:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK;AGAST;KAZE;AKAZE;SuperPointTorch", "Keypoint detector."); + PARAMETER_COND(Feature2D, 2Descriptor, QString, FINDOBJECT_NONFREE, "3:Brief;ORB;SIFT;SURF;BRISK;FREAK;KAZE;AKAZE;LUCID;LATCH;DAISY;SuperPointTorch", "6:Brief;ORB;SIFT;SURF;BRISK;FREAK;KAZE;AKAZE;LUCID;LATCH;DAISY;SuperPointTorch", "Keypoint descriptor."); +#else // NONFREE=SURF, DEFAULT=ORB PARAMETER_COND(Feature2D, 1Detector, QString, FINDOBJECT_NONFREE, "7:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK;AGAST;KAZE;AKAZE;SuperPointTorch" , "4:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK;AGAST;KAZE;AKAZE;SuperPointTorch", "Keypoint detector."); PARAMETER_COND(Feature2D, 2Descriptor, QString, FINDOBJECT_NONFREE, "3:Brief;ORB;SIFT;SURF;BRISK;FREAK;KAZE;AKAZE;LUCID;LATCH;DAISY;SuperPointTorch", "1:Brief;ORB;SIFT;SURF;BRISK;FREAK;KAZE;AKAZE;LUCID;LATCH;DAISY;SuperPointTorch", "Keypoint descriptor."); +#endif +#else // >=4.4 >=3.4.11: NONFREE=SURF, DEFAULT=SIFT + PARAMETER_COND(Feature2D, 1Detector, QString, FINDOBJECT_NONFREE, "7:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK;AGAST;KAZE;AKAZE;SuperPointTorch" , "5:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK;AGAST;KAZE;AKAZE;SuperPointTorch", "Keypoint detector."); + PARAMETER_COND(Feature2D, 2Descriptor, QString, FINDOBJECT_NONFREE, "3:Brief;ORB;SIFT;SURF;BRISK;FREAK;KAZE;AKAZE;LUCID;LATCH;DAISY;SuperPointTorch", "2:Brief;ORB;SIFT;SURF;BRISK;FREAK;KAZE;AKAZE;LUCID;LATCH;DAISY;SuperPointTorch", "Keypoint descriptor."); +#endif PARAMETER(Feature2D, 3MaxFeatures, int, 0, "Maximum features per image. If the number of features extracted is over this threshold, only X features with the highest response are kept. 0 means all features are kept."); PARAMETER(Feature2D, 4Affine, bool, false, "(ASIFT) Extract features on multiple affine transformations of the image."); PARAMETER(Feature2D, 5AffineCount, int, 6, "(ASIFT) Higher the value, more affine transformations will be done."); @@ -234,8 +243,8 @@ class FINDOBJECT_EXP Settings PARAMETER(Feature2D, SuperPointTorch_NMS_radius, int, 4, "[%s=true] Minimum distance (pixels) between keypoints"); PARAMETER(Feature2D, SuperPointTorch_cuda, bool, false, "Use Cuda device for Torch, otherwise CPU device is used by default."); - PARAMETER_COND(NearestNeighbor, 1Strategy, QString, FINDOBJECT_NONFREE, "1:Linear;KDTree;KMeans;Composite;Autotuned;Lsh;BruteForce", "6:Linear;KDTree;KMeans;Composite;Autotuned;Lsh;BruteForce", "Nearest neighbor strategy."); - PARAMETER_COND(NearestNeighbor, 2Distance_type, QString, FINDOBJECT_NONFREE, "0:EUCLIDEAN_L2;MANHATTAN_L1;MINKOWSKI;MAX;HIST_INTERSECT;HELLINGER;CHI_SQUARE_CS;KULLBACK_LEIBLER_KL;HAMMING", "1:EUCLIDEAN_L2;MANHATTAN_L1;MINKOWSKI;MAX;HIST_INTERSECT;HELLINGER;CHI_SQUARE_CS;KULLBACK_LEIBLER_KL;HAMMING", "Distance type."); + PARAMETER_COND(NearestNeighbor, 1Strategy, QString, FINDOBJECT_NONFREE || CV_MAJOR_VERSION >= 3, "1:Linear;KDTree;KMeans;Composite;Autotuned;Lsh;BruteForce", "6:Linear;KDTree;KMeans;Composite;Autotuned;Lsh;BruteForce", "Nearest neighbor strategy."); + PARAMETER_COND(NearestNeighbor, 2Distance_type, QString, FINDOBJECT_NONFREE || CV_MAJOR_VERSION >= 3, "0:EUCLIDEAN_L2;MANHATTAN_L1;MINKOWSKI;MAX;HIST_INTERSECT;HELLINGER;CHI_SQUARE_CS;KULLBACK_LEIBLER_KL;HAMMING", "1:EUCLIDEAN_L2;MANHATTAN_L1;MINKOWSKI;MAX;HIST_INTERSECT;HELLINGER;CHI_SQUARE_CS;KULLBACK_LEIBLER_KL;HAMMING", "Distance type."); PARAMETER(NearestNeighbor, 3nndrRatioUsed, bool, true, "Nearest neighbor distance ratio approach to accept the best match."); PARAMETER(NearestNeighbor, 4nndrRatio, float, 0.8f, "Nearest neighbor distance ratio."); PARAMETER(NearestNeighbor, 5minDistanceUsed, bool, false, "Minimum distance with the nearest descriptor to accept a match."); diff --git a/src/Settings.cpp b/src/Settings.cpp index e0d4568b..8f9175ca 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -137,7 +137,7 @@ ParametersMap Settings::loadSettings(const QString & fileName) int index = str.split(':').first().toInt(); if(key.compare(Settings::kFeature2D_1Detector()) == 0) { -#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV)))) +#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) #if FINDOBJECT_NONFREE == 0 if(index == 5 || index == 7) { @@ -171,7 +171,7 @@ ParametersMap Settings::loadSettings(const QString & fileName) } else if(key.compare(Settings::kFeature2D_2Descriptor()) == 0) { -#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV)))) +#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) #if FINDOBJECT_NONFREE == 0 if(index == 2 || index == 3) { @@ -211,6 +211,32 @@ ParametersMap Settings::loadSettings(const QString & fileName) setParameter(key, value); } } + + //validate descriptors and nearest neighbor compatibilities + bool isBinaryDescriptor = currentDescriptorType().compare("ORB") == 0 || + currentDescriptorType().compare("Brief") == 0 || + currentDescriptorType().compare("BRISK") == 0 || + currentDescriptorType().compare("FREAK") == 0 || + currentDescriptorType().compare("AKAZE") == 0 || + currentDescriptorType().compare("LATCH") == 0 || + currentDescriptorType().compare("LUCID") == 0; + bool binToFloat = getNearestNeighbor_7ConvertBinToFloat(); + if(isBinaryDescriptor && !binToFloat && currentNearestNeighborType().compare("Lsh") != 0 && currentNearestNeighborType().compare("BruteForce") != 0) + { + UWARN("Current selected descriptor type (\"%s\") is binary while nearest neighbor strategy is not (\"%s\").\n" + "Falling back to \"BruteForce\" nearest neighbor strategy with Hamming distance (by default).", + currentDescriptorType().toStdString().c_str(), + currentNearestNeighborType().toStdString().c_str()); + QString tmp = Settings::getNearestNeighbor_1Strategy(); + *tmp.begin() = '6'; // set BruteForce + setNearestNeighbor_1Strategy(tmp); + loadedParameters.insert(Settings::kNearestNeighbor_1Strategy(), tmp); + tmp = Settings::getNearestNeighbor_2Distance_type(); + *tmp.begin() = '8'; // set HAMMING + setNearestNeighbor_2Distance_type(tmp); + loadedParameters.insert(Settings::kNearestNeighbor_2Distance_type(), tmp); + } + UINFO("Settings loaded from %s.", path.toStdString().c_str()); } else @@ -711,7 +737,7 @@ Feature2D * Settings::createKeypointDetector() { //check for nonfree stuff -#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV)))) +#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) #if FINDOBJECT_NONFREE == 0 if(strategies.at(index).compare("SIFT") == 0 || strategies.at(index).compare("SURF") == 0) @@ -997,7 +1023,7 @@ Feature2D * Settings::createKeypointDetector() #endif UDEBUG("type=%s", strategies.at(index).toStdString().c_str()); } -#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV)))) +#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) #if FINDOBJECT_NONFREE == 1 else if(strategies.at(index).compare("SIFT") == 0) { @@ -1126,7 +1152,7 @@ Feature2D * Settings::createDescriptorExtractor() { //check for nonfree stuff -#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV)))) +#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) #if FINDOBJECT_NONFREE == 0 if(strategies.at(index).compare("SIFT") == 0 || strategies.at(index).compare("SURF") == 0) @@ -1352,7 +1378,7 @@ Feature2D * Settings::createDescriptorExtractor() UDEBUG("type=%s", strategies.at(index).toStdString().c_str()); } #endif -#if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV)))) +#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) #if FINDOBJECT_NONFREE == 1 else if(strategies.at(index).compare("SIFT") == 0) {