如何在网络摄像头源上叠加 png?

How to overlay a png on a webcam feed?

我有一个形状为 (480,640,4) 的 png 图像和一个形状为 (480,640,3) 的网络摄像头框架。我想将 png 完全覆盖在网络摄像头源上,但出现以下错误:

added_image = cv2.addWeighted(frame,0.4,png,0.1,0)

错误:

cv2.error: OpenCV(4.2.0) /io/opencv/modules/core/src/arithm.cpp:669: error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'arithm_op'

是频道不同的问题。有人可以帮我解决这个问题吗? 提前致谢!

这是因为您的图像具有不同数量的通道(一个是 4 通道,另一个是 3 通道)。如果您查看有关 addWeighted() 的文档。它说第一个源图像(src1)和第二个源图像(src2):

src1: first input array.

src2: second input array of the same size and channel number as src1.

这是因为图片的尺寸不一样。您必须将 PNG 图像从 BGRA 转换为 BGR。那么错误应该就没有了。

png = cv2.cvtColor(png, cv2.COLOR_BGRA2BGR)
added_image = cv2.addWeighted(frame,0.4,png,0.1,0)

如果您使用 addWeighted(),您将在背景图像的任何位置获得相同的叠加图像常数部分。这似乎不太可能是您想要的,因为您的输入图像有 4 个通道,其中一个可能是 alpha 通道。所以通常您会期望背景图像根据 alpha 通道显示不同。

以此为背景(摄像头)图片,形状为(500,300,3):

这是具有透明度和形状 (500,300,4) 的叠加图像:

import cv2
import numpy as np

# Read background and overlay images
bg = cv2.imread('buckinghampalace.jpg')
ol = cv2.imread('overlay.png', cv2.IMREAD_UNCHANGED) 

# Make a result image that is either the background image or the overlay image depending on the alpha channel being < 128
res = np.where((ol[...,3]<128)[...,None], bg, ol[...,0:3])

cv2.imwrite('result.jpg', res)