如何使用OpenCV覆盖图像和文本/形状?

问题描述 投票:2回答:1

我遇到有关OpenCV透明覆盖的问题。到目前为止,这是我的代码:

import cv2

cap = cv2.VideoCapture('Sample_Vid.mp4')
stat_overlay = cv2.imread('overlay.png')
fps = 21

if cap.isOpened():
    while cap.isOpened():
        ret, frame = cap.read()
        overlay = frame.copy()
        output = frame.copy()

        cv2.rectangle(overlay, (0, 0), (730, 50), (0, 0, 0), -1)
        cv2.putText(overlay, fps, (1230, 20), cv2.FONT_HERSHEY_DUPLEX, 0.5, (255, 255, 255), 1)
        cv2.addWeighted(overlay, 1.0, output, 0, 0, output)

        cv2.imshow('frame', output)

所以我的框架上有一个矩形,上面显示了FPS。现在,我要先覆盖stat_overlay图像,然后再覆盖文本和形状,因为它们是动态的。在我阅读的所有说明中,都告诉我使用cv2.addWeighted(stat_overlay, 1.0, output, 0, 0, output)进行此操作,但是我已经有一个命令(如动态叠加层所使用的命令),如果在其上方插入第二个命令,则该命令将无效。任何想法如何解决这个问题?

感谢您提前回答!

python opencv overlay transparent cv2
1个回答
0
投票

您正在使用的命令:cv2.addWeighted(overlay, 1.0, output, 0, 0, output),使用alpha = 1.0beta = 0,因此没有透明性。您基本上是将overlay图像复制到output图像。 AddWeighted documentation:

cv2.addWeighted(src1,alpha,src2,beta,gamma [,dst [,dtype]])src1 –第一个输入数组。alpha-第一个数组元素的权重。src2 –第二个输入数组,其大小和通道号与src1相同。beta –第二个数组元素的权重。dst –输出数组,其大小和通道数与输入数组相同。

您还可以使用以下代码来覆盖文本:

AddWeighted


对于覆盖output = frame.copy() cv2.rectangle(output, (0, 0), (730, 50), (0, 0, 0), -1) cv2.putText(output, fps, (1230, 20), cv2.FONT_HERSHEY_DUPLEX, 0.5, (255, 255, 255), 1) ,您可以使用类似stat_overlay代码示例的解决方案。

我不知道Alpha blending是RGB还是RGBA格式。如果图像具有Alpha通道,则可以将其用作透明度平面。如果图像是RGB,则可以创建所需的Alpha平面。

[如果'overlay.png'是小图像(如徽标),则可能不需要这些,您可以将小图像“放置”在'overlay.png'图像上。


我创建了一个自包含的代码示例,该示例基于output示例。为了使代码独立,代码使用:

'overlay.png'


结果(最后一帧):import ffmpeg import cv2 import numpy as np in_filename = 'Sample_Vid.mp4' # Input file for testing (".264" or ".h264" is a convention for elementary h264 video stream file) ## Build synthetic video, for testing: ################################################ # ffmpeg -y -r 10 -f lavfi -i testsrc=size=192x108:rate=1 -c:v libx264 -crf 23 -t 50 test_vid.264 width, height = 640, 480 ( ffmpeg .input('testsrc=size={}x{}:rate=1'.format(width, height), f='lavfi') .output(in_filename, vcodec='libx264', crf=23, t=5) .overwrite_output() .run() ) ################################################ cap = cv2.VideoCapture('Sample_Vid.mp4') #stat_overlay = cv2.imread('overlay.png') # Create image with green circle, instead of reaing a file # The image is created as RGBA (the 4'th plane is the transparency). stat_overlay = np.zeros((height, width, 4), np.uint8) cv2.circle(stat_overlay, (320, 240), 80, (0, 0, 255, 255), thickness=20) # Draw red circle (with alpha = 255) # https://www.learnopencv.com/alpha-blending-using-opencv-cpp-python/ stat_alpha = stat_overlay[:, :, 3] # Take 4'th plane as alpha channel stat_alpha = cv2.cvtColor(stat_alpha, cv2.COLOR_GRAY2BGR) # Duplicate alpha channel 3 times (to match output dimensions) # https://www.learnopencv.com/alpha-blending-using-opencv-cpp-python/ # Normalize the alpha mask to keep intensity between 0 and 1 stat_alpha = stat_alpha.astype(float) / 255 stat_overlay = stat_overlay[:, :, 0:3] # Get RGB channels fps = 21 if cap.isOpened(): while cap.isOpened(): ret, frame = cap.read() if ret: output = frame.copy() # https://www.learnopencv.com/alpha-blending-using-opencv-cpp-python/ # Alpha blending: foreground = stat_overlay.astype(float) background = output.astype(float) # Multiply the foreground with the alpha matte foreground = cv2.multiply(stat_alpha, foreground) # Multiply the background with ( 1 - alpha ) background = cv2.multiply(1.0 - stat_alpha, background) # Add the masked foreground and background. output = cv2.add(foreground, background).astype(np.uint8) cv2.rectangle(output, (0, 0), (230, 50), (0, 0, 0), -1) cv2.putText(output, str(fps), (123, 20), cv2.FONT_HERSHEY_DUPLEX, 0.5, (255, 255, 255), 1) cv2.imshow('frame', output) cv2.waitKey(1000) else: break cv2.destroyAllWindows()
© www.soinside.com 2019 - 2024. All rights reserved.