-
-
Notifications
You must be signed in to change notification settings - Fork 56.5k
A SimpleBlobDetector parameter is not used unless other parameter is set #6667
Copy link
Copy link
Closed
Milestone
Description
SimpleBlobDetector has many parameters, and the two are minDistBetweenBlobs and threshold (set by minThreshold, maxThreshold, thresholdStep)
A developer is forced to use more than one threshold values to use minDistBetweenBlobs parameter, which could degrade processing speed. It also confuses beginners without knowledge in the interworkings of the code because one would normally use just one threshold for blob detection.
Please state the information for your system
- OpenCV version: 3.1
- Host OS: Windows 10
In which part of the OpenCV library you got the issue?
- features2d
- SimpleBlobDetector
Expected behaviour
- SimpleBlobDetector parameter
minDistBetweenBlobsto work if there is only one threshold.
Actual behaviour
minDistBetweenBlobsonly works with more than one threshold because the code that uses them can never be reached.
Steps to reproduce the issue
- Provide a greyscale image of range 0-255.
- Set threshold as
min: 250,max: 260,step: 10, so that only one threshold is used at 250. - Change
minDistBetweenBlobs
Code example to reproduce the issue
Following is as it is currently in opencv/modules/features2d/src/blobdetector.cpp. I inserted my comment inside /* ... */ blocks.
std::vector < std::vector<Center> > centers; /* 1. 'centers' is initialized here*/
for (double thresh = params.minThreshold; thresh < params.maxThreshold; thresh += params.thresholdStep)
{
Mat binarizedImage;
threshold(grayscaleImage, binarizedImage, thresh, 255, THRESH_BINARY);
std::vector < Center > curCenters;
findBlobs(grayscaleImage, binarizedImage, curCenters);
std::vector < std::vector<Center> > newCenters;
for (size_t i = 0; i < curCenters.size(); i++)
{
bool isNew = true;
for (size_t j = 0; j < centers.size(); j++) /* 2. 'centers' has size of 0, so this loop is skipped */
{
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; /* 3. So the code surrounding params.minDistBetweenBlobs is skipped */
if (!isNew)
{
centers[j].push_back(curCenters[i]);
size_t k = centers[j].size() - 1;
while( k > 0 && centers[j][k].radius < centers[j][k-1].radius )
{
centers[j][k] = centers[j][k-1];
k--;
}
centers[j][k] = curCenters[i];
break;
}
}
if (isNew)
newCenters.push_back(std::vector<Center> (1, curCenters[i]));
}
std::copy(newCenters.begin(), newCenters.end(), std::back_inserter(centers)); /* 4. 'centers' is updated here, but it's not useful for blob detectors with one threshold.
}
Reactions are currently unavailable