You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决霍夫变换检测的圆填充后残留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()

修改说明

  1. 使用skimage.draw.disk直接生成圆内所有像素坐标,替代逐像素判断,效率更高
  2. 新增掩码图像,彻底标记所有圆区域,覆盖包括边缘在内的所有像素
  3. 最终图像完全基于掩码生成,不再依赖原始图像的像素值,避免边缘残留

内容的提问来源于stack exchange,提问作者Rishhh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:37:37