如何求解一组轮廓的质心?合并轮廓法精度问题求助
解决多轮廓组质心计算问题
错误原因分析
直接使用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
相关产品推荐
相关产品推荐

