Python OpenCV - overlay an image with transparency

Dusan picture Dusan · Jan 6, 2017 · Viewed 9.9k times · Source

What I'm trying to achieve is to place an image with transparency on top of another one. Something like this:

enter image description here

I haven't been able to find any solution, so I decided to go pixel by pixel and calculate the resulting color. That one worked for me, but its very slow. I'm new to OpenCV and also to Python.

This is my code, I came up with:

import numpy as np
import cv2

img1 = cv2.imread("img1.png", -1)
img2 = cv2.imread("img2.png", -1) # this one has transparency
h, w, depth = img2.shape

result = np.zeros((h, w, 3), np.uint8)

for i in range(h):
    for j in range(w):
        color1 = img1[i, j]
        color2 = img2[i, j]
        alpha = color2[3] / 255.0
        new_color = [ (1 - alpha) * color1[0] + alpha * color2[0],
                      (1 - alpha) * color1[1] + alpha * color2[1],
                      (1 - alpha) * color1[2] + alpha * color2[2] ]
        result[i, j] = new_color

cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Is there another way of doing this? Some faster way, much faster? Thanks.

Answer

Josanghyeon picture Josanghyeon · Apr 10, 2018

Answer :

import numpy as np
import cv2

from time import time

img1 = cv2.imread("./test_image/rgb.jpg", -1)
img2 = cv2.imread("./test_image/rgba.png", -1) # this one has transparency
h, w, c = img2.shape

img1 = cv2.resize(img1, (w, h), interpolation = cv2.INTER_CUBIC)
result = np.zeros((h, w, 3), np.uint8)

#slow
st = time()
for i in range(h):
for j in range(w):
        color1 = img1[i, j]
        color2 = img2[i, j]
        alpha = color2[3] / 255.0
        new_color = [ (1 - alpha) * color1[0] + alpha * color2[0],
                      (1 - alpha) * color1[1] + alpha * color2[1],
                      (1 - alpha) * color1[2] + alpha * color2[2] ]
        result[i, j] = new_color
end = time() - st
print(end)

#fast
st = time()
alpha = img2[:, :, 3] / 255.0
result[:, :, 0] = (1. - alpha) * img1[:, :, 0] + alpha * img2[:, :, 0]
result[:, :, 1] = (1. - alpha) * img1[:, :, 1] + alpha * img2[:, :, 1]
result[:, :, 2] = (1. - alpha) * img1[:, :, 2] + alpha * img2[:, :, 2]
end = time() - st
print(end)

cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()