From 755e0143fb8c40fee082b8343a2b3ce383c47a0b Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Wed, 6 Oct 2021 15:05:45 +0300 Subject: [PATCH] Merge pull request #20815 from alalek:fix_20649_revert_19859 features2d: repair SimpleBlobDetector * features2d: revert code change by PR #19859 Reverted commit 76860933f0a31c0abd1b26c1f11b25972cda031e * features2d: check SimpleBlobDetector parameters consistency --- modules/features2d/src/blobdetector.cpp | 23 +++++++++++++------ modules/features2d/test/test_blobdetector.cpp | 1 + 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/modules/features2d/src/blobdetector.cpp b/modules/features2d/src/blobdetector.cpp index c2215cd57c..fb79831807 100644 --- a/modules/features2d/src/blobdetector.cpp +++ b/modules/features2d/src/blobdetector.cpp @@ -44,6 +44,8 @@ #include #include +#include + // Requires CMake flag: DEBUG_opencv_features2d=ON //#define DEBUG_BLOB_DETECTOR @@ -317,6 +319,19 @@ void SimpleBlobDetectorImpl::detect(InputArray image, std::vector& CV_Error(Error::StsUnsupportedFormat, "Blob detector only supports 8-bit images!"); } + CV_CheckGT(params.thresholdStep, 0.0f, ""); + if (params.minThreshold + params.thresholdStep >= params.maxThreshold) + { + // https://github.com/opencv/opencv/issues/6667 + CV_LOG_ONCE_INFO(NULL, "SimpleBlobDetector: params.minDistBetweenBlobs is ignored for case with single threshold"); +#if 0 // OpenCV 5.0 + CV_CheckEQ(params.minRepeatability, 1u, "Incompatible parameters for case with single threshold"); +#else + if (params.minRepeatability != 1) + CV_LOG_WARNING(NULL, "SimpleBlobDetector: params.minRepeatability=" << params.minRepeatability << " is incompatible for case with single threshold. Empty result is expected."); +#endif + } + std::vector < std::vector
> centers; for (double thresh = params.minThreshold; thresh < params.maxThreshold; thresh += params.thresholdStep) { @@ -325,19 +340,13 @@ void SimpleBlobDetectorImpl::detect(InputArray image, std::vector& std::vector < Center > curCenters; findBlobs(grayscaleImage, binarizedImage, curCenters); - if(params.maxThreshold - params.minThreshold <= params.thresholdStep) { - // if the difference between min and max threshold is less than the threshold step - // we're only going to enter the loop once, so we need to add curCenters - // to ensure we still use minDistBetweenBlobs - centers.push_back(curCenters); - } std::vector < std::vector
> newCenters; for (size_t i = 0; i < curCenters.size(); i++) { bool isNew = true; for (size_t j = 0; j < centers.size(); j++) { - double dist = norm(centers[j][centers[j].size() / 2 ].location - curCenters[i].location); + double dist = norm(centers[j][ centers[j].size() / 2 ].location - curCenters[i].location); isNew = dist >= params.minDistBetweenBlobs && dist >= centers[j][ centers[j].size() / 2 ].radius && dist >= curCenters[i].radius; if (!isNew) { diff --git a/modules/features2d/test/test_blobdetector.cpp b/modules/features2d/test/test_blobdetector.cpp index 56b7145862..c6ed09e6a2 100644 --- a/modules/features2d/test/test_blobdetector.cpp +++ b/modules/features2d/test/test_blobdetector.cpp @@ -12,6 +12,7 @@ TEST(Features2d_BlobDetector, bug_6667) SimpleBlobDetector::Params params; params.minThreshold = 250; params.maxThreshold = 260; + params.minRepeatability = 1; // https://github.com/opencv/opencv/issues/6667 std::vector keypoints; Ptr detector = SimpleBlobDetector::create(params);