如何使用 OpenCV 叠加图像 AND text/shapes?
How to use OpenCV to overlay an image AND text/shapes?
我 运行 遇到了关于 OpenCV 的 t运行sparent 覆盖的问题。到目前为止,这是我的代码:
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)
来执行此操作,但我已经有一个类似于动态叠加层使用的命令,如果我在它上面插入第二个命令,它就不起作用。有什么解决办法吗?
提前感谢您的回答!
您正在使用的命令:cv2.addWeighted(overlay, 1.0, output, 0, 0, output)
,使用alpha = 1.0
,和beta = 0
,所以没有透明度。
您基本上是在 将 overlay
图像复制到 output
图像中。
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
src1 – first input array.
alpha – weight of the first array elements.
src2 – second input array of the same size and channel number as src1.
beta – weight of the second array elements.
dst – output array that has the same size and number of channels as the input arrays.
您还可以使用以下代码叠加文本:
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 代码示例之类的解决方案。
不知道'overlay.png'
是RGB格式还是RGBA格式
如果图像有 alpha 通道,您可以将其用作透明平面。
如果图像是 RGB,您可以创建所需的 alpha 平面。
如果 'overlay.png'
是小图片(如徽标),您可能不需要任何这些,您可以 "place" output
图片上的小图片.
我创建了一个独立的代码示例,它基于 alpha blending 示例。
为了使代码自包含,代码使用:
- ffmpeg-python 用于生成合成视频(用于测试)。
- 代码,画红圈代替
'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()
结果(最后一帧):
我 运行 遇到了关于 OpenCV 的 t运行sparent 覆盖的问题。到目前为止,这是我的代码:
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)
来执行此操作,但我已经有一个类似于动态叠加层使用的命令,如果我在它上面插入第二个命令,它就不起作用。有什么解决办法吗?
提前感谢您的回答!
您正在使用的命令:cv2.addWeighted(overlay, 1.0, output, 0, 0, output)
,使用alpha = 1.0
,和beta = 0
,所以没有透明度。
您基本上是在 将 overlay
图像复制到 output
图像中。
cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
src1 – first input array.
alpha – weight of the first array elements.
src2 – second input array of the same size and channel number as src1.
beta – weight of the second array elements.
dst – output array that has the same size and number of channels as the input arrays.
您还可以使用以下代码叠加文本:
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 代码示例之类的解决方案。
不知道'overlay.png'
是RGB格式还是RGBA格式
如果图像有 alpha 通道,您可以将其用作透明平面。
如果图像是 RGB,您可以创建所需的 alpha 平面。
如果 'overlay.png'
是小图片(如徽标),您可能不需要任何这些,您可以 "place" output
图片上的小图片.
我创建了一个独立的代码示例,它基于 alpha blending 示例。
为了使代码自包含,代码使用:
- ffmpeg-python 用于生成合成视频(用于测试)。
- 代码,画红圈代替
'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()
结果(最后一帧):