From 126159e2ed1148429b9234aad13ebbeda9a9917f Mon Sep 17 00:00:00 2001 From: Matthieu Hog Date: Thu, 16 Nov 2023 11:58:18 +0100 Subject: [PATCH 1/4] added unknown image detector/descriptor type --- src/aliceVision/feature/ImageDescriber.cpp | 4 + src/aliceVision/feature/ImageDescriber.hpp | 110 ++++++++++++++++++ .../feature/imageDescriberCommon.hpp | 5 +- src/aliceVision/feature/regionsFactory.hpp | 3 + src/aliceVision/sfm/pipeline/regionsIO.cpp | 4 +- src/aliceVision/voctree/VocabularyTree.hpp | 3 + 6 files changed, 124 insertions(+), 5 deletions(-) diff --git a/src/aliceVision/feature/ImageDescriber.cpp b/src/aliceVision/feature/ImageDescriber.cpp index 883818d9bf..5cdf5f1626 100644 --- a/src/aliceVision/feature/ImageDescriber.cpp +++ b/src/aliceVision/feature/ImageDescriber.cpp @@ -228,6 +228,10 @@ std::unique_ptr createImageDescriber(EImageDescriberType imageDe case EImageDescriberType::AKAZE_LIOP: describerPtr.reset(new ImageDescriber_AKAZE(AKAZEParams(AKAZEOptions(), feature::AKAZE_LIOP))); break; + //Unknown descriptor to be used when the descriptor is computed outside of alicevsion + case EImageDescriberType::UNKNOWN: + describerPtr.reset(new UnknownImageDescriber()); + break; #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) case EImageDescriberType::CCTAG3: diff --git a/src/aliceVision/feature/ImageDescriber.hpp b/src/aliceVision/feature/ImageDescriber.hpp index 2bb84a3f4f..5d91a9fa1c 100644 --- a/src/aliceVision/feature/ImageDescriber.hpp +++ b/src/aliceVision/feature/ImageDescriber.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -260,6 +261,115 @@ class ImageDescriber void LoadFeatures(Regions* regions, const std::string& sfileNameFeats) const { regions->LoadFeatures(sfileNameFeats); } }; +/** + * @brief Used to load descripters computed outside of meshroom. + */ +class UnknownImageDescriber : public ImageDescriber +{ + public: + UnknownImageDescriber() = default; + + virtual ~UnknownImageDescriber() = default; + + /** + * @brief Check if the image describer use CUDA + * @return True if the image describer use CUDA + */ + bool useCuda() const override { return false; } + + /** + * @brief Check if the image describer use float image + * @return True if the image describer use float image + */ + bool useFloatImage() const override { return false; } + + /** + * @brief Get the corresponding EImageDescriberType + * @return EImageDescriberType + */ + EImageDescriberType getDescriberType() const override { return EImageDescriberType::UNKNOWN; } + + /** + * @brief Get the total amount of RAM needed for a + * feature extraction of an image of the given dimension. + * @param[in] width The image width + * @param[in] height The image height + * @return total amount of memory needed + */ + std::size_t getMemoryConsumption(std::size_t width, std::size_t height) const override + { + return 0; + } + + /** + * @brief Set image describer always upRight + * @param[in] upRight + */ + void setUpRight(bool upRight) override + {} + + /** + * @brief Set if yes or no imageDescriber need to use cuda implementation + * @param[in] useCuda + */ + void setUseCuda(bool useCuda) override + {} + + /** + * @brief set the CUDA pipe + * @param[in] pipe The CUDA pipe id + */ + void setCudaPipe(int pipe) override + {} + + /** + * @brief Use a preset to control the number of detected regions + * @param[in] preset The preset configuration + */ + void setConfigurationPreset(ConfigurationPreset preset) override + {} + + /** + * @brief Detect regions on the 8-bit image and compute their attributes (description) + * @param[in] image Image. + * @param[out] regions The detected regions and attributes (the caller must delete the allocated data) + * @param[in] mask 8-bit grayscale image for keypoint filtering (optional) + * Non-zero values depict the region of interest. + * @return True if detection succed. + */ + bool describe(const image::Image& image, + std::unique_ptr& regions, + const image::Image* mask = nullptr) override + { + return false; + } + + /** + * @brief Detect regions on the float image and compute their attributes (description) + * @param[in] image Image. + * @param[out] regions The detected regions and attributes (the caller must delete the allocated data) + * @param[in] mask 8-bit gray image for keypoint filtering (optional). + * Non-zero values depict the region of interest. + * @return True if detection succed. + */ + bool describe(const image::Image& image, std::unique_ptr& regions, const image::Image* mask = nullptr) override + { + return false; + } + + /** + * @brief Allocate Regions type depending of the ImageDescriber + * @param[in,out] regions + */ + void allocate(std::unique_ptr& regions) const override + { + regions.reset(new UNKNOWN_Regions); + } + + private: + std::unique_ptr _imageDescriberImpl = nullptr; +}; + /** * @brief Create the desired ImageDescriber method. * Don't use a factory, perform direct allocation. diff --git a/src/aliceVision/feature/imageDescriberCommon.hpp b/src/aliceVision/feature/imageDescriberCommon.hpp index 937a3f28a8..678d81cf02 100644 --- a/src/aliceVision/feature/imageDescriberCommon.hpp +++ b/src/aliceVision/feature/imageDescriberCommon.hpp @@ -23,9 +23,8 @@ enum class EImageDescriberType : unsigned char SIFT = 10, SIFT_FLOAT = 11, SIFT_UPRIGHT = 12, - DSPSIFT = 13 - - , + DSPSIFT = 13, + AKAZE = 20, AKAZE_LIOP = 21, AKAZE_MLDB = 22 diff --git a/src/aliceVision/feature/regionsFactory.hpp b/src/aliceVision/feature/regionsFactory.hpp index 58e98a392c..72a928a1f7 100644 --- a/src/aliceVision/feature/regionsFactory.hpp +++ b/src/aliceVision/feature/regionsFactory.hpp @@ -29,5 +29,8 @@ using AKAZE_Liop_Regions = ScalarRegions; /// Define the AKAZE Keypoint (with a binary descriptor saved in an uchar array) using AKAZE_BinaryRegions = BinaryRegions<64>; +/// Define an unknown feature regions +using UNKNOWN_Regions = ScalarRegions; + } // namespace feature } // namespace aliceVision diff --git a/src/aliceVision/sfm/pipeline/regionsIO.cpp b/src/aliceVision/sfm/pipeline/regionsIO.cpp index 19e5555f5c..9d3c4f227e 100644 --- a/src/aliceVision/sfm/pipeline/regionsIO.cpp +++ b/src/aliceVision/sfm/pipeline/regionsIO.cpp @@ -26,7 +26,7 @@ using namespace sfmData; std::unique_ptr loadRegions(const std::vector& folders, IndexT viewId, const feature::ImageDescriber& imageDescriber) { assert(!folders.empty()); - + const std::string imageDescriberTypeName = feature::EImageDescriberType_enumToString(imageDescriber.getDescriberType()); const std::string basename = std::to_string(viewId); @@ -228,7 +228,7 @@ bool loadRegionsPerView(feature::RegionsPerView& regionsPerView, std::unique_ptr regionsPtr; try { - regionsPtr = loadRegions(featuresFolders, iter->second.get()->getViewId(), *(imageDescribers.at(i))); + regionsPtr = loadRegions(featuresFolders, iter->second.get()->getViewId(), *(imageDescribers.at(i))); } catch (const std::exception& e) { diff --git a/src/aliceVision/voctree/VocabularyTree.hpp b/src/aliceVision/voctree/VocabularyTree.hpp index 96abbc0904..7c973e326d 100644 --- a/src/aliceVision/voctree/VocabularyTree.hpp +++ b/src/aliceVision/voctree/VocabularyTree.hpp @@ -360,6 +360,9 @@ inline std::unique_ptr createVoctreeForDescriberType(feature::E case EImageDescriberType::AKAZE_MLDB: res.reset(new VocabularyTree); break; + case EImageDescriberType::UNKNOWN: + res.reset(new VocabularyTree); + break; #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) case EImageDescriberType::CCTAG3: From e522f080596cbfa89c333e1dab18bcfb6acf9b47 Mon Sep 17 00:00:00 2001 From: Matthieu Hog Date: Tue, 3 Sep 2024 16:38:34 +0200 Subject: [PATCH 2/4] renamed to generic --- src/aliceVision/feature/ImageDescriber.cpp | 6 +++--- src/aliceVision/feature/ImageDescriber.hpp | 10 +++++----- src/aliceVision/feature/imageDescriberCommon.cpp | 5 +++++ src/aliceVision/feature/imageDescriberCommon.hpp | 7 +++++-- src/aliceVision/feature/regionsFactory.hpp | 2 +- src/aliceVision/matching/svgVisualization.cpp | 4 ++++ src/aliceVision/sfm/pipeline/regionsIO.cpp | 4 ++-- src/aliceVision/voctree/VocabularyTree.hpp | 4 ++-- 8 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/aliceVision/feature/ImageDescriber.cpp b/src/aliceVision/feature/ImageDescriber.cpp index 5cdf5f1626..055f859877 100644 --- a/src/aliceVision/feature/ImageDescriber.cpp +++ b/src/aliceVision/feature/ImageDescriber.cpp @@ -228,9 +228,9 @@ std::unique_ptr createImageDescriber(EImageDescriberType imageDe case EImageDescriberType::AKAZE_LIOP: describerPtr.reset(new ImageDescriber_AKAZE(AKAZEParams(AKAZEOptions(), feature::AKAZE_LIOP))); break; - //Unknown descriptor to be used when the descriptor is computed outside of alicevsion - case EImageDescriberType::UNKNOWN: - describerPtr.reset(new UnknownImageDescriber()); + //Generic descriptor to be used when the descriptor is computed outside of alicevsion + case EImageDescriberType::GENERIC: + describerPtr.reset(new GenericImageDescriber()); break; #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) diff --git a/src/aliceVision/feature/ImageDescriber.hpp b/src/aliceVision/feature/ImageDescriber.hpp index 5d91a9fa1c..59c0652523 100644 --- a/src/aliceVision/feature/ImageDescriber.hpp +++ b/src/aliceVision/feature/ImageDescriber.hpp @@ -264,12 +264,12 @@ class ImageDescriber /** * @brief Used to load descripters computed outside of meshroom. */ -class UnknownImageDescriber : public ImageDescriber +class GenericImageDescriber : public ImageDescriber { public: - UnknownImageDescriber() = default; + GenericImageDescriber() = default; - virtual ~UnknownImageDescriber() = default; + virtual ~GenericImageDescriber() = default; /** * @brief Check if the image describer use CUDA @@ -287,7 +287,7 @@ class UnknownImageDescriber : public ImageDescriber * @brief Get the corresponding EImageDescriberType * @return EImageDescriberType */ - EImageDescriberType getDescriberType() const override { return EImageDescriberType::UNKNOWN; } + EImageDescriberType getDescriberType() const override { return EImageDescriberType::GENERIC; } /** * @brief Get the total amount of RAM needed for a @@ -363,7 +363,7 @@ class UnknownImageDescriber : public ImageDescriber */ void allocate(std::unique_ptr& regions) const override { - regions.reset(new UNKNOWN_Regions); + regions.reset(new GENERIC_Regions); } private: diff --git a/src/aliceVision/feature/imageDescriberCommon.cpp b/src/aliceVision/feature/imageDescriberCommon.cpp index 448db0a231..32c2945808 100644 --- a/src/aliceVision/feature/imageDescriberCommon.cpp +++ b/src/aliceVision/feature/imageDescriberCommon.cpp @@ -61,6 +61,8 @@ std::string EImageDescriberType_enumToString(EImageDescriberType imageDescriberT return "akaze_liop"; case EImageDescriberType::AKAZE_MLDB: return "akaze_mldb"; + case EImageDescriberType::GENERIC: + return "generic"; #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) case EImageDescriberType::CCTAG3: @@ -113,6 +115,9 @@ EImageDescriberType EImageDescriberType_stringToEnum(const std::string& imageDes if (type == "akaze_mldb") return EImageDescriberType::AKAZE_MLDB; + if (type == "generic") + return EImageDescriberType::GENERIC; + #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) if (type == "cctag3") return EImageDescriberType::CCTAG3; diff --git a/src/aliceVision/feature/imageDescriberCommon.hpp b/src/aliceVision/feature/imageDescriberCommon.hpp index 678d81cf02..75cc77f9bf 100644 --- a/src/aliceVision/feature/imageDescriberCommon.hpp +++ b/src/aliceVision/feature/imageDescriberCommon.hpp @@ -27,7 +27,9 @@ enum class EImageDescriberType : unsigned char AKAZE = 20, AKAZE_LIOP = 21, - AKAZE_MLDB = 22 + AKAZE_MLDB = 22, + + GENERIC = 100 #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) , @@ -111,7 +113,8 @@ inline float getStrongSupportCoeff(EImageDescriberType imageDescriberType) case EImageDescriberType::AKAZE_LIOP: case EImageDescriberType::AKAZE_MLDB: return 0.14f; - + case EImageDescriberType::GENERIC: + return -1.0f; #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) case EImageDescriberType::CCTAG3: case EImageDescriberType::CCTAG4: diff --git a/src/aliceVision/feature/regionsFactory.hpp b/src/aliceVision/feature/regionsFactory.hpp index 72a928a1f7..bb6b992edc 100644 --- a/src/aliceVision/feature/regionsFactory.hpp +++ b/src/aliceVision/feature/regionsFactory.hpp @@ -30,7 +30,7 @@ using AKAZE_Liop_Regions = ScalarRegions; using AKAZE_BinaryRegions = BinaryRegions<64>; /// Define an unknown feature regions -using UNKNOWN_Regions = ScalarRegions; +using GENERIC_Regions = ScalarRegions; } // namespace feature } // namespace aliceVision diff --git a/src/aliceVision/matching/svgVisualization.cpp b/src/aliceVision/matching/svgVisualization.cpp index 1f448d2d6d..bc482a4bc0 100644 --- a/src/aliceVision/matching/svgVisualization.cpp +++ b/src/aliceVision/matching/svgVisualization.cpp @@ -36,6 +36,10 @@ std::string describerTypeColor(feature::EImageDescriberType descType) return "purple"; case feature::EImageDescriberType::AKAZE_MLDB: return "purple"; + + case feature::EImageDescriberType::GENERIC: + return "black"; + #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) case feature::EImageDescriberType::CCTAG3: return "blue"; diff --git a/src/aliceVision/sfm/pipeline/regionsIO.cpp b/src/aliceVision/sfm/pipeline/regionsIO.cpp index 9d3c4f227e..19e5555f5c 100644 --- a/src/aliceVision/sfm/pipeline/regionsIO.cpp +++ b/src/aliceVision/sfm/pipeline/regionsIO.cpp @@ -26,7 +26,7 @@ using namespace sfmData; std::unique_ptr loadRegions(const std::vector& folders, IndexT viewId, const feature::ImageDescriber& imageDescriber) { assert(!folders.empty()); - + const std::string imageDescriberTypeName = feature::EImageDescriberType_enumToString(imageDescriber.getDescriberType()); const std::string basename = std::to_string(viewId); @@ -228,7 +228,7 @@ bool loadRegionsPerView(feature::RegionsPerView& regionsPerView, std::unique_ptr regionsPtr; try { - regionsPtr = loadRegions(featuresFolders, iter->second.get()->getViewId(), *(imageDescribers.at(i))); + regionsPtr = loadRegions(featuresFolders, iter->second.get()->getViewId(), *(imageDescribers.at(i))); } catch (const std::exception& e) { diff --git a/src/aliceVision/voctree/VocabularyTree.hpp b/src/aliceVision/voctree/VocabularyTree.hpp index 7c973e326d..f63d818502 100644 --- a/src/aliceVision/voctree/VocabularyTree.hpp +++ b/src/aliceVision/voctree/VocabularyTree.hpp @@ -360,8 +360,8 @@ inline std::unique_ptr createVoctreeForDescriberType(feature::E case EImageDescriberType::AKAZE_MLDB: res.reset(new VocabularyTree); break; - case EImageDescriberType::UNKNOWN: - res.reset(new VocabularyTree); + case EImageDescriberType::GENERIC: + res.reset(new VocabularyTree); break; #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) From 7e818744c257752004af6a56eb5c3a4b00d1a63e Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Wed, 4 Sep 2024 23:13:22 +0200 Subject: [PATCH 3/4] generic should have the same coef than standard descriptor types --- src/aliceVision/feature/imageDescriberCommon.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/aliceVision/feature/imageDescriberCommon.hpp b/src/aliceVision/feature/imageDescriberCommon.hpp index 75cc77f9bf..d0cedae257 100644 --- a/src/aliceVision/feature/imageDescriberCommon.hpp +++ b/src/aliceVision/feature/imageDescriberCommon.hpp @@ -112,9 +112,8 @@ inline float getStrongSupportCoeff(EImageDescriberType imageDescriberType) case EImageDescriberType::AKAZE: case EImageDescriberType::AKAZE_LIOP: case EImageDescriberType::AKAZE_MLDB: - return 0.14f; case EImageDescriberType::GENERIC: - return -1.0f; + return 0.14f; #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) case EImageDescriberType::CCTAG3: case EImageDescriberType::CCTAG4: From 6738642a2bce3196d12368e4610078e23f3afe27 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Wed, 4 Sep 2024 23:13:36 +0200 Subject: [PATCH 4/4] enum formatting --- .../feature/imageDescriberCommon.hpp | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/aliceVision/feature/imageDescriberCommon.hpp b/src/aliceVision/feature/imageDescriberCommon.hpp index d0cedae257..0434dd05bd 100644 --- a/src/aliceVision/feature/imageDescriberCommon.hpp +++ b/src/aliceVision/feature/imageDescriberCommon.hpp @@ -27,29 +27,25 @@ enum class EImageDescriberType : unsigned char AKAZE = 20, AKAZE_LIOP = 21, - AKAZE_MLDB = 22, - - GENERIC = 100 + AKAZE_MLDB = 22 #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_CCTAG) - , - CCTAG3 = 30, - CCTAG4 = 31 + , CCTAG3 = 30 + , CCTAG4 = 31 #endif #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_OPENCV) #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_OCVSIFT) - , - SIFT_OCV = 40 + , SIFT_OCV = 40 #endif - , - AKAZE_OCV = 41 + , AKAZE_OCV = 41 #endif #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_APRILTAG) - , - APRILTAG16H5 = 50 + , APRILTAG16H5 = 50 #endif + + , GENERIC = 100 }; /**