如何解决霍夫变换检测的圆填充后残留Canny边缘的问题?
问题:霍夫圆填充后残留Canny边缘线条的解决方法
我正在使用霍夫圆检测算法在二值视杯区域检测圆,通过以下代码可以填充检测到的圆,但填充后的图像内部会出现Canny边缘检测的线条,请问该如何解决?
import numpy as np import matplotlib.pyplot as plt import cv2 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()
问题原因
原代码的填充逻辑仅针对原始灰度图中的纯黑(0)/纯白(255)像素处理,但Canny边缘线条的像素值介于0和255之间,不在判断条件范围内,因此这些边缘像素被保留了下来。
解决方法
直接基于检测到的圆区域生成掩码,用掩码统一填充颜色,彻底覆盖所有圆内像素:
import numpy as np import matplotlib.pyplot as plt import cv2 from skimage import color from skimage.transform import hough_circle, hough_circle_peaks from skimage.feature import canny from skimage.draw import disk # 读取并转换图像 cimage = cv2.imread("cupcluster.jpg") image = cv2.cvtColor(cimage, cv2.COLOR_BGR2GRAY) # Canny边缘检测 edges = canny(image, sigma=10, low_threshold=5, high_threshold=50) # 霍夫圆检测 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) # 创建全黑掩码,标记圆区域 mask = np.zeros_like(image, dtype=np.uint8) for center_y, center_x, radius in zip(cy, cx, radii): # 获取圆内所有像素坐标 rr, cc = disk((center_y, center_x), radius, shape=image.shape) mask[rr, cc] = 255 # 圆内填充为白色 # 生成最终RGB图像:圆内白,圆外黑 image_rgb = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.uint8) image_rgb[mask == 255] = (255, 255, 255) image_rgb[mask == 0] = (0, 0, 0) # 展示结果 plt.imshow(image_rgb) plt.title('Image with Filled Circles') plt.axis('off') plt.show()
修改说明
- 使用
skimage.draw.disk直接生成圆内所有像素坐标,替代逐像素判断,效率更高 - 新增掩码图像,彻底标记所有圆区域,覆盖包括边缘在内的所有像素
- 最终图像完全基于掩码生成,不再依赖原始图像的像素值,避免边缘残留
内容的提问来源于stack exchange,提问作者Rishhh
相关产品推荐
相关产品推荐

