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

如何计算二值图中多分离轮廓白色区域的整体质心?

获取二值图像白色区域整体质心的正确方法

你的思路方向是对的,但拼接轮廓点来计算质心的方式其实有个关键问题——你只用到了轮廓的边缘像素,忽略了白色区域内部的所有像素,这样算出来的是边缘点的质心,不是整个白色区域的质心,结果会和真实区域质心有偏差,尤其是当白色区域内部面积较大时,偏差会更明显。

下面给你两种更可靠的解决方案:

方法一:直接对二值图像计算矩(推荐,最简单高效)

OpenCV的cv2.moments()函数可以直接接收单通道图像作为输入,此时它会计算所有非零像素(也就是你的白色区域)的矩,直接得到整个白色区域的质心,完全符合你的需求:

# 直接对二值图像计算矩
mmt = cv2.moments(binary_image)

# 计算质心坐标,注意先判断m00不为0(避免除以0错误)
if mmt['m00'] != 0:
    self.cx = int(mmt['m10'] / mmt['m00'])
    self.cy = int(mmt['m01'] / mmt['m00'])
else:
    # 处理图像中没有白色区域的特殊情况
    self.cx, self.cy = 0, 0

方法二:通过填充轮廓生成掩码后计算矩

如果你一定要基于轮廓操作,可以先创建一个空白掩码,把所有检测到的轮廓填充为白色,再对这个掩码计算矩,结果和方法一完全一致:

_, contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 创建和原图尺寸一致的空白掩码
mask = np.zeros_like(binary_image)
# 填充所有轮廓(参数-1表示填充所有轮廓,cv2.FILLED表示填充内部)
cv2.drawContours(mask, contours, -1, 255, thickness=cv2.FILLED)

# 对填充后的掩码计算矩
mmt = cv2.moments(mask)
if mmt['m00'] != 0:
    self.cx = int(mmt['m10'] / mmt['m00'])
    self.cy = int(mmt['m01'] / mmt['m00'])
else:
    self.cx, self.cy = 0, 0

总结一下,方法一不需要处理轮廓,一步到位就能得到准确的整体质心,是最优选择;你的原方法因为只考虑了边缘点,所以无法反映整个白色区域的质量分布,建议替换成上面的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:53:35