如何合并或去除边缘图中霍夫变换检测出的重复线条?
解决霍夫变换检测重复线条问题
方案一:基于角度和距离的阈值手动去重
重复线条的核心特征是角度(theta)和距离(rho)的数值非常接近,可以通过设定合理阈值筛选出唯一线条:
- 设定角度差阈值(比如转成弧度后小于0.02弧度≈1.15度)和距离差阈值(比如小于10像素,根据图像尺寸调整)
- 遍历检测到的线条,只保留与已保留线条差异超过阈值的新线条
示例代码:
import numpy as np # 假设已得到angles2, distances2 filtered_angles = [] filtered_distances = [] # 设定阈值(根据实际情况调整) theta_threshold = 0.02 # 弧度,对应约1.15度 rho_threshold = 10 # 像素 for theta, rho in zip(angles2, distances2): # 检查是否与已保留的线条重复 is_duplicate = False for saved_theta, saved_rho in zip(filtered_angles, filtered_distances): if abs(theta - saved_theta) < theta_threshold and abs(rho - saved_rho) < rho_threshold: is_duplicate = True break if not is_duplicate: filtered_angles.append(theta) filtered_distances.append(rho) # 绘制去重后的线条 plt.imshow(img, "gray") x = np.linspace(0, img_sliced.shape[1], 50000) for i, (rho, theta) in enumerate(zip(filtered_distances, filtered_angles)): plt.plot(x, line(x, rho, theta), label=f'line :{i}') plt.xlim((0, img_sliced.shape[1])) plt.ylim((img_sliced.shape[0], 0)) plt.legend() plt.show()
方案二:用KMeans聚类自动合并相似线条
你提到的KMeans完全适用,把角度和距离作为特征维度,聚类后每个簇取中心值作为代表线条,自动合并重复项:
from sklearn.cluster import KMeans # 将角度和距离组合成特征矩阵 features = np.column_stack((angles2, distances2)) # 设定聚类数(可以先预估,比如你原本要13条,实际可能更少,也可以用肘部法则确定) k = 8 # 示例值,根据实际情况调整 kmeans = KMeans(n_clusters=k, random_state=42) kmeans.fit(features) # 获取每个簇的中心,作为去重后的线条参数 cluster_centers = kmeans.cluster_centers_ clustered_angles = cluster_centers[:, 0] clustered_distances = cluster_centers[:, 1] # 绘制聚类后的线条 plt.imshow(img, "gray") x = np.linspace(0, img_sliced.shape[1], 50000) for i, (rho, theta) in enumerate(zip(clustered_distances, clustered_angles)): plt.plot(x, line(x, rho, theta), label=f'line :{i}') plt.xlim((0, img_sliced.shape[1])) plt.ylim((img_sliced.shape[0], 0)) plt.legend() plt.show()
方案三:调整霍夫变换参数从源头减少重复
重复线条很多时候是因为边缘噪声或霍夫参数太宽松:
- 提高
hough_line_peaks的threshold值(比如从3调到10),只保留累积值更高的显著线条 - 适当减小
num_peaks,避免检测过多冗余线条 - 调整Canny边缘检测的高低阈值(比如
canny(img, 50, 150)),过滤掉细碎噪声边缘,减少霍夫变换的无效输入
内容的提问来源于stack exchange,提问作者Rastaw
相关产品推荐
相关产品推荐

