Adding shadow to an image with alpha channels

I am trying to add a shadow effect dynamically to images with alpha channels.
Consider this image for example,

Right now, what I am trying to do is, separate the mask and the rgb channels. Then add a blur effect to the mask and adding the images back together using cv2.addWeighted
However, for that to work, I would need to add an offset to the mask before adding the images together. I am not sure how to do that.
My current code is following:

import cv2
import numpy as np

filename = "removed.png"

img = cv2.imread(filename, cv2.IMREAD_UNCHANGED)
alpha_channel = np.invert(img[:,:,3])
rgb_channels = img[:,:,:3]

cv2.imwrite("colorImg.jpeg", rgb_channels)
cv2.imwrite("invertedMask.jpeg", alpha_channel)

colorImg = cv2.imread("./colorImg.jpeg")
maskImg = cv2.imread("./invertedMask.jpeg")
maskImg = cv2.blur(maskImg, (10, 10))
# Add offset here somehow
masked = cv2.addWeighted(colorImg, 0.8, maskImg, 0.4, 0)
cv2.imshow("masked", masked)

I am pretty sure this approach is not that good, and I am open to suggestions for other approaches.

please post an example of what that should look like, and what your code currently does produce.

you need alpha compositing (overlay/transparency/…). opencv doesn’t yet have a function for that. you’d have to do your own multiplications… there are plenty of recipes around.

construct the “background” that is a constructed “shadow” of the foreground’s silhouette.

alpha-composite the foreground on the background.

1 Like