Home > front end >  find small defects from the image
find small defects from the image

Time:04-15

I have an image which contains four circles in each corner and there is a defect present in one of the circles, so how to identify it. I have a lot of image with small and big defects. I am resizing the image as the image is of size 1920*1080 to size 960*540. I have tried normalizing the image, then applying threshold and canny edge but I don't know how to identify or recognize the image. I am working with OpenCV C and I am beginner so I don't know which algorithm to apply.

My image is :And you can clearly see that the defect is present in the top left circle and all other circles are without defects.

enter image description here

After canny my image looks like this: enter image description here

Up till now I have tried the below code :

        //resize image
        Mat r_img;
        resize(img, r_img, Size(img.cols / 2, img.rows / 2), 0, 0, INTER_LANCZOS4);

        Mat gfilter;
        cv::GaussianBlur(r_img, gfilter, Size(5, 5),2, 2);

        //convert to grayscale
        Mat gray_img;
        cv::cvtColor(gfilter, gray_img, COLOR_BGR2GRAY);

        double min, max;
        cv::minMaxLoc(gray_img, &min, &max);
        float sub = min;
        float mult = 255.0f / (float)(max - sub);
        cv::Mat normalized = gray_img - sub;
        normalized = mult * normalized;
        cv::imshow("normalized", normalized);

        cv::Mat mask;
        cv::threshold(normalized, mask, 127, 255, THRESH_BINARY)
        
        Mat canny;
        cv::Canny(normalized, canny, 50, 150, 3);

CodePudding user response:

Why you employing the processes such as resizing and blurring? I think they work in the direction of obscuring defects.

Cut out each of the four areas and logPolar() them, will help you to find defects, I think.


//Circle Area Image.
//  In this sample code, this image is created at here.
//  In real, you must cut out the circle region from your source image.
cv::Mat TheSrcCircleImg = cv::Mat::zeros( 101, 101, CV_8UC3 );
cv::Point Center{ 50,50 };  //also, you must estimate this point.
{
    //Draw some cielces 
    cv::circle( TheSrcCircleImg, Center, 48, cv::Scalar(8,96,16), -1 );
    cv::circle( TheSrcCircleImg, Center, 35, cv::Scalar(0,128,0), -1 );
    cv::circle( TheSrcCircleImg, Center, 22, cv::Scalar(255,32,0), 6 );
    cv::circle( TheSrcCircleImg, Center, 29, cv::Scalar(100,100,100), 1 );
    cv::circle( TheSrcCircleImg, Center, 10, cv::Scalar(0,0,0), -1 );
    //Add "defects"
    cv::line( TheSrcCircleImg, cv::Point(70,65), cv::Point(96,55), cv::Scalar(0,255,255), 2 );
    cv::line( TheSrcCircleImg, cv::Point(45,32), cv::Point(30,30), cv::Scalar(0,255,255), 1 );
}
cv::imshow( "The Src", TheSrcCircleImg );

//I found that arguments of logPolar() is not explained in reference manual.
//So, I used werpPolar() intstead.
cv::Mat ResultImg;
cv::warpPolar( TheSrcCircleImg, ResultImg, cv::Size(50,360), Center, 50, cv::INTER_LINEAR cv::WARP_POLAR_LINEAR );
cv::imshow( "Result", ResultImg );
cv::waitKey();

CodePudding user response:

  • locate the circles centers accurately (finding the outlines of the holes is easy);

  • unwind the images to straighten the rings;

  • use template matching on small windows to detect deviations from the clean part. Alternatively, just image differencing.

Remarks:

  • straighten on more than 360° to make sure that the template is tried everywhere;

  • to obtain the template, a good method can be to average all the profiles along the unwound image, then to repeat it to get a squarish image.

  • Related