OpenCV  3.1.0
Open Source Computer Vision
Hough Circle Transform

Goal

In this tutorial you will learn how to:

Theory

Hough Circle Transform

Code

  1. What does this program do?
    • Loads an image and blur it to reduce the noise
    • Applies the Hough Circle Transform to the blurred image .
    • Display the detected circle in a window.
  2. The sample code that we will explain can be downloaded from here. A slightly fancier version (which shows trackbars for changing the threshold values) can be found here.
    #include <iostream>
    using namespace cv;
    using namespace std;
    static void help()
    {
    cout << "\nThis program demonstrates circle finding with the Hough transform.\n"
    "Usage:\n"
    "./houghcircles <image_name>, Default is ../data/board.jpg\n" << endl;
    }
    int main(int argc, char** argv)
    {
    cv::CommandLineParser parser(argc, argv,
    "{help h ||}{@image|../data/board.jpg|}"
    );
    if (parser.has("help"))
    {
    help();
    return 0;
    }
    string filename = parser.get<string>("@image");
    if (filename.empty())
    {
    help();
    cout << "no image_name provided" << endl;
    return -1;
    }
    Mat img = imread(filename, 0);
    if(img.empty())
    {
    help();
    cout << "can not open " << filename << endl;
    return -1;
    }
    Mat cimg;
    medianBlur(img, img, 5);
    cvtColor(img, cimg, COLOR_GRAY2BGR);
    vector<Vec3f> circles;
    HoughCircles(img, circles, HOUGH_GRADIENT, 1, 10,
    100, 30, 1, 30 // change the last two parameters
    // (min_radius & max_radius) to detect larger circles
    );
    for( size_t i = 0; i < circles.size(); i++ )
    {
    Vec3i c = circles[i];
    circle( cimg, Point(c[0], c[1]), c[2], Scalar(0,0,255), 3, LINE_AA);
    circle( cimg, Point(c[0], c[1]), 2, Scalar(0,255,0), 3, LINE_AA);
    }
    imshow("detected circles", cimg);
    return 0;
    }

Explanation

  1. Load an image
    src = imread( argv[1], 1 );
    if( !src.data )
    { return -1; }
  2. Convert it to grayscale:
    cvtColor( src, src_gray, COLOR_BGR2GRAY );
  3. Apply a Gaussian blur to reduce noise and avoid false circle detection:
    GaussianBlur( src_gray, src_gray, Size(9, 9), 2, 2 );
  4. Proceed to apply Hough Circle Transform:
    vector<Vec3f> circles;
    HoughCircles( src_gray, circles, HOUGH_GRADIENT, 1, src_gray.rows/8, 200, 100, 0, 0 );
    with the arguments:
    • src_gray: Input image (grayscale).
    • circles: A vector that stores sets of 3 values: \(x_{c}, y_{c}, r\) for each detected circle.
    • HOUGH_GRADIENT: Define the detection method. Currently this is the only one available in OpenCV.
    • dp = 1: The inverse ratio of resolution.
    • min_dist = src_gray.rows/8: Minimum distance between detected centers.
    • param_1 = 200: Upper threshold for the internal Canny edge detector.
    • param_2 = 100*: Threshold for center detection.
    • min_radius = 0: Minimum radio to be detected. If unknown, put zero as default.
    • max_radius = 0: Maximum radius to be detected. If unknown, put zero as default.
  5. Draw the detected circles:
    for( size_t i = 0; i < circles.size(); i++ )
    {
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    int radius = cvRound(circles[i][2]);
    // circle center
    circle( src, center, 3, Scalar(0,255,0), -1, 8, 0 );
    // circle outline
    circle( src, center, radius, Scalar(0,0,255), 3, 8, 0 );
    }
    You can see that we will draw the circle(s) on red and the center(s) with a small green dot
  6. Display the detected circle(s):
    namedWindow( "Hough Circle Transform Demo", WINDOW_AUTOSIZE );
    imshow( "Hough Circle Transform Demo", src );
  7. Wait for the user to exit the program

Result

The result of running the code above with a test image is shown below:

Hough_Circle_Tutorial_Result.jpg