You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中通过FFmpeg将硬件触发相机的YUV420 Mat数据编码为HEVC视频

问题:Python中通过pypylon获取Basler相机YUV420帧,用FFmpeg NVENC编码HEVC视频

Ubuntu 20.04环境下用Python开发,通过pypylon获取Basler硬件触发相机的帧数据,需要调用GPU NVENC,用FFmpeg将YUV420格式的Mat数据编码为HEVC视频,遇到实现瓶颈。

已尝试的操作

  • FFmpeg原生支持相机编码,但仅兼容网络摄像头,无法适配pypylon控制的Basler硬件触发相机
  • FFmpeg转码功能不符合需求
  • 尝试过JPEG序列编码,但先存帧再编码效率太低
  • 已成功将相机帧通过pypylon转为HEVC适配的YUV420格式
  • 了解到FFmpeg编码核心是AVFrame,推测需要将YUV420数据转为AVFrame再编码,但不清楚Python中具体实现方式

期望的简化代码逻辑

camera = pylon.InstantCamera(tlf.CreateFirstDevice())
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_YUV420
video_handle = xxxxxx  # HEVC编码句柄
while True:
    grabResult = camera.RetrieveResult(timeout, pylon.TimeoutHandling_ThrowException)
    image = converter.Convert(grabResult).GetArray()
    video_handle.write(frame)  # 通过FFmpeg NVENC编码为HEVC视频

解决方案

1. 依赖安装

确保安装必要库及带NVENC支持的FFmpeg:

pip install ffmpeg-python opencv-python pypylon
# Ubuntu下安装带NVENC的FFmpeg及NVIDIA编码库
sudo apt install ffmpeg libnvidia-encode-$(nvidia-smi | grep -oP 'Driver Version: \K[0-9]+')

2. 核心实现思路

通过ffmpeg-python库创建FFmpeg管道,直接将YUV420帧数据以字节流形式喂入NVENC编码器,跳过磁盘存储环节,保证编码效率。关键是要匹配相机输出的分辨率、帧率、像素格式与FFmpeg的输入参数。

3. 完整代码示例

import pylon
import numpy as np
import ffmpeg

# 初始化相机及触发配置
tlf = pylon.TlFactory.GetInstance()
camera = pylon.InstantCamera(tlf.CreateFirstDevice())
camera.Open()

# 配置硬件触发参数(根据相机型号调整)
camera.TriggerSelector.SetValue("FrameStart")
camera.TriggerMode.SetValue("On")
camera.TriggerSource.SetValue("Hardware")

# 初始化格式转换器
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_YUV420

# 获取相机基础参数
width = camera.Width.GetValue()
height = camera.Height.GetValue()
fps = camera.ResultingFrameRate.GetValue()

# 构建FFmpeg NVENC编码管道
output_filename = "output.hevc"
process = (
    ffmpeg
    .input('pipe:', format='rawvideo', pix_fmt='yuv420p', s=f'{width}x{height}', r=fps)
    .output(output_filename, vcodec='hevc_nvenc', pix_fmt='yuv420p', preset='fast')
    .overwrite_output()
    .run_async(pipe_stdin=True)
)

try:
    camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
    while camera.IsGrabbing():
        grabResult = camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
        if grabResult.GrabSucceeded():
            # 转换为YUV420格式的NumPy数组
            image = converter.Convert(grabResult).GetArray()
            # 将数组转为字节流写入FFmpeg管道
            process.stdin.write(image.tobytes())
        grabResult.Release()
finally:
    # 释放资源
    camera.StopGrabbing()
    camera.Close()
    process.stdin.close()
    process.wait()

4. 关键说明

  • FFmpeg参数解析:
    • format='rawvideo':指定输入为无压缩原始视频流
    • pix_fmt='yuv420p':与pypylon输出的像素格式完全匹配
    • vcodec='hevc_nvenc':强制使用NVIDIA硬件编码器
    • preset='fast':可根据需求调整,ultrafast速度最快,medium质量更高
  • 效率保障:直接通过内存字节流传递数据,无磁盘IO开销,适配实时编码需求
  • 资源管理:必须在finally块中释放相机资源并关闭FFmpeg进程,避免内存泄漏

内容的提问来源于stack exchange,提问作者QuantumRiver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 03:37:50