Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting Circles without using Hough Circles

I have an image of a circle, I want to find the circle but not using hough circles.

I found a way, linked here.

But I can't find the transition coordinates from white to black as I don't know the x and y coordinates in the circle. What other methods are there, or how can I make that approach work?

This is my test image:

enter image description here

like image 577
j.doe Avatar asked May 23 '16 20:05

j.doe


People also ask

How to detect concentric circles with houghcircles?

One of the parameters of the HoughCircles () function is the distance between the centers of the circles. This prevents us to easily detect concentric circles. For this, it is necessary to change the minimal or the maximal radius of the circle in the loop, and do more detections of the same image.

How to detect the circles in the image?

The examples can be executed directly in your browser. In order to detect the circles, or any other geometric shape, we first need to detect the edges of the objects present in the image. The edges in an image are the points for which there is a sharp change of color. For instance, the edge of a red ball on a white background is a circle.

How to find circles on grayscale images using Hough transform?

The HoughCircles () function finds circles on grayscale images using a Hough Transform. circles – Output vector of found circles. This vector is encoded as 3-element floating-point vector (x,y,radius). This is only needed in c++ method – Detection method to use. CV_HOUGH_GRADIENT is currently the only available method

What are the parameters of houghcircles?

We will use now HoughCircles, which accepts the following parameters: image: 8-bit, single-channel, grayscale input image. circles: Output vector of found circles. Each vector is encoded as a 3-element floating-point vector (x, y, radius) .


2 Answers

Another approach (that is useful for more than just circles) would be to find the image contours and do image moment analysis on the circle to find it's centre of mass:

enter image description here

enter image description here

I recommend learning them if you'e going to move forward with image processing. They're pretty helpful approaches that transform images into more useful structures.

like image 149
Lamar Latrell Avatar answered Oct 03 '22 01:10

Lamar Latrell


One possible approach is to first threshold the image to get rid of some of the noise around the circle. Then you can extract the edge of the circle using Canny edge detection. Finally, findNonZero to get a list of pixel coordinates.


I first did a quick prototype with Python:

import cv2
import numpy as np

img = cv2.imread('circle.png', 0)
mask = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]
edges = cv2.Canny(mask, 20, 100)
points = np.array([p[0] for p in cv2.findNonZero(edges)])

And then ported it to C++, adding some extra code to save all the intermediate images and plot the found pixels.

#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat img(cv::imread("circle.png", 0));

    cv::Mat mask;
    cv::threshold(img, mask, 127, 255, cv::THRESH_BINARY);

    cv::imwrite("circle_1.png", mask);

    cv::Mat edges;
    cv::Canny(mask, edges, 20, 100);

    cv::imwrite("circle_2.png", edges);

    std::vector<cv::Point2i> points;
    cv::findNonZero(edges, points);

    cv::Mat output(cv::Mat::zeros(edges.size(), CV_8UC3));
    for (auto const& p : points) {
        output.at<cv::Vec3b>(p) = cv::Vec3b(127, 255, 127);
    }
    cv::imwrite("circle_3.png", output);
}

Output of threshold:

Output of Canny:

Re-plotted pixels:

like image 45
Dan Mašek Avatar answered Oct 03 '22 01:10

Dan Mašek