OpenCV K-means算法分割围棋19×19交点问题求助
围棋棋盘交点K-means聚类失效的原因分析
问题背景
尝试用K-means算法对19×19围棋棋盘的交点进行聚类分割,但聚类中心杂乱分布,整体结果与预期偏差极大。
核心原因排查
特征逻辑与代码实现不一致
函数注释提到要基于单位圆上的角度坐标做K-means,但实际代码直接使用了交点的原始二维坐标。即便改用原始坐标,围棋交点是网格状分布,直接做二维K-means很难捕捉到行列的离散聚类模式。噪声点干扰与K值不匹配
如果输入的pts集合中混入了大量非交点的噪声(比如线条检测错误生成的伪交点、棋盘边缘杂点),固定设置k=361会强制将所有样本分为361类,真实交点会被打散,噪声点也会占用聚类中心,导致中心分布混乱。聚类参数设置不合理
- 终止条件
criteria的迭代次数(10次)太少、精度阈值(1.0)太宽松,算法可能未收敛就停止,中心位置无法对齐真实交点。 - 使用
cv.KMEANS_RANDOM_CENTERS随机初始化中心,对于网格状样本,极易陷入局部最优,无法收敛到规整的网格位置。
- 终止条件
样本预处理缺失
- 未对输入
pts做噪声过滤,无效样本干扰聚类效果。 - 未做坐标归一化:若图像宽高差异大,x、y坐标数值范围不同,K-means会偏向数值大的维度,导致聚类失衡。
- 未对输入
优化建议
- 拆分维度聚类:对x坐标和y坐标分别做一维K-means(各聚19类),再组合得到19×19的交点,比二维聚类更贴合棋盘网格特性。
- 样本预处理:先通过阈值筛选、形态学操作过滤噪声点;将坐标归一化到[0,1]范围,消除维度数值差异影响。
- 调整参数与初始化方式:
- 改用
cv.KMEANS_PP_CENTERS(K-means++)初始化中心,提升收敛稳定性; - 提高迭代次数至50-100次,降低精度阈值到0.1,确保算法收敛。
- 改用
- 验证输入样本:先可视化输入的
pts,确认有效交点占比,避免噪声过多干扰聚类。
原始代码
def segment_intersections_kmeans(pts, k=19**2, **kwargs): """Groups intersections based on position with k-means. Uses k-means on the coordinates of the angle on the unit circle to segment `k` angles inside `lines`. """ criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0) flags = kwargs.get('flags', cv.KMEANS_RANDOM_CENTERS) attempts = kwargs.get('attempts', 100) pts = np.float32(pts) # run kmeans on the coords labels, centers = cv.kmeans(pts, k, None, criteria, attempts, flags)[1:] print("Labels \n" , labels, "\n", len(labels)) labels = labels.reshape(-1) # transpose to row vec # segment lines based on their kmeans label segmented = defaultdict(list) for i, line in enumerate(pts): segmented[labels[i]].append(line) segmented = list(segmented.values()) return segmented
结果可视化描述
- 原始棋盘:标准19×19围棋棋盘
- 聚类中心:绿色标记的中心无规则分布,未对齐棋盘交点
- 全聚类结果:各类别样本分散,未形成规整的网格分组
内容的提问来源于stack exchange,提问作者M Millo
相关产品推荐
相关产品推荐

