如果将中心定义为质量中心 https://en.wikipedia.org/wiki/Center_of_mass,那么这并不困难,尽管 CoM 可能超出您的形状。您可以将您的图像解释为二维分布 https://en.wikipedia.org/wiki/Joint_probability_distribution,你可以找到它的期望值 https://en.wikipedia.org/wiki/Expected_value#Finite_case(CoM) 使用积分(求和)。
如果你有 numpy 这很简单。首先创建一个包含 1 的 numpy 数组,其中图像是非白色的,然后将其除以总数,使其成为概率分布。
from PIL import Image
import numpy as np
im = Image.open('image.bmp')
immat = im.load()
(X, Y) = im.size
m = np.zeros((X, Y))
for x in range(X):
for y in range(Y):
m[x, y] = immat[(x, y)] != (255, 255, 255)
m = m / np.sum(np.sum(m))
从这时起,它就变成了基本的概率论。您找到边际分布,然后计算期望值,就好像它是离散概率分布一样。
# marginal distributions
dx = np.sum(m, 1)
dy = np.sum(m, 0)
# expected values
cx = np.sum(dx * np.arange(X))
cy = np.sum(dy * np.arange(Y))
(cx, cy)
是您正在寻找的 CoM。
Remarks:
- 如果你没有numpy,你仍然可以这样做。这只是有点乏味,因为你必须通过循环/推导式进行求和。
- 如果您想根据颜色分配“质量”,可以轻松扩展此方法。你只需要改变
m[x, y] = immat[(x, y)] != (255, 255, 255)
to m[x, y] = f(immat[(x, y)])
where f
是任意(非负值)函数。
- 如果你想避免双循环,你可以使用
np.asarray(im)
,但要小心索引
无循环:
m = np.sum(np.asarray(im), -1) < 255*3
m = m / np.sum(np.sum(m))
dx = np.sum(m, 0) # there is a 0 here instead of the 1
dy = np.sum(m, 1) # as np.asarray switches the axes, because
# in matrices the vertical axis is the main
# one, while in images the horizontal one is
# the first