Search code examples
pythonopencvpython-imaging-library

PIL vs OpenCV Affine Transform: why does the image turn upside down?


I'm trying to get rid of OpenCV in my image pipeline. I'm replacing it with PIL. I understand that the affine transformation in OpenCV is source -> destination, but the parameter for PIL is destination -> source. The transformation matrix used in OpenCV can be inverted to be used in PIL.

The problem I have is there's one image that I can successfully affine transform in OpenCV, but not PIL. The result I get from PIL is upside down and translated. I've tried inverting the OpenCV transformation matrix and applying it to the PIL ".transform()" method, but I get the same results. What am I doing wrong here?

...
warped = cv2.warpAffine(image, M, (width, height))
...
a_f = M[0, 0]
b_f = M[0, 1]
c_f = M[0, 2]
d_f = M[1, 0]
e_f = M[1, 1]
f_f = M[1, 2]

a_i, b_i, c_i, d_i, e_i, f_i = invert_affine(a_f, b_f, c_f, d_f, e_f, f_f)
warped = image.transform(
    ...
    (a_i, b_i, c_i, d_i, e_i, f_i),
    ...
)

I was asked for a reproducible example. I've put the image on a CDN. I have a script on GitHub. Bounding Box Bad Transform From PIL Affine Transform


Solution

  • This was a problem with the EXIF orientation tag.

    Fixed it with this:

    # Open the image using PIL
    image = Image.open(local_file)
    from PIL import ImageOps
    image = ImageOps.exif_transpose(image)
    

    ‘’’