c++opencvcomputer-visionblobdiplib

dot detection on the washer with opencv


I am using opencv blob detection function to detect black dots but it cause slow speed and high cpu consumption. Is there more effective way to detect those black dots ? and Blob detection sometimes not detecting some black dots

This is my example image

enter image description here

This is my existing code

SimpleBlobDetector::Params params;
params.minThreshold = 50;
params.maxThreshold = 200;
params.filterByArea = true;
params.minArea = 500;
params.filterByCircularity = true;
params.minCircularity = 0.1;
std::vector<KeyPoint> keypoints;
Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
detector->detect( im, keypoints);
Mat im_with_keypoints;
drawKeypoints( im, keypoints, im_with_keypoints, Scalar(0,0,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS );

These are the black dots try to detect

enter image description here


Solution

  • 1- To be able to increase the speed during SimpleBlobDetector , you can resize your input source dividing by 2 or more. This will still help to find the blobs and also will increase the speed.

    2- On the other hand, for precise solution you can detect each contour and draw circle around them. You can filter the circle by using the radius and also you can enter the inside of circle to count the pixel, to filter the contour size etc. You can go on with morphological functions to achieve the task.

    Here is the code for guideline and output:

    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    RNG rng(12345);
    
    int main()
    {
        
        Mat img = imread("/ur/img/directory/image.png",0);
        imshow("Input",img);
        medianBlur(img,img,5);
        Mat canny_output;
        Canny( img, canny_output, 145, 145*3 );
        vector<vector<Point> > contours;
        findContours( canny_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
        vector<vector<Point> > contours_poly( contours.size() );
        vector<Point2f>centers( contours.size() );
        vector<float>radius( contours.size() );
        for( size_t i = 0; i < contours.size(); i++ )
        {
            approxPolyDP( contours[i], contours_poly[i], 3, true );
            minEnclosingCircle( contours_poly[i], centers[i], radius[i] );
        }
        Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
        for( size_t i = 0; i< contours.size(); i++ )
        {
            Scalar color = Scalar( 0,255,255);
            drawContours( drawing, contours_poly, (int)i, color );
            if((int)radius[i]>0 && (int)radius[i]<100)
                circle( img, centers[i], (int)radius[i], color, 2 );
        }
        imshow("Output",img);
        imshow("Contours",drawing);
        waitKey(0);
        return 0;
    }
    

    enter image description here