Перспективное преобразование с помощью Python PIL с использованием координат src / target - PullRequest
0 голосов
/ 28 октября 2018

Я наткнулся на этот вопрос и пытаюсь выполнить преобразование перспективы с помощью Python Pillow.

Это именно то, что я пытаюсь сделать, и как выглядит результат:

enter image description here

И вот код, который я использовал, чтобы попробовать это:

from PIL import Image
import numpy

# function copy-pasted from https://stackoverflow.com/a/14178717/744230
def find_coeffs(pa, pb):
    matrix = []
    for p1, p2 in zip(pa, pb):
        matrix.append([p1[0], p1[1], 1, 0, 0, 0, -p2[0]*p1[0], -p2[0]*p1[1]])
        matrix.append([0, 0, 0, p1[0], p1[1], 1, -p2[1]*p1[0], -p2[1]*p1[1]])

    A = numpy.matrix(matrix, dtype=numpy.float)
    B = numpy.array(pb).reshape(8)

    res = numpy.dot(numpy.linalg.inv(A.T * A) * A.T, B)
    return numpy.array(res).reshape(8)

# test.png is a 256x256 white square
img = Image.open("./images/test.png")

coeffs = find_coeffs(
    [(0, 0), (256, 0), (256, 256), (0, 256)],
    [(15, 115), (140, 20), (140, 340), (15, 250)])

img.transform((300, 400), Image.PERSPECTIVE, coeffs,
              Image.BICUBIC).show()

Я не совсем уверен, как работает преобразование, нокажется, что точки движутся совершенно в противоположном направлении (например, мне нужно сделать (-15, 115), чтобы точка А переместилась вправо. Однако она также не будет двигаться на 15 пикселей, а на 5).

Как определить точные координаты целевых точек для правильного перекоса изображения?

1 Ответ

0 голосов
/ 01 ноября 2018

Ответ очень прост: просто поменяйте местами исходные и целевые координаты.Но это не ваша ошибка: автор связанного ответа особенно легко запутался, потому что target, source (в данном случае) является запутанным порядком для аргументов функции, потому что аргументы функции не имеют полезных имен, и потому что пример делаетобратное преобразование сдвига.

Вместо обмена исходными и целевыми координатами вы также можете поменять местами аргументы функции find_coeffs.Еще лучше, переименуйте их тоже, как

def find_coeffs(source_coords, target_coords):
    matrix = []
    for s, t in zip(source_coords, target_coords):
        matrix.append([t[0], t[1], 1, 0, 0, 0, -s[0]*t[0], -s[0]*t[1]])
        matrix.append([0, 0, 0, t[0], t[1], 1, -s[1]*t[0], -s[1]*t[1]])
    A = numpy.matrix(matrix, dtype=numpy.float)
    B = numpy.array(source_coords).reshape(8)
    res = numpy.dot(numpy.linalg.inv(A.T * A) * A.T, B)
    return numpy.array(res).reshape(8)

Оставив остальную часть вашего кода, только используя другое изображение, я получаю это преобразование:

Walter with red cornersWalter with red corners in perspective

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...