使用OpenCV保存从Deepstream管道提取的帧到视频



我试图用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()

不幸的是,生成的文件不是有效的视频文件。在以上过程中,我做错了什么吗?如有任何帮助,我将不胜感激。

注:只是为了测试帧是否被正确地存储在队列中,如果我试图将帧保存为while循环中的图像:

cv2.imwrite(dest_folder + '/' + f'tmp{total_frames}.png', frame)

我得到正确保存和有效的png图像。

注:帧在被缓冲时的分辨率为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 ]

最新更新