How to merge two images base transparent python
Question:
I need to join two images where the base image has a transparent background, I already tried to do it using
image 01
image and a photo I need to put her in the second in the blank space
second image
expected result and this
import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
dim = (425, 425)
apple = mpimg.imread('image.png')
apple = cv2.resize(apple, dim)
banana = mpimg.imread('image2.png')
banana = cv2.resize(banana, dim)
_ = plt.imshow(apple)
_ = plt.show()
_ = plt.imshow(banana)
_ = plt.show()
list_images = [apple, banana]
def blend(list_images): # Blend images equally.
equal_fraction = 1.0 / (len(list_images))
output = np.zeros_like(list_images[0])
for img in list_images:
output = output + img * equal_fraction
output = output.astype(np.uint8)
_ = plt.imshow(output)
return output
output = blend(list_images)
_ = plt.imshow(output)
Answers:
You can easily make use of your alpha (transparent) channel for this purpose. Unfortunately, when I tried reading your frame image using cv2.IMREAD_UNCHANGED
, it didn’t have the appropriate alpha channel. According to your result, the region outside the rounded corners is in white.
So using your frame image I created the alpha channel and used it the following.
# Reading images
tr = cv2.imread('frame.png')
la = cv2.imread('sunset.jpg')
# resizing
dim = (425, 425)
tr = cv2.resize(tr, dim)
la = cv2.resize(la, dim)
# Finding the largest contour (white region) from the first channel in frame
th = cv2.threshold(tr[:,:,0],127,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
contours, hierarchy = cv2.findContours(th, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
c = max(contours, key = cv2.contourArea)
# Draw the largest contour onto a mask
black = np.zeros((tr.shape[0], tr.shape[1]), np.uint8)
mask = cv2.drawContours(black,[c],0,255, -1)
Mask image: we want the sunset image to be present in the white region
# Create 3-channel mask of float datatype
alpha = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)/255.0
# Perform blending and limit pixel values to 0-255
blended = cv2.convertScaleAbs(tr*(1-alpha) + la*alpha)
I need to join two images where the base image has a transparent background, I already tried to do it using
image 01
image and a photo I need to put her in the second in the blank space
second image
expected result and this
import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
dim = (425, 425)
apple = mpimg.imread('image.png')
apple = cv2.resize(apple, dim)
banana = mpimg.imread('image2.png')
banana = cv2.resize(banana, dim)
_ = plt.imshow(apple)
_ = plt.show()
_ = plt.imshow(banana)
_ = plt.show()
list_images = [apple, banana]
def blend(list_images): # Blend images equally.
equal_fraction = 1.0 / (len(list_images))
output = np.zeros_like(list_images[0])
for img in list_images:
output = output + img * equal_fraction
output = output.astype(np.uint8)
_ = plt.imshow(output)
return output
output = blend(list_images)
_ = plt.imshow(output)
You can easily make use of your alpha (transparent) channel for this purpose. Unfortunately, when I tried reading your frame image using cv2.IMREAD_UNCHANGED
, it didn’t have the appropriate alpha channel. According to your result, the region outside the rounded corners is in white.
So using your frame image I created the alpha channel and used it the following.
# Reading images
tr = cv2.imread('frame.png')
la = cv2.imread('sunset.jpg')
# resizing
dim = (425, 425)
tr = cv2.resize(tr, dim)
la = cv2.resize(la, dim)
# Finding the largest contour (white region) from the first channel in frame
th = cv2.threshold(tr[:,:,0],127,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
contours, hierarchy = cv2.findContours(th, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
c = max(contours, key = cv2.contourArea)
# Draw the largest contour onto a mask
black = np.zeros((tr.shape[0], tr.shape[1]), np.uint8)
mask = cv2.drawContours(black,[c],0,255, -1)
Mask image: we want the sunset image to be present in the white region
# Create 3-channel mask of float datatype
alpha = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)/255.0
# Perform blending and limit pixel values to 0-255
blended = cv2.convertScaleAbs(tr*(1-alpha) + la*alpha)