0
votes

I have an image that shows two circles sharing the same center but having a different radius - an inner and an outer circle. I need to check, if these two circles are "broken", that means, if the shape of the circles are somehow frayed or tattered.

The circles always have the same radius, so I'm using HoughCircles of OpenCV with a given radius for each of the two circles, to determine if the image contains the two circles. The circles can be found without any problem. I'm fairly unexperienced to image processing so I thought, using HoughCircles would only find the circles if their shape is flawless, but HoughCircles also finds the circles if they are some edges or curves on the stroke of the circle.

Is there a better way to check, if the two circles are intact or is HoughCircles a totally wrong way? I played a bit with the threshold parameters of HoughCircles but when the threshold is set too low, the algorithm does not find a circle at all no matter it is intact or broken.

Edit: Here is an abstracted images that might make it clearer. http://1drv.ms/1toMHay The inner circle is broken, the outer ok. HoughCircles might detect both circles although the inner should not be detected.

The idea is, that I have a reference Image with both circles intact, to determine the correct radius, threshold and other parameters for the hough circles function to make sure, these are found with hough circles. With these parameters other images should be analyzed to see, if these also contain two intact circles or if at least one circle looks like the inner circle from the image I provided.

Uploaded Images I uploaded some real images to make it clearer what I'm trying to achieve. http://1drv.ms/1nhJJQ9 These images are takes in two different light situations, with direct and indirect light. Each set has an "intact" image and some broken ones. Now I have to detect, if the image is intact or broken and my first approach is, to look if the two circles are intact or frayed somehow. Is that even possible with those images or is there a better way?

2
You should give a link to a couple of images. That will help us to help you :)biquette
maybe you can try my answer from stackoverflow.com/questions/20698613/… and only accept near 100% circles. but diip_thomas answer using contours might be easier ;)Micka

2 Answers

2
votes

Option 1

Too detect if there are circles I would stick to the houghCircles function in OpenCV. To detect if they are tattered/frayed I would suggest using contours.

If you use the OpenCV function findContours() you'll get a list of all the "shapes" in your image. You can then check if any of these contours match your expected criteria. A circle should have a consistent ratio between the contourArea() and the arcLength().

An example of using findContours() and checking the area of each contour:

//Find and draw contours
vector <vector<Point> > contours; // Vector for storing contour
vector<Vec4i> hierarchy;
findContours(binaryImage, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);

for (int i = 0; i < contours.size(); i++) {
 float area = contourArea(contours[i], false);
 if (area > 300) {
  drawContours(inputImage, contours, i, Scalar(0, 0, 255), 2, 8, hierarchy);
 }
}

Make sure you use a binary image as input. This example draws all contours on an image in red that are bigger than 300 in contourArea.

Option 2

Your other option is to stick with the houghCircles() but then do a check for the pixels around the circle you found. If you sweep the pixels in a radius from the center point and count how many pixels are white in your binary image you can create a percentage that might descibe how well your houghCircle fits the image.

You can check the pixel values of a binary image in the following way, you just have to make a statement to only check pixels on your circle.

for(int i=0;i<binaryImage.rows;i++) {
    for(int j=0;j<binaryImage.cols;j++) {
       std::cout << (int)binaryImage.at<uchar>(i,j)<< ",";
    }
    std::cout << "\n";
}
0
votes

as biqutte said, with some images you'll get better help, but my idea is if you kn ow the the radius and the center position, you can write a small function that evaluate the pixel color along the cirle you can set your own margin. an you can the OpenCV function cv::Termcriteria to improve the precision of your algorithm.