I have two images: the temple and the mask (the heart). I want to mask the temple with the shape of the heart and leave out the black background. The result should be a heart shaped cutout from the temple with a white or transparent background.
Asked
Active
Viewed 3,522 times
-2
-
This sounds like a job for https://graphicdesign.stackexchange.com/ – niamulbengali Dec 31 '20 at 17:14
-
3What have you tried so far? – Nouman Dec 31 '20 at 17:33
-
I'm just unsure how to go about it – sam Dec 31 '20 at 18:13
-
@sam shift the white heart to the left and multiply the two images, maybe you need to stack the binary image in x3 shape to be multiplied by colour image and normalize the heart by 255. – Bilal Dec 31 '20 at 18:42
-
I'm looking for a general method that coul work with any simple shape and image – sam Dec 31 '20 at 18:48
-
where is your code? What did you try? What did you find in Google? Do you know module `pillow` or `cv2` ? – furas Dec 31 '20 at 18:48
-
general method is to check first in Google, next write some code, and come to Stackoverflow when code gives error message. – furas Dec 31 '20 at 18:50
-
Yea I tried Cv2. I used this (below) thread to get me almost all the way but it seems some code is missing. https://stackoverflow.com/questions/62813546/how-do-i-crop-an-image-based-on-custom-mask-in-python/65523478?noredirect=1#comment115845665_65523478 – sam Dec 31 '20 at 18:51
-
[What's the most simple way to crop a circle thumbnail from an image?](https://stackoverflow.com/questions/58543750/whats-the-most-simple-way-to-crop-a-circle-thumbnail-from-an-image) it shows `pillow` and `putalpha(mask)` – furas Dec 31 '20 at 18:55
1 Answers
2
You can use pillow
and putalpha
to add grayscale image (L
) to RGB image as alpha
channel - so it will have transparent background. But both images have to be the same size.
from PIL import Image
# load images
img_org = Image.open('temple.jpg')
img_mask = Image.open('heart.jpg')
# convert images
#img_org = img_org.convert('RGB') # or 'RGBA'
img_mask = img_mask.convert('L') # grayscale
# the same size
img_org = img_org.resize((400,400))
img_mask = img_mask.resize((400,400))
# add alpha channel
img_org.putalpha(img_mask)
# save as png which keeps alpha channel
img_org.save('output-pillow.png')
BTW:
You can use other functions in pillow
to resize only mask and keep original proportions of heart.
Black color give full transparent, white color keep original color, but you can also gray colors to make pixel half-transparent.
EDIT:
The same with cv2
import cv2
# load images
img_org = cv2.imread('temple.jpg')
img_mask = cv2.imread('heart.jpg')
# convert colors
#img_org = cv2.cvtColor(img_org, ???)
img_mask = cv2.cvtColor(img_mask, cv2.COLOR_BGR2GRAY)
# the same size
img_org = cv2.resize(img_org, (400,400))
img_mask = cv2.resize(img_mask, (400,400))
# add alpha channel
b, g, r = cv2.split(img_org)
img_output = cv2.merge([b, g, r, img_mask], 4)
# write as png which keeps alpha channel
cv2.imwrite('output-cv2.png', img_output)
BTW: cv2
uses BGR
instead og RGB

furas
- 134,197
- 12
- 106
- 148