From 9f74982a549e88ffd8b778a71f87151550cc7e30 Mon Sep 17 00:00:00 2001 From: Yuriy Chernyshov Date: Tue, 3 Oct 2023 15:16:41 +0200 Subject: [PATCH] Merge pull request #24323 from georgthegreat:akaze-variadic --- .../features2d/include/opencv2/features2d.hpp | 9 ++++++++- .../test/AKAZEDescriptorExtractorTest.java | 2 +- modules/features2d/src/akaze.cpp | 20 ++++++++++++++++--- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/modules/features2d/include/opencv2/features2d.hpp b/modules/features2d/include/opencv2/features2d.hpp index 98ae85f353..a7d348d833 100644 --- a/modules/features2d/include/opencv2/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d.hpp @@ -889,11 +889,15 @@ public: @param nOctaveLayers Default number of sublevels per scale level @param diffusivity Diffusivity type. DIFF_PM_G1, DIFF_PM_G2, DIFF_WEICKERT or DIFF_CHARBONNIER + @param max_points Maximum amount of returned points. In case if image contains + more features, then the features with highest response are returned. + Negative value means no limitation. */ CV_WRAP static Ptr create(AKAZE::DescriptorType descriptor_type = AKAZE::DESCRIPTOR_MLDB, int descriptor_size = 0, int descriptor_channels = 3, float threshold = 0.001f, int nOctaves = 4, - int nOctaveLayers = 4, KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2); + int nOctaveLayers = 4, KAZE::DiffusivityType diffusivity = KAZE::DIFF_PM_G2, + int max_points = -1); CV_WRAP virtual void setDescriptorType(AKAZE::DescriptorType dtype) = 0; CV_WRAP virtual AKAZE::DescriptorType getDescriptorType() const = 0; @@ -916,6 +920,9 @@ public: CV_WRAP virtual void setDiffusivity(KAZE::DiffusivityType diff) = 0; CV_WRAP virtual KAZE::DiffusivityType getDiffusivity() const = 0; CV_WRAP virtual String getDefaultName() const CV_OVERRIDE; + + CV_WRAP virtual void setMaxPoints(int max_points) = 0; + CV_WRAP virtual int getMaxPoints() const = 0; }; //! @} features2d_main diff --git a/modules/features2d/misc/java/test/AKAZEDescriptorExtractorTest.java b/modules/features2d/misc/java/test/AKAZEDescriptorExtractorTest.java index fd98cddee1..69b12d00b1 100644 --- a/modules/features2d/misc/java/test/AKAZEDescriptorExtractorTest.java +++ b/modules/features2d/misc/java/test/AKAZEDescriptorExtractorTest.java @@ -58,7 +58,7 @@ public class AKAZEDescriptorExtractorTest extends OpenCVTestCase { extractor.write(filename); - String truth = "%YAML:1.0\n---\nformat: 3\nname: \"Feature2D.AKAZE\"\ndescriptor: 5\ndescriptor_channels: 3\ndescriptor_size: 0\nthreshold: 1.0000000474974513e-03\noctaves: 4\nsublevels: 4\ndiffusivity: 1\n"; + String truth = "%YAML:1.0\n---\nformat: 3\nname: \"Feature2D.AKAZE\"\ndescriptor: 5\ndescriptor_channels: 3\ndescriptor_size: 0\nthreshold: 1.0000000474974513e-03\noctaves: 4\nsublevels: 4\ndiffusivity: 1\nmax_points: -1\n"; String actual = readFile(filename); actual = actual.replaceAll("e([+-])0(\\d\\d)", "e$1$2"); // NOTE: workaround for different platforms double representation assertEquals(truth, actual); diff --git a/modules/features2d/src/akaze.cpp b/modules/features2d/src/akaze.cpp index 7aa97dae36..a41ee55200 100644 --- a/modules/features2d/src/akaze.cpp +++ b/modules/features2d/src/akaze.cpp @@ -61,7 +61,7 @@ namespace cv { public: AKAZE_Impl(DescriptorType _descriptor_type, int _descriptor_size, int _descriptor_channels, - float _threshold, int _octaves, int _sublevels, KAZE::DiffusivityType _diffusivity) + float _threshold, int _octaves, int _sublevels, KAZE::DiffusivityType _diffusivity, int _max_points) : descriptor(_descriptor_type) , descriptor_channels(_descriptor_channels) , descriptor_size(_descriptor_size) @@ -69,6 +69,7 @@ namespace cv , octaves(_octaves) , sublevels(_sublevels) , diffusivity(_diffusivity) + , max_points(_max_points) { } @@ -98,6 +99,9 @@ namespace cv void setDiffusivity(KAZE::DiffusivityType diff_) CV_OVERRIDE{ diffusivity = diff_; } KAZE::DiffusivityType getDiffusivity() const CV_OVERRIDE{ return diffusivity; } + void setMaxPoints(int max_points_) CV_OVERRIDE { max_points = max_points_; } + int getMaxPoints() const CV_OVERRIDE { return max_points; } + // returns the descriptor size in bytes int descriptorSize() const CV_OVERRIDE { @@ -195,6 +199,12 @@ namespace cv KeyPointsFilter::runByPixelsMask(keypoints, mask.getMat()); } + if (max_points > 0 && (int)keypoints.size() > max_points) { + std::partial_sort(keypoints.begin(), keypoints.begin() + max_points, keypoints.end(), + [](const cv::KeyPoint& k1, const cv::KeyPoint& k2) {return k1.response > k2.response;}); + keypoints.erase(keypoints.begin() + max_points, keypoints.end()); + } + if(descriptors.needed()) { impl.Compute_Descriptors(keypoints, descriptors); @@ -215,6 +225,7 @@ namespace cv fs << "octaves" << octaves; fs << "sublevels" << sublevels; fs << "diffusivity" << diffusivity; + fs << "max_points" << max_points; } void read(const FileNode& fn) CV_OVERRIDE @@ -234,6 +245,8 @@ namespace cv sublevels = (int)fn["sublevels"]; if (!fn["diffusivity"].empty()) diffusivity = static_cast((int)fn["diffusivity"]); + if (!fn["max_points"].empty()) + max_points = (int)fn["max_points"]; } DescriptorType descriptor; @@ -243,15 +256,16 @@ namespace cv int octaves; int sublevels; KAZE::DiffusivityType diffusivity; + int max_points; }; Ptr AKAZE::create(DescriptorType descriptor_type, int descriptor_size, int descriptor_channels, float threshold, int octaves, - int sublevels, KAZE::DiffusivityType diffusivity) + int sublevels, KAZE::DiffusivityType diffusivity, int max_points) { return makePtr(descriptor_type, descriptor_size, descriptor_channels, - threshold, octaves, sublevels, diffusivity); + threshold, octaves, sublevels, diffusivity, max_points); } String AKAZE::getDefaultName() const