Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

bug in SimpleBlobDetector?

Hi, I am looking the implementation of SimpleBlobDetector. It looks the insertions sort is not correct as shown below. I also copy entire SimpleBlobDetector codes at the end.

For the insertion sort, we should compare with the key or switch values, right? The following OpenCV code looks weird.

                size_t k = centers[j].size() - 1;
                while( k > 0 && centers[j][k].radius < centers[j][k-1].radius )//compare with key
                {
                    centers[j][k] = centers[j][k-1];//or switch values here
                    k--;
                }
                centers[j][k] = curCenters[i];

Entire blob detection codes:

void SimpleBlobDetectorImpl::detect(InputArray image, std::vector<cv::keypoint>& keypoints, InputArray) { //TODO: support mask keypoints.clear(); Mat grayscaleImage; if (image.channels() == 3) cvtColor(image, grayscaleImage, COLOR_BGR2GRAY); else grayscaleImage = image.getMat();

std::vector < std::vector<Center> > centers;
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++)
        {
            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)
            {
                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];//should switch here?
                    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));
}

for (size_t i = 0; i < centers.size(); i++)
{
    if (centers[i].size() < params.minRepeatability)
        continue;
    Point2d sumPoint(0, 0);
    double normalizer = 0;
    for (size_t j = 0; j < centers[i].size(); j++)
    {
        sumPoint += centers[i][j].confidence * centers[i][j].location;
        normalizer += centers[i][j].confidence;
    }
    sumPoint *= (1. / normalizer);
    KeyPoint kpt(sumPoint, (float)(centers[i][centers[i].size() / 2].radius) * 2.0f);
    keypoints.push_back(kpt);
}

}

click to hide/show revision 2
No.2 Revision

bug in SimpleBlobDetector?

Hi, I am looking the implementation of SimpleBlobDetector. It looks the insertions sort is not correct as shown below. I also copy entire SimpleBlobDetector codes at the end.

For the insertion sort, we should compare with the key or switch values, right? The following OpenCV code looks weird.

 size_t k = centers[j].size() - 1;
 while( k > 0 && centers[j][k].radius < centers[j][k-1].radius )//compare with key
 {
     centers[j][k] = centers[j][k-1];//or switch values here
     k--;
 }
 centers[j][k] = curCenters[i];

Entire blob detection codes:

void SimpleBlobDetectorImpl::detect(InputArray image, std::vector<cv::keypoint>& std::vector<cv::KeyPoint>& keypoints, InputArray)
{
    //TODO: support mask
    keypoints.clear();
    Mat grayscaleImage;
    if (image.channels() == 3)
        cvtColor(image, grayscaleImage, COLOR_BGR2GRAY);
    else
        grayscaleImage = image.getMat();

image.getMat();

    std::vector < std::vector<Center> > centers;
 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++)
         {
             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)
             {
                 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];//should switch here?
                     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));
 }

 for (size_t i = 0; i < centers.size(); i++)
 {
     if (centers[i].size() < params.minRepeatability)
         continue;
     Point2d sumPoint(0, 0);
     double normalizer = 0;
     for (size_t j = 0; j < centers[i].size(); j++)
     {
         sumPoint += centers[i][j].confidence * centers[i][j].location;
         normalizer += centers[i][j].confidence;
     }
     sumPoint *= (1. / normalizer);
     KeyPoint kpt(sumPoint, (float)(centers[i][centers[i].size() / 2].radius) * 2.0f);
     keypoints.push_back(kpt);
    }
}

}

bug in SimpleBlobDetector?

Hi, I am looking the implementation of SimpleBlobDetector. It looks the insertions sort is not correct as shown below. I also copy entire SimpleBlobDetector codes at the end.

For the insertion sort, we should compare with the key or switch values, right? The following OpenCV code looks weird.

size_t k = centers[j].size() - 1;
while( k > 0 && centers[j][k].radius < centers[j][k-1].radius )//compare with key
{
    centers[j][k] = centers[j][k-1];//or switch values here
    k--;
}
centers[j][k] = curCenters[i];

Entire blob detection codes:

void SimpleBlobDetectorImpl::detect(InputArray image, std::vector<cv::KeyPoint>& keypoints, InputArray)
{
    //TODO: support mask
    keypoints.clear();
    Mat grayscaleImage;
    if (image.channels() == 3)
        cvtColor(image, grayscaleImage, COLOR_BGR2GRAY);
    else
        grayscaleImage = image.getMat();

    std::vector < std::vector<Center> > centers;
    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++)
            {
                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)
                {
                    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];//should switch here?
                        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));
    }

    for (size_t i = 0; i < centers.size(); i++)
    {
        if (centers[i].size() < params.minRepeatability)
            continue;
        Point2d sumPoint(0, 0);
        double normalizer = 0;
        for (size_t j = 0; j < centers[i].size(); j++)
        {
            sumPoint += centers[i][j].confidence * centers[i][j].location;
            normalizer += centers[i][j].confidence;
        }
        sumPoint *= (1. / normalizer);
        KeyPoint kpt(sumPoint, (float)(centers[i][centers[i].size() / 2].radius) * 2.0f);
        keypoints.push_back(kpt);
    }
}