Using Opencv to Overlay Transparent Image Onto Another Image

overlay image on another image with opencv and numpy

Here is one way to do that in Python/Opencv.

  • Read the transparent foreground image
  • Read the background image
  • Extract the alpha channel from the foreground image
  • Extract the BGR channels from the foreground image
  • Composite them together using np.where conditional
  • Save the result

Front:

Sample Image

Back:

Sample Image

import cv2
import numpy as np

# read foreground image
img = cv2.imread('front.png', cv2.IMREAD_UNCHANGED)

# read background image
back = cv2.imread('back.png')

# extract alpha channel from foreground image as mask and make 3 channels
alpha = img[:,:,3]
alpha = cv2.merge([alpha,alpha,alpha])

# extract bgr channels from foreground image
front = img[:,:,0:3]

# blend the two images using the alpha channel as controlling mask
result = np.where(alpha==(0,0,0), back, front)

# save result
cv2.imwrite("front_back.png", result)

# show result
cv2.imshow("RESULT", result)
cv2.waitKey(0)

Result:

Sample Image

Overlaying an image over another image both with transparent background using opencv

This is giving me desired solution but would prefer a better one if possible

    s_img = cv2.imread("obama2.png", -1)
l_img = cv2.imread('obama.png',-1)
for i in range(0,s_img.shape[0]):
for j in range(0,s_img.shape[1]):
if s_img[i][j][3]!=0:
l_img[i+y_offset][j+x_offset][0:3] = s_img[i][j][0:3]
l_img[i+y_offset][j+x_offset][3] = 255

cv2.imwrite('final2.png',l_img)

Edit: Looks like i missed something basic. I have to consider alpha channel while looping since the background image has transparency as well.

s_img = cv2.imread("obama2.png", -1)
l_img = cv2.imread('obama.png',-1)
x_offset = 162
y_offset = 69

y1, y2 = y_offset, y_offset + s_img.shape[0]
x1, x2 = x_offset, x_offset + s_img.shape[1]

alpha_s = s_img[:, :, 3] / 255.0
alpha_l = 1.0 - alpha_s

for c in range(0, 4):
l_img[y1:y2, x1:x2, c] = (alpha_s * s_img[:, :, c] +
alpha_l * l_img[y1:y2, x1:x2, c])
cv2.imwrite('final.png',l_img)

Overlay smaller image to larger image in Python

This is actually the correct output. Fully transparent images (like your template image) have the pixel value of 0 on empty areas which represents black. If you were to use semi-transparent templates (which have pixels value greater than 0 even if they are slightly transparent). You should see this:

Sample Image

Answer 2:

Your output images are 24bit. (Which means you get rid of thhe alpha channel before saving it). I looked into your code and saw the lines 34 and 35;

img_result = img[:, :, :3].copy()   
img_overlay = img_overlay_rgba[:, :, :3]

You're sending RGB images to overlay_image_alpha function. Change this to;

img_result = img.copy()
img_overlay = img_overlay_rgba

To preserve Alpha channel information.

New Output:

Sample Image

On Photoshop:

Sample Image



Related Topics



Leave a reply



Submit