我正在使用霍夫圆检测来检测二元视杯区域上的圆。 使用下面的代码,我可以填充圆圈,但精明的边缘检测线显示在填充图像内。我该如何解决这个问题?
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()
注意检查像素是否在圆内。
image[y, x] == 0
和 image[y, x] == 255
条件是多余的,会导致错误,只需删除它们即可,即
# 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)
由于在这种情况下,您正在比较原始图像的灰度版本,因此该位置的像素不一定具有 0 或 255 个值。
或者,要绘制圆圈,您可以使用
skimage
内置 draw.disk
函数,如下所示:
# 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
或者,如果您想“自己绘制”,您可以使用 numpy 索引,如here所述,如下所示:
# 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
以下是完整版。
版本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()
版本 2(numpy 索引):
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()
两个版本都有更好的时间复杂度。