0

I'm trying to write a script that will identify the circles projected in concentric rings of light. I realize the image is not the best quality, but I'm hoping to still find a way to identify the circles. Once identified, I want to output a measure that tells me how "circular" the circle actually is and if it's being "pulled" in a given direction. Here are the pictures:

enter image description here[![[enter image description here] enter image description here

I've tried this so far which isn't working:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Load the image
image_path = '/mnt/data/IMG_1.JPG'
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Apply Gaussian blur to reduce noise
gray_blurred = cv2.GaussianBlur(gray, (9, 9), 2)

# Use the Hough Circle Transform to detect the central circle
hough_circles = cv2.HoughCircles(gray_blurred, cv2.HOUGH_GRADIENT, dp=1.2, minDist=50, param1=100, param2=30, minRadius=30, maxRadius=150)

# Draw detected Hough circles
if hough_circles is not None:
    hough_circles = np.uint16(np.around(hough_circles))
    for i in hough_circles[0, :]:
        cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
        cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)

# Use Canny edge detection
edges = cv2.Canny(gray_blurred, 50, 150)

# Find contours
contours, _ = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Filter contours based on circularity and size
def is_circle(contour, min_radius, max_radius):
    # Approximate contour to polygon
    approx = cv2.approxPolyDP(contour, 0.02 * cv2.arcLength(contour, True), True)
    # Calculate the radius of the contour
    area = cv2.contourArea(contour)
    if area == 0:
        return False, 0, 0, 0
    perimeter = cv2.arcLength(contour, True)
    circularity = (4 * np.pi * area) / (perimeter * perimeter)
    (x, y), radius = cv2.minEnclosingCircle(contour)
    return 0.7 < circularity < 1.3 and min_radius < radius < max_radius, int(x), int(y), int(radius)

# Draw detected contours as circles
min_radius, max_radius = 30, 150
for contour in contours:
    circle, x, y, radius = is_circle(contour, min_radius, max_radius)
    if circle:
        cv2.circle(img, (x, y), radius, (0, 255, 0), 2)
        cv2.circle(img, (x, y), 2, (0, 0, 255), 3)

# Show the result
plt.figure(figsize=(10, 10))
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title('Detected Circles and Shadows')
plt.axis('off')
plt.show()

This outputs the following image:

enter image description here

6
  • The second image is fully "circle-free" and the first one has only one circle, but "polluted" by the radial spokes. In other words there are no circles to detect ... only sections of circles. Commented Jun 18, 2024 at 20:07
  • Do you expect from object detection algorithms to deliver to you results you have no idea yourself what they should be in first place? Or have you a detailed idea what do you actually want to achieve and which image data do you need for it? Commented Jun 18, 2024 at 20:13
  • Threshold on the rings first using cv2.inRange() and then clean up with morphology. See if that will help? Commented Jun 18, 2024 at 21:20
  • maybe you should display image in every step to see how it looks like. And maybe when it finds circle then you should remove it (e.g. fill it with black color) and search again - to find bigger circle, and later remove it and search another circle (even bigger), etc. Commented Jun 19, 2024 at 2:18
  • please clarify what you consider circles here. there's a concentric quarter-circle pattern, and there is a type of overlay, pink-red in the first and white-brown in the second. Commented Jun 19, 2024 at 14:27

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.