使用 OpenCV 将从 Deepstream 管道中提取的帧保存到视频中
Save frames extracted from Deepstream pipeline to video using OpenCV
我正在尝试使用 OpenCV 将从 Deepstream 管道中提取的帧保存到视频中,但我最终得到的只是一个 9KB 的文件。
这是我的代码(在探测函数中执行):
batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
l_frame = batch_meta.frame_meta_list
frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
frame = pyds.get_nvds_buf_surface(hash(gst_buffer), frame_meta.batch_id)
frame_copy = np.array(frame, copy=True, order='C')
frame_copy = cv2.cvtColor(frame_copy, cv2.COLOR_RGBA2BGRA)
每次调用探测函数时都会执行以上代码。图像保存到队列中:
frame_buffer.put(frame_copy)
将所需数量的帧推入队列后,我使用以下代码将缓冲的帧保存到视频文件中:
codec = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('out.avi', codec, fps, (output_width, output_height))
out.write(frame_copy)
total_frames = FRAME_RECORDING_THRESH
while total_frames > 0:
frame = frame_buffer.get()
frame = cv2.resize(frame, (output_width, output_height), interpolation = cv2.INTER_LINEAR)
out.write(frame)
total_frames -= 1
out.release()
很遗憾,生成的文件不是有效的视频文件。在上述过程中我做错了吗?任何帮助将不胜感激。
P.S。只是为了测试帧是否已正确存储在队列中,如果我尝试将帧保存为 while 循环中的图像:
cv2.imwrite(dest_folder + '/' + f'tmp{total_frames}.png', frame)
我得到正确保存和有效的 png 图像。
P.S。 2 帧在缓冲时的分辨率为 output_width, output_height
。此外,尝试在保存之前执行 cv2.resize
不会改变任何内容。
我无法测试它,但常见的错误是人们认为而不是代码
out = cv2.VideoWriter('out.avi', codec, fps, (output_width, output_height))
会自动将帧调整为 (output_width, output_height)
大小,但事实并非如此。
您必须手动调整帧大小。
如果您不这样做,那么 Writer
将跳过帧,您会得到损坏的文件 - 没有帧。
while total_frames > 0:
frame = frame_buffer.get()
frame = cv2(frame, (output_width, output_height))
out.write(frame)
total_frames -= 1
编辑:
似乎问题可以用透明层制作图像 A
- RGBA
- 因为视频不使用 A
.
需要删除它。
您可以使用 cv2.COLOR_RGBA2BGR
而不是 cv2.COLOR_RGBA2BGRA
进行转换
frame_copy = cv2.cvtColor(frame_copy, cv2.COLOR_RGBA2BGR)
或者您可以删除 numpy.array
的最后一层
frame_copy = frame_copy[ : , : , :3 ]
我正在尝试使用 OpenCV 将从 Deepstream 管道中提取的帧保存到视频中,但我最终得到的只是一个 9KB 的文件。
这是我的代码(在探测函数中执行):
batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
l_frame = batch_meta.frame_meta_list
frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
frame = pyds.get_nvds_buf_surface(hash(gst_buffer), frame_meta.batch_id)
frame_copy = np.array(frame, copy=True, order='C')
frame_copy = cv2.cvtColor(frame_copy, cv2.COLOR_RGBA2BGRA)
每次调用探测函数时都会执行以上代码。图像保存到队列中:
frame_buffer.put(frame_copy)
将所需数量的帧推入队列后,我使用以下代码将缓冲的帧保存到视频文件中:
codec = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('out.avi', codec, fps, (output_width, output_height))
out.write(frame_copy)
total_frames = FRAME_RECORDING_THRESH
while total_frames > 0:
frame = frame_buffer.get()
frame = cv2.resize(frame, (output_width, output_height), interpolation = cv2.INTER_LINEAR)
out.write(frame)
total_frames -= 1
out.release()
很遗憾,生成的文件不是有效的视频文件。在上述过程中我做错了吗?任何帮助将不胜感激。
P.S。只是为了测试帧是否已正确存储在队列中,如果我尝试将帧保存为 while 循环中的图像:
cv2.imwrite(dest_folder + '/' + f'tmp{total_frames}.png', frame)
我得到正确保存和有效的 png 图像。
P.S。 2 帧在缓冲时的分辨率为 output_width, output_height
。此外,尝试在保存之前执行 cv2.resize
不会改变任何内容。
我无法测试它,但常见的错误是人们认为而不是代码
out = cv2.VideoWriter('out.avi', codec, fps, (output_width, output_height))
会自动将帧调整为 (output_width, output_height)
大小,但事实并非如此。
您必须手动调整帧大小。
如果您不这样做,那么 Writer
将跳过帧,您会得到损坏的文件 - 没有帧。
while total_frames > 0:
frame = frame_buffer.get()
frame = cv2(frame, (output_width, output_height))
out.write(frame)
total_frames -= 1
编辑:
似乎问题可以用透明层制作图像 A
- RGBA
- 因为视频不使用 A
.
需要删除它。
您可以使用 cv2.COLOR_RGBA2BGR
而不是 cv2.COLOR_RGBA2BGRA
frame_copy = cv2.cvtColor(frame_copy, cv2.COLOR_RGBA2BGR)
或者您可以删除 numpy.array
frame_copy = frame_copy[ : , : , :3 ]