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

如何让Scikit-Image的Hough变换检测到立方体的另一条边缘?

问题:Hough变换检测立方体边缘遗漏的解决方法

我尝试使用Scikit-Image库中的Hough变换检测下图中的立方体边缘:
原始立方体图像

更新
以下是我正在使用的代码:

smoothed_image = filters.frangi(gray_image)

# Perform edge detection using the Canny edge detector
low_threshold = 0.1  
high_threshold = 3  
low_threshold = low * smoothed_image.max()
high_threshold = high * low_threshold
edges = canny(smoothed_image, sigma, low_threshold=low_threshold,
             high_threshold=high_threshold)


# Hough transform to detect the filament profile
hspace, theta, dist = hough_line(edges)

# Find the vertical lines
vertical_peaks = hough_line_peaks(hspace, theta, dist, num_peaks=2)

vertical_lines = []

for _, angle, dist in zip(*vertical_peaks):
    x = dist * np.cos(angle)
    y = dist * np.sin(angle)
    vertical_lines.append((x, y))


# Visualize the results
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(smoothed_image)
axes[0].set_title('Smoothed Image')
#axes[0].axis('off')
axes[1].imshow(edges, cmap='gray')
axes[1].set_title('Canny Edge Detection')
axes[1].axis('off')
axes[2].imshow(edges, cmap='gray')
for x, y in vertical_lines:
    axes[2].axvline(x=x, color='red')
axes[2].set_xlim((0, image.shape[1]))
axes[2].set_ylim((image.shape[0], 0))
axes[2].set_title('Detected Lines')
axes[2].axis('off')
plt.tight_layout()
plt.show()

运行后得到如下输出结果:
检测结果输出

请问如何调整才能让Hough变换检测到遗漏的那条边缘?


解决建议

1. 优化预处理步骤

Frangi滤波主打管状结构检测(如血管),对立方体这类规则边缘适配性差,改用高斯滤波能更高效地去噪并保留边缘:

# 替换Frangi滤波为高斯滤波
smoothed_image = filters.gaussian(gray_image, sigma=1.0)

2. 修正并调整Canny边缘检测参数

原代码存在变量名错误(low未定义),且高低阈值比例过高,导致弱边缘被过滤,调整后:

# 修正阈值计算并调整比例
low_threshold = 0.05 * smoothed_image.max()
high_threshold = 2 * low_threshold  # 降低高阈值与低阈值的比例
edges = feature.canny(smoothed_image, sigma=1.0,
                     low_threshold=low_threshold,
                     high_threshold=high_threshold)
  • 降低low_threshold比例,确保弱边缘能被保留
  • sigma建议在0.8-1.2之间测试,平衡噪声过滤与边缘清晰度

3. 改进Hough变换的峰值检测逻辑

  • 增加峰值数量:将num_peaks从2改为3,匹配立方体3条垂直边缘的需求
  • 过滤垂直角度:只保留接近90°(np.pi/2)的角度,排除无关方向干扰
  • 降低峰值阈值:让较弱的峰值也能被检测到

修改后的Hough检测代码:

# Hough变换
hspace, theta, dist = transform.hough_line(edges)

# 过滤垂直方向的角度(允许±0.1弧度的偏差)
vertical_angle_mask = np.abs(theta - np.pi/2) < 0.1
filtered_hspace = hspace.copy()
filtered_hspace[~vertical_angle_mask] = 0  # 非垂直方向的投票置0

# 检测3个峰值,降低阈值要求
vertical_peaks = transform.hough_line_peaks(filtered_hspace, theta, dist,
                                           num_peaks=3, threshold=0.3 * hspace.max())

4. 完整修改后的代码

import numpy as np
import matplotlib.pyplot as plt
from skimage import filters, feature, transform, io, color

# 读取图像并转为灰度图
image = io.imread('cube_image.jpg')
gray_image = color.rgb2gray(image) if len(image.shape) == 3 else image

# 预处理:高斯滤波
smoothed_image = filters.gaussian(gray_image, sigma=1.0)

# Canny边缘检测
low_threshold = 0.05 * smoothed_image.max()
high_threshold = 2 * low_threshold
edges = feature.canny(smoothed_image, sigma=1.0,
                     low_threshold=low_threshold,
                     high_threshold=high_threshold)

# Hough变换与垂直边缘过滤
hspace, theta, dist = transform.hough_line(edges)
vertical_angle_mask = np.abs(theta - np.pi/2) < 0.1
filtered_hspace = hspace.copy()
filtered_hspace[~vertical_angle_mask] = 0

# 检测3个峰值
vertical_peaks = transform.hough_line_peaks(filtered_hspace, theta, dist,
                                           num_peaks=3, threshold=0.3 * hspace.max())

# 提取直线参数
vertical_lines = []
for _, angle, d in zip(*vertical_peaks):
    x0 = d * np.cos(angle)
    y0 = d * np.sin(angle)
    vertical_lines.append((x0, y0))

# 可视化结果
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(smoothed_image, cmap='gray')
axes[0].set_title('平滑后图像')
axes[1].imshow(edges, cmap='gray')
axes[1].set_title('Canny边缘检测')
axes[1].axis('off')
axes[2].imshow(gray_image, cmap='gray')
for x, y in vertical_lines:
    axes[2].axvline(x=x, color='red', linewidth=2)
axes[2].set_xlim((0, image.shape[1]))
axes[2].set_ylim((image.shape[0], 0))
axes[2].set_title('检测到的垂直边缘')
axes[2].axis('off')
plt.tight_layout()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 02:14:56