Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perspective transform with Python PIL using src / target coordinates

I stumbled upon this question and am trying to perform perspective transformation with Python Pillow.

This is specifically what I am trying to do and what the result looks like:

enter image description here

And this is the code that I used to try it:

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()

I am not exactly sure how the transformation works, but it seems the points move quite into the opposite direction (e.g. I need to do (-15, 115) to make point A move to the right. However, it also won't move 15 pixels but 5).

How can I determine the exact coordinates of the target points to skew the image properly?

like image 767
Maxim Zubarev Avatar asked Oct 28 '18 13:10

Maxim Zubarev


People also ask

How to do a perspective transformation in Python?

Let’s now quickly analyze the python code to do a perspective transformation. First we need to load the image we want to transform. So let’s import the libraries and then we load the image. We then need to select 4 points, in order: top-left, top-right, bottom-left, bottom-right.

What is perspective transformation in image processing?

In Perspective Transformation, we can change the perspective of a given image or video for getting better insights into the required information. In Perspective Transformation, we need to provide the points on the image from which want to gather information by changing the perspective.

How do you change the perspective of an image?

In Perspective Transformation, we need to provide the points on the image from which want to gather information by changing the perspective. We also need to provide the points inside which we want to display our image. Then, we get the perspective transform from the two given sets of points and wrap it with the original image.

What is PiL image in Python?

Python PIL | Image.transform () method Last Updated : 02 Aug, 2019 PIL is the Python Imaging Library which provides the python interpreter with image editing capabilities. The Image module provides a class with the same name which is used to represent a PIL image.


1 Answers

The answer is very simple: just swap the source and target coordinates. But it's not your fault: the author of the linked answer made it particularly easy to get confused, because target, source is (in this case) a confusing order for function arguments, because function arguments have no helpful names, and because the example does the backward transformation of a shear.

Instead of swapping source and target coordinates, you can also swap the arguments of the find_coeffs function. Even better, rename them too, like

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)

Leaving the rest of your code the same, only using a different image, I get this transformation:

Walter with red corners    ⇒    Walter with red corners in perspective

like image 142
Walter Tross Avatar answered Oct 02 '22 16:10

Walter Tross