灰度图像质心(中心强度)计算错误,求正确实现方法
正确计算灰度图像质心的方法
原代码的问题
- 坐标维度混淆:图像是1024行(垂直方向,对应y坐标)、1280列(水平方向,对应x坐标),但原代码把行索引数组用于计算x方向质心,列索引数组用于计算y方向质心,完全搞反了维度对应关系。
- 加权逻辑错误:
np.dot(X, img)本质是用行索引对每列像素值加权求和,不符合x质心(按列索引加权)的计算逻辑,y方向的计算同理错误。
正确实现方案
质心的核心计算逻辑是:每个坐标位置的权重为对应像素的强度,最终质心是所有坐标的强度加权平均值。公式为:
- 水平方向(x)质心:
x_cm = Σ(x_i * I_i) / ΣI,其中x_i是列索引,I_i是第i列所有像素的强度和 - 垂直方向(y)质心:
y_cm = Σ(y_j * I_j) / ΣI,其中y_j是行索引,I_j是第j行所有像素的强度和
方法1:基于行/列求和的高效计算
import numpy as np # 假设img是(1024, 1280)的灰度图像数组 intensite_total = np.sum(img) # 计算x方向质心(列索引范围0~1279) x_coords = np.arange(1280) col_intensities = np.sum(img, axis=0) # 按列求和,得到1280个元素的数组 x_bary = np.sum(x_coords * col_intensities) / intensite_total # 计算y方向质心(行索引范围0~1023) y_coords = np.arange(1024) row_intensities = np.sum(img, axis=1) # 按行求和,得到1024个元素的数组 y_bary = np.sum(y_coords * row_intensities) / intensite_total print(f"质心坐标:x={x_bary:.1f}, y={y_bary:.1f}")
方法2:基于网格坐标的广播计算(逻辑更直观)
import numpy as np # 生成全图的x、y坐标网格(注意mgrid的顺序:先y后x) y_coords, x_coords = np.mgrid[0:1024, 0:1280] intensite_total = np.sum(img) x_bary = np.sum(x_coords * img) / intensite_total y_bary = np.sum(y_coords * img) / intensite_total print(f"质心坐标:x={x_bary:.1f}, y={y_bary:.1f}")
说明
- 两种方法本质等价:方法1通过行/列求和减少了计算量,适合大尺寸图像;方法2直接对每个像素的坐标按强度加权,逻辑更直观。
- 运行后应得到接近(520, 430)的结果,若仍有偏差,需检查图像是否存在其他高强度区域干扰,或确认坐标原点的定义是否与预期一致。
内容的提问来源于stack exchange,提问作者Camille
相关产品推荐
相关产品推荐

