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:
Back:
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:
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:
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:
On Photoshop:
Related Topics
Generate List of Quarters Betweeen Given Dates
How to Connect to a Remote Windows Machine to Execute Commands Using Python
Reading Columns of a Txt File on Python
Python How to Remove Escape Characters from a String
Plotting Data from Multiple Pandas Data Frames in One Plot
Retrieving Subfolders Names in S3 Bucket from Boto3
Finding Non-Numeric Rows in Dataframe in Pandas
Pandas - How to Compare 2 CSV Files and Output Changes
Calculate Monthly Returns from Daily Returns in Pandas(Cumpound)
Swapping Columns in a Numpy Array
How to Block Comment Code in the Ipython Notebook
Python Converting MySQL Query Result to Json
Python Opencv Cv2 - How to Increase the Brightness and Contrast of an Image by 100%
How to Delete Quotes from Data Read from .Csv File
Python - Ensuring a Variable Holds a Positive Number