Rishhh
Rishhh

Reputation: 11

How do I fill in the Circles detected using Hough transform?

using edge detection using hough detection

I'm using Hough circle detection to detect a circle over a binary optic cup region. Using the code below, I can fill in the circle but the lines of canny edge detection shows up inside the filled image. How do I fix that?

import numpy as np
import matplotlib.pyplot as plt

from skimage import data, color
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte

# Read the image
cimage = cv2.imread("cupcluster.jpg")

# Convert the image to grayscale
image = cv2.cvtColor(cimage, cv2.COLOR_BGR2GRAY)

# Perform edge detection using Canny
edges = canny(image, sigma=10, low_threshold=5, high_threshold=50)

# Detect circles using Hough Circle Transform
hough_radii = np.arange(78, 100, 2)
hough_res = hough_circle(edges, hough_radii)
accums, cy, cx, radii = hough_circle_peaks(hough_res, hough_radii, total_num_peaks=1)

# Create an RGB image from the grayscale image
image_rgb = color.gray2rgb(image)

# Iterate over each pixel in the image
for y in range(image.shape[0]):
    for x in range(image.shape[1]):
        # Check if the pixel is inside any of the detected circles
        inside_circle = False
        for center_y, center_x, radius in zip(cy, cx, radii):
            if (x - center_x)**2 + (y - center_y)**2 <= radius**2:
                inside_circle = True
                break
        
        # If the pixel is inside a circle and is black, set it to white
        if inside_circle and image[y, x] == 0:
            image_rgb[y, x] = (255, 255, 255)
        
        # If the pixel is outside a circle and is white, set it to black
        elif not inside_circle and image[y, x] == 255:
            image_rgb[y, x] = (0, 0, 0)

# Display the result
plt.imshow(image_rgb)
plt.title('Image with Filled Circles')
plt.axis('off')
plt.show()

This is the code I've used to transform and fill in. and this is the input I'm getting filled Image with edge lines

Upvotes: 1

Views: 83

Answers (1)

Vardan Grigoryants
Vardan Grigoryants

Reputation: 1419

Pay attention on your checks of whether the pixel is inside a circle.

image[y, x] == 0 and image[y, x] == 255 conditions are redundant causing the bug, just remove them, i.e.

# If the pixel is inside a circle and is black, set it to white
if inside_circle:
    image_rgb[y, x] = (255, 255, 255)

# If the pixel is outside a circle and is white, set it to black
elif not inside_circle:
    image_rgb[y, x] = (0, 0, 0)

Since, in that conditions, your are comparing grayscale version of your original image, it is not necessary true that the pixel in that location will have 0 or 255 values.

Alternatively, to draw the circles you can use skimage built-in draw.disk function like this:

# Create an RGB blank image from the original image
image_rgb = np.zeros_like(cimage)

# Iterating over each detected circles and drawing them
for center_y, center_x, radius in zip(cy, cx, radii):
    rr, cc = disk((center_y, center_x), radius, shape=blank.shape)
    image_rgb[rr, cc] = 255

Or, if you want "to draw of your own", you can use numpy indexing, described here, like this:

# Create an RGB blank image from the original image
image_rgb = np.zeros_like(cimage)

# Iterating over each detected circles and drawing them
nrows, ncols = image.shape
row, col = np.ogrid[:nrows, :ncols]
for center_y, center_x, radius in zip(cy, cx, radii):
    mask = ((row - center_y)**2 + (col - center_x)**2 <= radius**2)
    image_rgb[mask] = 255

Below are full versions.

Version 1 (skimage.draw.disk):

import numpy as np
import matplotlib.pyplot as plt

from skimage import data, color
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte
from skimage.draw import disk

# Read the image
cimage = cv2.imread("cupcluster.jpg")

# Convert the image to grayscale
image = cv2.cvtColor(cimage, cv2.COLOR_BGR2GRAY)

# Perform edge detection using Canny
edges = canny(image, sigma=10, low_threshold=5, high_threshold=50)

# Detect circles using Hough Circle Transform
hough_radii = np.arange(78, 100, 2)
hough_res = hough_circle(edges, hough_radii)
accums, cy, cx, radii = hough_circle_peaks(hough_res, hough_radii, total_num_peaks=1)

# Create an RGB blank image from the original image
image_rgb = np.zeros_like(cimage)

# Iterating over each detected circles and drawing them
for center_y, center_x, radius in zip(cy, cx, radii):
    rr, cc = disk((center_y, center_x), radius, shape=blank.shape)
    image_rgb[rr, cc] = 255

# Display the result
plt.imshow(image_rgb)
plt.title('Image with Filled Circles')
plt.axis('off')
plt.show()

Version 2 (numpy indexing):

import numpy as np
import matplotlib.pyplot as plt

from skimage import data, color
from skimage.transform import hough_circle, hough_circle_peaks
from skimage.feature import canny
from skimage.draw import circle_perimeter
from skimage.util import img_as_ubyte

# Read the image
cimage = cv2.imread("cupcluster.jpg")

# Convert the image to grayscale
image = cv2.cvtColor(cimage, cv2.COLOR_BGR2GRAY)

# Perform edge detection using Canny
edges = canny(image, sigma=10, low_threshold=5, high_threshold=50)

# Detect circles using Hough Circle Transform
hough_radii = np.arange(78, 100, 2)
hough_res = hough_circle(edges, hough_radii)
accums, cy, cx, radii = hough_circle_peaks(hough_res, hough_radii, total_num_peaks=1)

# Create an RGB blank image from the original image
image_rgb = np.zeros_like(cimage)

# Iterating over each detected circles and drawing them
nrows, ncols = image.shape
row, col = np.ogrid[:nrows, :ncols]
for center_y, center_x, radius in zip(cy, cx, radii):
    mask = ((row - center_y)**2 + (col - center_x)**2 <= radius**2)
    image_rgb[mask] = 255

# Display the result
plt.imshow(image_rgb)
plt.title('Image with Filled Circles')
plt.axis('off')
plt.show()

Both versions have better time complexity.

Upvotes: 0

Related Questions