Igor
Igor

Reputation: 1

OpenCV - Working with pictures with a transparent background

I have a character. On a transparent background. I want to add glasses to him. This picture is also on a transparent background. If I use this code, then the picture is inserted with a black background. What is the solution? thanks

import cv2
from PIL import Image
from matplotlib import pyplot as plt


img = cv2.imread('pers.png')[...,::-1]
img2 = img.copy()

mask = cv2.imread('glasses.png')[...,::-1]
img2[2:(2+mask.shape[0]), 4:(4+mask.shape[1])] = mask


im = Image.fromarray(img2)
im.save("resume.png")

Upvotes: 0

Views: 2327

Answers (1)

fmw42
fmw42

Reputation: 53089

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

 - Read the first image (unchanged)
 - Read the second image (unchanged)
 - Extract the BGR and alpha channels from the first image 
 - Extract the BGR and alpha channels from the second image
 - Specify the offset for the second image onto the first image
 - Insert the BGR channels of the second image into a copy of the BGR channels of the first image
 - Insert the mask from the alpha channel of the second image into a black image the size of the first image
 - Combine the new mask with the alpha channel of the first image by multiplication (or using bitwise_and)
 - Blend the inserted version of the second image with the first image using the combined mask via Numpy where().
 - Save results

First Input:

enter image description here

Second Input:

enter image description here

import cv2
import numpy as np

# read background image
img = cv2.imread("obama_transparent.png", cv2.IMREAD_UNCHANGED)
ht, wd = img.shape[:2]

# read overlay image
img2 = cv2.imread("sunglasses.png", cv2.IMREAD_UNCHANGED)
ht2, wd2 = img2.shape[:2]

# extract alpha channel as mask and base bgr images
bgr = img[:,:,0:3]
mask = img[:,:,3]
bgr2 = img2[:,:,0:3]
mask2 = img2[:,:,3]

# insert bgr2 into bgr1 at desired location and insert mask2 into black image
x = 580
y = 390

bgr2_new = bgr.copy()
bgr2_new[y:y+ht2, x:x+wd2] = bgr2

mask_new = np.zeros((ht,wd), dtype=np.uint8)
mask_new[y:y+ht2, x:x+wd2] = mask2

# combine the two masks
# either multiply or use bitwise_and
mask_combined = cv2.multiply(mask,mask_new)
mask_combined = cv2.cvtColor(mask_combined, cv2.COLOR_GRAY2BGR)

# overlay the base bgr2_new image onto bgr using mask
result = np.where(mask_combined==255, bgr2_new, bgr)

# save results
cv2.imwrite('obama_transparent_glasses.jpg', result)

# display results
cv2.imshow('bgr', bgr)
cv2.imshow('mask', mask)
cv2.imshow('bgr2', bgr2)
cv2.imshow('mask2', mask2)
cv2.imshow('bgr2_new', bgr2_new)
cv2.imshow('mask_combined', mask_new)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Results:

enter image description here

Upvotes: 1

Related Questions