🐶
Machine Vision

Robust Circle Detection with OpenCV: Hough Transform & More

By Jan on 02/24/2025

Learn how to use OpenCV and techniques like the Hough Transform to implement robust circle detection algorithms that are invariant to color and size variations in images.

Robust Circle Detection with OpenCV: Hough Transform & More

Table of Contents

Introduction

This article provides a step-by-step guide on how to detect circles in an image using OpenCV in Python. The process involves preprocessing the image, detecting edges, applying the Hough Circle Transform, filtering the detected circles, and finally, drawing the circles on the original image.

Step-by-Step Guide

  1. Preprocess the image:

    • Convert the image to grayscale: gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    • Apply Gaussian blur to reduce noise: blurred = cv2.GaussianBlur(gray, (5, 5), 0)
  2. Edge detection:

    • Use Canny edge detection: edges = cv2.Canny(blurred, 50, 150)
  3. Hough Circle Transform:

    • Apply HoughCircles function: circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, dp=1.2, minDist=20, param1=50, param2=30, minRadius=10, maxRadius=50)
  4. Filter detected circles:

    • Loop through detected circles and filter based on size, color, or other criteria.
  5. Draw detected circles:

    • Use cv2.circle() function to draw the detected circles on the original image.

Example code snippet:

import cv2

# Load the image
image = cv2.imread('image.jpg')

# Preprocessing
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)

# Edge detection
edges = cv2.Canny(blurred, 50, 150)

# Hough Circle Transform
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, dp=1.2, minDist=20, param1=50, param2=30, minRadius=10, maxRadius=50)

# Draw detected circles
if circles is not None:
    circles = np.round(circles[0, :]).astype("int")
    for (x, y, r) in circles:
        cv2.circle(image, (x, y), r, (0, 255, 0), 2)

# Display the result
cv2.imshow("Detected Circles", image)
cv2.waitKey(0)

Note: Adjust the parameters of HoughCircles() and filtering criteria based on the specific image and application.

Code Example

This Python code uses OpenCV to detect circles in an image. It loads the image, preprocesses it by converting to grayscale and applying Gaussian blur, detects edges using Canny edge detection, and then applies Hough Circle Transform to find circles. The code then filters the detected circles based on radius and draws the remaining circles on the original image. Finally, it displays the image with the detected circles.

import cv2
import numpy as np

# Load the image
image = cv2.imread('image.jpg')

# Preprocessing
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)

# Edge detection
edges = cv2.Canny(blurred, 50, 150)

# Hough Circle Transform
circles = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, dp=1.2, minDist=20,
                           param1=50, param2=30, minRadius=10, maxRadius=50)

# Draw detected circles
if circles is not None:
    circles = np.round(circles[0, :]).astype("int")
    for (x, y, r) in circles:
        # Filter circles based on size (example: radius between 20 and 40 pixels)
        if 20 < r < 40:
            cv2.circle(image, (x, y), r, (0, 255, 0), 2)

# Display the result
cv2.imshow("Detected Circles", image)
cv2.waitKey(0)

Explanation:

  1. Import necessary libraries: cv2 for image processing and numpy for numerical operations.
  2. Load the image: Replace 'image.jpg' with the path to your image file.
  3. Preprocess the image: Convert to grayscale and apply Gaussian blur to reduce noise.
  4. Edge detection: Use Canny edge detection to find edges in the image.
  5. Hough Circle Transform: Apply the HoughCircles function to detect circles in the edge image. Adjust the parameters as needed for your specific image.
  6. Filter detected circles:
    • The code includes an example filter that only draws circles with a radius between 20 and 40 pixels.
    • You can add more filtering criteria based on your needs, such as color or location.
  7. Draw detected circles: Draw the filtered circles on the original image using cv2.circle().
  8. Display the result: Show the image with detected circles using cv2.imshow().

Remember to adjust the parameters and filtering criteria based on your specific image and application.

Additional Notes

Preprocessing:

  • Grayscale Conversion: Necessary because Hough Circle Transform operates on intensity gradients, not color.
  • Gaussian Blur:
    • Kernel size (5,5) is a common starting point. Adjust based on image noise level.
    • Larger kernel = more blurring = less sensitive to noise, but potential loss of detail.

Edge Detection:

  • Canny Edge Detection:
    • Thresholds (50, 150) control edge sensitivity. Adjust to capture desired circle boundaries.
    • Lower threshold = more edges detected, potentially including noise.
    • Higher threshold = fewer, more prominent edges.

Hough Circle Transform:

  • cv2.HOUGH_GRADIENT: The standard method for circles.
  • dp: Inverse ratio of accumulator resolution to image resolution. Higher dp = fewer accumulator bins = faster but less accurate.
  • minDist: Minimum distance between detected circle centers. Prevents clustering of circles on the same feature.
  • param1: Canny edge detector's higher threshold (passed to Canny internally).
  • param2: Accumulator threshold. Lower value detects more circles (including false ones).
  • minRadius, maxRadius: Limit detected circle sizes. Useful when you have an idea about the target circle dimensions.

Filtering Detected Circles:

  • Essential for real-world images: HoughCircles often produces false positives.
  • Filtering criteria:
    • Size (radius): As shown in the example, filter by a specific radius range.
    • Color: Analyze the average color within each detected circle to eliminate those that don't match your target.
    • Location: If you expect circles in a certain region of the image, discard those outside that area.
    • Circular Hough Transform Score: You can access the accumulator values corresponding to each detected circle. A higher score generally indicates a stronger circle.

Drawing Detected Circles:

  • cv2.circle():
    • (x, y): Circle center coordinates.
    • r: Radius.
    • (0, 255, 0): Green color (BGR format).
    • 2: Line thickness.

General Tips:

  • Parameter Tuning: Experiment with different parameter values for each step to find what works best for your specific images.
  • Image Quality: High-resolution images with good contrast and well-defined circle edges will generally yield better results.
  • Alternative Approaches: If Hough Circle Transform doesn't perform well, consider other circle detection methods like:
    • Contour detection with circle fitting.
    • Randomized Hough Transform.
    • Deep learning-based object detection models.

Summary

This article provides a step-by-step guide to detecting circles in images using OpenCV and the Hough Circle Transform algorithm.

Here's a summary of the process:

  1. Image Preprocessing:

    • Convert the input image to grayscale to simplify processing.
    • Apply Gaussian blur to reduce noise and improve edge detection accuracy.
  2. Edge Detection:

    • Utilize the Canny edge detection algorithm to identify potential circle boundaries.
  3. Hough Circle Transform:

    • Employ the cv2.HoughCircles() function on the edge-detected image to detect circular shapes.
    • This function requires parameter tuning (e.g., dp, minDist, param1, param2, minRadius, maxRadius) to optimize circle detection for specific images.
  4. Circle Filtering:

    • Iterate through the detected circles and apply filtering criteria based on factors like size, color, or other relevant features to eliminate false positives.
  5. Circle Visualization:

    • Draw the detected circles on the original image using the cv2.circle() function for visual confirmation.

Key Points:

  • The provided Python code snippet demonstrates the entire process, from loading the image to displaying the results.
  • Parameter adjustment within the HoughCircles() function and filtering criteria are crucial for accurate circle detection and depend on the specific image and application requirements.

Conclusion

By following these steps, you can effectively detect circles within images using OpenCV and Python. Remember that fine-tuning parameters and applying appropriate filtering techniques are crucial for achieving optimal results based on the specific characteristics of your images and the goals of your application.

References

Were You Able to Follow the Instructions?

😍Love it!
😊Yes
😐Meh-gical
😞No
🤮Clickbait