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

如何求解一组轮廓的质心?合并轮廓法精度问题求助

解决多轮廓组质心计算问题

错误原因分析

直接使用np.concatenate(holes)合并轮廓点,得到的是无序的点集合,而非多个闭合区域的有效合并。cv2.moments处理这类点集时,会将其视为单一的非闭合轮廓计算矩,导致质心结果偏离预期。

正确解决方案

方法一:累加各轮廓的矩计算全局质心

图像矩具有可加性,多个区域的总矩等于每个区域矩的和。遍历所有孔洞轮廓,累加每个轮廓的矩分量,再用总矩计算全局质心:

total_m00 = 0
total_m10 = 0
total_m01 = 0

for cnt in holes:
    m = cv2.moments(cnt)
    # 跳过面积为0的无效轮廓
    if m["m00"] == 0:
        continue
    total_m00 += m["m00"]
    total_m10 += m["m10"]
    total_m01 += m["m01"]

# 计算全局质心
if total_m00 != 0:
    cX = int(total_m10 / total_m00)
    cY = int(total_m01 / total_m00)
else:
    cX, cY = 0, 0

方法二:加权平均各轮廓的质心

每个轮廓的质心可单独计算,全局质心为所有轮廓质心的面积加权平均(面积等价于均匀密度下的质量):

total_area = 0
sum_weighted_x = 0
sum_weighted_y = 0

for cnt in holes:
    m = cv2.moments(cnt)
    if m["m00"] == 0:
        continue
    area = m["m00"]
    # 单个轮廓的质心
    cnt_cx = m["m10"] / area
    cnt_cy = m["m01"] / area
    # 累加加权坐标
    sum_weighted_x += cnt_cx * area
    sum_weighted_y += cnt_cy * area
    total_area += area

if total_area != 0:
    global_cX = int(sum_weighted_x / total_area)
    global_cY = int(sum_weighted_y / total_area)
else:
    global_cX, global_cY = 0, 0

效果说明

两种方法均无需滤波或形态学操作,直接基于原始轮廓计算,能准确得到整个孔洞组的质心位置,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:17:13