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.
After canny my image looks like this:
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.