9

I am trying to make a transparent image and draw on it, and after I will addWeighted over the base image.

How can I initialize fully transparent image with width and hight in openCV python?

EDIT: I want to make a effect like in Photoshop, having stack of the layers, all stacked layers are initially transparent and drawing is performed on fully transparent layer. On the end I will merge all layers to get final image

Michael Presečan
  • 162
  • 1
  • 3
  • 12
  • 1
    This is very broad. Just use a new image (e.g. white), draw on it and somehow mark where you are drawing (not needed if you don't draw white as you can check for all pixels != white). Then all non-drawed weights are zero, when you combine these two images. (I'm not an opencv user and i made some assumptions about how addWeighted works). – sascha Jun 16 '17 at 17:49
  • 1
    OpenCV supports alpha channel but doesnt support rendering them. – Micka Jun 16 '17 at 18:54

3 Answers3

21

For creating a transparent image you need a 4 channel matrix, 3 of which would represent RGB colors and the 4th channel would represent Alpha channel, To create a transparent image, you can ignore the RGB values and directly set the alpha channel to be 0. In Python OpenCV uses numpy to manipulate matrices, so a transparent image can be created as

import numpy as np
import cv2

img_height, img_width = 300, 300
n_channels = 4
transparent_img = np.zeros((img_height, img_width, n_channels), dtype=np.uint8)

# Save the image for visualization
cv2.imwrite("./transparent_img.png", transparent_img)
ZdaR
  • 22,343
  • 7
  • 66
  • 87
  • Thank you, I have tried to draw something on the image you have proposed, but it doesnt work. Image is truly created but I cannot draw a simple rectangle on it. Operation is completed, but when image is saved, rectangle cannot be seen. – Michael Presečan Jun 18 '17 at 16:41
  • 4
    Actually it worked out when i added rectangle with 4 channels, with alpha 255 value... thank you – Michael Presečan Jun 19 '17 at 08:16
  • 2
    @MichaelPresečan could you edit the answer and add the rectangle so the example is broader. – titusfx Aug 05 '20 at 12:18
  • @MichaelPresečan Please edit the answer with your addition of the rectangle for others as well – KansaiRobot Jul 29 '21 at 11:03
13

If you want to draw on several "layers" and then stack the drawings together, then how about this:

import cv2
import numpy as np

#create 3 separate BGRA images as our "layers"
layer1 = np.zeros((500, 500, 4))
layer2 = np.zeros((500, 500, 4))
layer3 = np.zeros((500, 500, 4))

#draw a red circle on the first "layer",
#a green rectangle on the second "layer",
#a blue line on the third "layer"
red_color = (0, 0, 255, 255)
green_color = (0, 255, 0, 255)
blue_color = (255, 0, 0, 255)
cv2.circle(layer1, (255, 255), 100, red_color, 5)
cv2.rectangle(layer2, (175, 175), (335, 335), green_color, 5)
cv2.line(layer3, (170, 170), (340, 340), blue_color, 5)

res = layer1[:] #copy the first layer into the resulting image

#copy only the pixels we were drawing on from the 2nd and 3rd layers
#(if you don't do this, the black background will also be copied)
cnd = layer2[:, :, 3] > 0
res[cnd] = layer2[cnd]
cnd = layer3[:, :, 3] > 0
res[cnd] = layer3[cnd]

cv2.imwrite("out.png", res)

enter image description here

Headcrab
  • 6,838
  • 8
  • 40
  • 45
5

To convert an image's white parts to transparent:

import cv2
import numpy as np

img = cv2.imread("image.png", cv2.IMREAD_UNCHANGED)
img[np.where(np.all(img[..., :3] == 255, -1))] = 0
cv2.imwrite("transparent.png", img)
Red
  • 26,798
  • 7
  • 36
  • 58