Python - Найти центр объекта на изображении

У меня есть файл изображения, который имеет белый фон с небелым объектом. Я хочу найти центр объекта, используя python (Pillow).

Я нашел похожий вопрос в C ++, но нет приемлемого ответа -Как я могу найти центр объекта?

Аналогичный вопрос, но с неработающими ссылками в ответе -Какой самый быстрый способ найти центр многоугольника неправильной формы? (неработающие ссылки в ответе)

Я также читал эту страницу, но она не дает мне полезного рецепта -https://en.wikipedia.org/wiki/Smallest-circle_problem

Вот пример изображения:

Изменить: текущее решение, которое я использую, это:

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)
 Nir30 мая 2016 г., 09:27
@ user20160 К сожалению, упомянутый ответ снова сломал ссылки - нет пригодного кода

Ответы на вопрос(2)

Центр массыТогда это не сложно, хотя CoM может находиться за пределами вашей фигуры. Вы можете интерпретировать свое изображение как2D распределение, и вы можете найти егоожидаемое значение (CoM) с использованием интеграции (суммирование).

Если у вас есть NumPy это довольно просто. Сначала создайте пустой массив, содержащий 1, где ваше изображение не является белым, затем, чтобы сделать его распределением вероятностей, разделите его на общее число единиц.

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) это КОМ, который вы ищете.

Примечания:

Если у вас нет numpy, вы все равно можете это сделать. Это немного более утомительно, так как вы должны делать суммирования с помощью циклов / пониманий.Этот метод может быть легко расширен, если вы хотите назначить «массу» на основе цвета. Вы просто должны изменитьm[x, y] = immat[(x, y)] != (255, 255, 255) вm[x, y] = f(immat[(x, y)]) где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
 PaulDong07 апр. 2017 г., 08:53
действительно хорошее решение с чистым кодом. Могу ли я предложить добавить ссылку на интуицию за «Вы найдете предельные распределения, а затем рассчитываете ожидаемые значения, как если бы это было дискретное распределение вероятностей»? Я думаю, что это имеет смысл, но, возможно, не так доступно для людей, которые не знакомы с теорией вероятностей (что я считаю прекрасным).

с одной точкой треугольника в самых дальних «точках» на объекте, а затем найти центр этого треугольника.

Ваш ответ на вопрос