0
votes

I am trying to overlay a transparent PNG over a JPG image, I somehow cannot get it to work, what I tried:

import cv2
import numpy as np

a = cv2.imread("a.jpeg")
b = cv2.imread("b.png", cv2.IMREAD_UNCHANGED)

# add alpha channel to jpeg
(h, w) = a.shape[:2]
a = np.dstack([a, np.ones((h, w), dtype="uint8") * 0])

c = cv2.add(b,a)
cv2.imwrite("out.jpeg", c)

The following code will combine the two images, but the PNG transparency is not correct, it's somehow more opaque than it should be. ( I read this could be a issue with opencv ? not reading alpha correctly from png )

What I am trying to do is simply stack two image over another, a background JPG and put over a PNG that has some transparent zones, both images are the same size.

Thanks!

1
Could you provide the images you're using?rayryeng
You are just adding... which may give you wrong results.... (a pixel could result in white if it is a pixel (255, 0, 255) and (0,255,0) and I guess you want to preserve the colors) First, what do you want to do? have a semi transparent image over a background or a solid image over the background (where the transparency is 0)? Also, post an example image, and if possible what you want to achieveapi55
np.ones(...) * 0 – why do you not use np.zeros? And maybe this is the cause of the problem, where you mix up an alpha channel containing ones vs. zeros (transparent vs. opaque)?mkrieger1
@api55: I want to have a solid PNG overlay-ed over a JPG background, 0 transparency. I manage to achieve this result by using the ImageMagick convert, like: convert -composite background.jpg overlay.png result.jpgMihail

1 Answers

0
votes

I found a example on github I modified a bit, works as expected:

import numpy as np
import cv2

img = cv2.imread('1_calib.jpeg')
overlay_t = cv2.imread('ol.png',-1) # -1 loads with transparency

def overlay_transparent(bg_img, img_to_overlay_t):
    # Extract the alpha mask of the RGBA image, convert to RGB 
    b,g,r,a = cv2.split(img_to_overlay_t)
    overlay_color = cv2.merge((b,g,r))

    mask = cv2.medianBlur(a,5)

    # Black-out the area behind the logo in our original ROI
    img1_bg = cv2.bitwise_and(bg_img.copy(),bg_img.copy(),mask = cv2.bitwise_not(mask))

    # Mask out the logo from the logo image.
    img2_fg = cv2.bitwise_and(overlay_color,overlay_color,mask = mask)

    # Update the original image with our new ROI
    bg_img = cv2.add(img1_bg, img2_fg)

    return bg_img

cv2.imshow('image',overlay_transparent(img, overlay_t))
cv2.waitKey(0)