Search code examples
pythonpython-3.ximageopencvpng

Problem about Background transparent .png format OpenCV with Python


I'm studying on OpenCV with Python. I tried to change a color of picture in PNG format, but I have got some problem with PNG background (The image has transparent background).

When I change it to grayscale, the background has changed to black -- my picture is not transparent anymore. What I desire is to keep the transparent background of picture.


Original image:

My code:

img = cv2.imread('line.png',cv2.IMREAD_UNCHANGED)
cv2.imshow('line',img)
cv2.waitKey()

Output image:

Desired output:

The white color around the border image should be transparent. How I can do this?


Solution

  • First, let me mention that if you display an image with alpha transparency using cv2.imshow then the transparent areas are going to be black.


    Since your input image already contains an alpha channel, the solution is simple -- just reuse the alpha channel.

    There's a slight problem -- even though PNG format allows to have grayscale with alpha channel, AFAIK there is no way to write such an image with OpenCV.

    Therefore the solution is straightforward: Take the processed grayscale image, convert it back to BGR, add the original alpha channel, and save the result.

    Since we're in Python, and therefore the image is represented as a numpy array, we can use array indexing to extract the channels we need. numpy.dstack allows us to add the alpha channel easily.


    Sample code:

    import cv2
    import numpy as np
    
    src = cv2.imread('51IgH.png', cv2.IMREAD_UNCHANGED)
    
    bgr = src[:,:,:3] # Channels 0..2
    gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
    
    # Some sort of processing...
    
    bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
    alpha = src[:,:,3] # Channel 3
    result = np.dstack([bgr, alpha]) # Add the alpha channel
    
    cv2.imwrite('51IgH_result.png', result)
    

    Result:

    Once more on different background, so you can see it's really transparent: