Python - 查找图像中对象的中心

2024-05-06

我有一个具有白色背景和非白色对象的图像文件。 我想使用 python (Pillow) 找到对象的中心。

我在 C++ 中发现了类似的问题,但没有可接受的答案 -如何找到物体的中心? https://stackoverflow.com/questions/12394153/how-can-i-find-center-of-object

类似的问题,但答案中的链接已损坏 -找到不规则多边形的中心的最快方法是什么? (答案中的链接已损坏) https://stackoverflow.com/questions/1203135/what-is-the-fastest-way-to-find-the-center-of-an-irregularly-shaped-polygon

我也读过此页,但它没有给我一个有用的食谱 -https://en.wikipedia.org/wiki/Smallest-circle_problem https://en.wikipedia.org/wiki/Smallest-circle_problem

Here's an example image: Moon

编辑: 我当前使用的解决方案是这样的:

def find_center(image_file):
    img = Image.open(image_file)
    img_mtx = img.load()
    top = bottom = 0
    first_row = True
    # First we find the top and bottom border of the object
    for row in range(img.size[0]):
        for col in range(img.size[1]):
            if img_mtx[row, col][0:3] != (255, 255, 255):
                bottom = row
                if first_row:
                    top = row
                    first_row = False
    middle_row = (top + bottom) / 2  # Calculate the middle row of the object

    left = right = 0
    first_col = True
    # Scan through the middle row and find the left and right border
    for col in range(img.size[1]):
        if img_mtx[middle_row, col][0:3] != (255, 255, 255):
            left = col
            if first_col:
                right = col
                first_col = False
    middle_col = (left + right) / 2  # Calculate the middle col of the object

    return (middle_row, middle_col)

如果将中心定义为质量中心 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python - 查找图像中对象的中心 的相关文章

随机推荐