使用OpenCV保存Deepstream管道提取帧为视频失效问题排查
问题根因
你生成9KB无效视频的核心原因是传入cv2.VideoWriter的帧为4通道BGRA格式,而你选用的XVID编码仅支持3通道BGR格式输入。cv2.imwrite原生支持带Alpha通道的BGRA图像,所以你导出单张PNG可以正常显示,但绝大多数常规视频编码(包括XVID)不支持透明通道,当VideoWriter接收到通道数不匹配的帧时,不会实际写入视频内容,最终仅生成包含文件头的空文件,大小通常在几KB级别。
修复步骤
- 修正帧通道数:在帧存入队列前,将4通道BGRA转为3通道BGR,添加转换代码:
frame_copy = cv2.cvtColor(frame_copy, cv2.COLOR_BGRA2BGR) - 校验分辨率匹配:VideoWriter初始化时传入的分辨率参数顺序是
(宽度, 高度),而NumPy数组的shape属性返回顺序是(高度, 宽度, 通道数),写入前可以打印frame.shape确认尺寸完全匹配,避免宽高写反导致写入失败。 - 增加编码器初始化校验:初始化VideoWriter后立刻调用
out.isOpened()判断是否创建成功,避免系统缺少对应编码库、路径无写入权限等问题导致的无效写入。
修正后参考代码
帧提取部分:
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) # 新增:转为3通道BGR适配视频编码 frame_copy = cv2.cvtColor(frame_copy, cv2.COLOR_BGRA2BGR) frame_buffer.put(frame_copy)
视频写入部分:
codec = cv2.VideoWriter_fourcc(*'XVID') out = cv2.VideoWriter('out.avi', codec, fps, (output_width, output_height)) # 校验编码器初始化状态 if not out.isOpened(): raise RuntimeError("视频写入对象初始化失败,请检查编码支持、输出路径权限") total_frames = FRAME_RECORDING_THRESH while total_frames > 0: frame = frame_buffer.get() # 兜底处理异常通道数 if frame.shape[-1] == 4: frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR) frame = cv2.resize(frame, (output_width, output_height), interpolation=cv2.INTER_LINEAR) out.write(frame) total_frames -= 1 out.release()
注:你原有写入逻辑中,在进入while循环前单独执行了一次
out.write(frame_copy),该帧不属于队列缓存的帧序列,容易出现帧内容、尺寸/通道不匹配的问题,修正后统一从队列取帧写入即可。
内容的提问来源于stack exchange,提问作者Giorgos Betsos
相关产品推荐
相关产品推荐

