Ask Your Question

Revision history [back]

Alpha channel overlay back to RGB

I need to overlay a watermark on a video stream. I am using av for flicking through the frames, but opencv for the image processing. It's a the point where I want to hand a frame back to av that I get a problem.

Here is an annotated example of what I am trying to do, and where I am having problems

container = av.open('video.mp4')

for frame in container.decode(video=0): background = frame.to_ndarray(format="bgr24") (h, w) = background.shape[:2] background = np.dstack([background, np.ones((h, w), dtype="uint8") * 255])

overlay = np.zeros((h, w, 4), dtype="uint8")
y1 = watermark_top_margin
y2 = watermark_top_margin + watermark_height
x1 = w - watermark_width - watermark_right_margin
x2 = w - watermark_right_margin

overlay[y1:y2, x1: x2] = resized_watermark

# blend the two images together using transparent overlays
output = background.copy()
cv2.addWeighted(overlay, watermark_alpha, output, 1.0, 0, output)

# blend the two images together using transparent overlays
output = background.copy()
cv2.addWeighted(overlay, watermark_alpha, output, 1.0, 0, output)

#This is the problem right here vvvvvvvvvvvvvvvvvvvvvv
output = cv2.cvtColor(output,cv2.COLOR_RGBA2RGB)
#Here is the problem ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The colour conversion loses any work I have done in the alpha channel. So the frame looks exactly as it did before I overlay the image.

new_frame = av.video.VideoFrame.from_ndarray(output, format="bgr24")

So my question is this. How can I convert the image back to RGB format to create an av frame without losing the alpha channel information? This needs to be performat as it is happening in real time.

click to hide/show revision 2
None

updated 2019-10-08 06:58:18 -0600

berak gravatar image

Alpha channel overlay back to RGB

I need to overlay a watermark on a video stream. I am using av for flicking through the frames, but opencv for the image processing. It's a the point where I want to hand a frame back to av that I get a problem.

Here is an annotated example of what I am trying to do, and where I am having problems

container = av.open('video.mp4')

for frame in container.decode(video=0): background = frame.to_ndarray(format="bgr24") (h, w) = background.shape[:2] background = np.dstack([background, np.ones((h, w), dtype="uint8") * 255])

255])

    overlay = np.zeros((h, w, 4), dtype="uint8")
 y1 = watermark_top_margin
 y2 = watermark_top_margin + watermark_height
 x1 = w - watermark_width - watermark_right_margin
 x2 = w - watermark_right_margin

 overlay[y1:y2, x1: x2] = resized_watermark

 # blend the two images together using transparent overlays
 output = background.copy()
 cv2.addWeighted(overlay, watermark_alpha, output, 1.0, 0, output)

 # blend the two images together using transparent overlays
 output = background.copy()
 cv2.addWeighted(overlay, watermark_alpha, output, 1.0, 0, output)

 #This is the problem right here vvvvvvvvvvvvvvvvvvvvvv
 output = cv2.cvtColor(output,cv2.COLOR_RGBA2RGB)
 #Here is the problem ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The colour conversion loses any work I have done in the alpha channel. So the frame looks exactly as it did before I overlay the image. image.

 new_frame = av.video.VideoFrame.from_ndarray(output, format="bgr24")

So my question is this. How can I convert the image back to RGB format to create an av frame without losing the alpha channel information? This needs to be performat as it is happening in real time.