Search code examples
pythonopencvtransparency

Problems with OpenCV warpPerspective with transparent images


I'm trying to change the perspective of a fake glasses image with OpenCV, but the transparent parts and opacity get lost. Resulting image has no transparencies. I want to change the perspective in order to stamp the resulting image over another image.

Can I do this with OpenCV?

#!/usr/bin/python
import numpy as np
import cv2

glasses = cv2.imread('fake_glasses.png')

RES_SIZE = (500,640)

pts1 = np.float32([[  0,  0], [599,  0],
                   [  0,208], [599,208]])
pts2 = np.float32([[ 94,231], [354,181],
                   [115,316], [375,281]])

M = cv2.getPerspectiveTransform(pts1,pts2)

rotated = cv2.warpPerspective(glasses, M, RES_SIZE)
cv2.imwrite("rotated_glasses.png", rotated)

fake_glasses.png (with transparent parts

mask.png


Solution

  • You are loading the image incorrectly, dropping the transparency layer. This is easy to verify -- print the shape of the image after you load it.

    >>> img1 = cv2.imread('fake_glasses.png')
    >>> print(img1.shape)
    (209, 600, 3)
    

    When not specified, the flags parameter of imread is set to IMREAD_COLOR. According to the documentation this means

    If set, always convert image to the 3 channel BGR color image.

    Instead, you should use IMREAD_UNCHANGED

    If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).

    With this change, the image loads correctly, including the alpha plane.

    >>> img2 = cv2.imread('fake_glasses.png', cv2.IMREAD_UNCHANGED)
    >>> print(img2.shape)
    (209, 600, 4)