CPU-GPU预处理流程的核心和优化关键 格式流转
重点:预处理流程的核心和优化关键 &格式流转
AVFrame (YUV) -> CPU Mat (BGR, HWC) -> GpuMat (BGR, HWC) [ (Kernel 1: BGR->RGB) -> (Kernel 2: HWC->CHW) ]-> TensorRT 推理。
2. GPU处理流程详解
项目的理想数据流如下,旨在最小化CPU-GPU数据拷贝,实现高效处理:
- CPU 解码:
FFmpeg
在CPU上解码视频文件,输出AVFrame
。 - 数据上传 (CPU -> GPU):
avframe_to_gpumat
函数将AVFrame
数据上传到GPU显存,创建cv::cuda::GpuMat
。YUV to BGR. - GPU 预处理:
preprocess_gpumat
函数在GPU上完成所有预处理,包括:-
- 尺寸调整 (隐式)(
cv::cuda::resize
)
- 尺寸调整 (隐式)(
- 颜色空间转换 (BGR -> RGB)
*归一化 (e.g., / 255.0) (GpuMat::convertTo
)
*数据布局转换 (HWC -> CHW)
-
- GPU 推理:
TensorRTEngine::infer
方法接收预处理后的GpuMat
,其指针直接送入TensorRT引擎。整个神经网络的计算全程在GPU上进行。 - GPU 输出: 推理结果(前景蒙版)直接生成在GPU显存中,并由一个
GpuMat
管理。
从第2步开始到第5步结束,数据始终保留在GPU上,形成了一个高效的 GPU内处理闭环。
4. 后续实施计划
为了使项目能够运行,计划采取以下步骤补全代码:
- 创建
VideoProcessor
类: 新建video_processor.h/.cpp
,封装整体处理逻辑,简化main
函数。 - 实现
ffmpeg_handler.cpp
: 完善视频帧的读取和解码功能。 - 实现
opencv_cuda_utils/gpu_utils.cpp
: 编码实现avframe_to_gpumat
和preprocess_gpumat
的具体逻辑。 - 实现
tensorrt_engine.cpp
: 完成TensorRT引擎的加载、配置及infer
方法的实现。 - 重构
main.cpp
: 使用VideoProcessor
类来驱动整个视频处理流程。
FFmpegHandler模块实现解码视频帧
@src/ffmpeg_handler/ffmpeg_handler.cpp中函数AVFrame* FFmpegHandler::readAVFrame()内部实现:输入本地视频文件,逐帧读取一个本地视频文件,输出解码后的视频帧 (AVFrame),请重新调整ffmpeg_handler.cpp与ffmpeg_handler.h
重点:预处理流程的核心和优化关键 &格式流转
AVFrame (YUV) -> CPU Mat (BGR, HWC) -> GpuMat (BGR, HWC) [ (Kernel 1: BGR->RGB) -> (Kernel 2: HWC->CHW) ]-> TensorRT 推理。
内核融合 (Kernel Fusion) (最高效)
这正是您在之前问题中提到的优化思路的延伸。我们可以编写一个全能的自定义CUDA Kernel,将多个操作合并为一次执行。
这个自定义Kernel将一次性完成:
- 尺寸调整 (隐式)
- 颜色空间转换 (BGR -> RGB)
- 归一化 (e.g., / 255.0)
- 数据布局转换 (HWC -> CHW)
执行流程:
- 上传: cv::Mat (CPU) -> cv::cuda::GpuMat (GPU, BGR, HWC),这一步不变。
- 调用全能的自定义Kernel: launch_preprocess_kernel(gpu_bgr_hwc, trt_input_buffer, model_input_size);
- 输入: 原始尺寸的GpuMat。
- 输出: 最终的、符合TensorRT要求的CHW浮点型数据指针。
- Kernel内部逻辑:
- CUDA线程根据它要写入的目标CHW缓冲区的(c, h, w)位置,反向计算出应该从源HWC GpuMat的哪个(x, y)坐标去采样。这个“反向计算”过程本身就包含了尺寸调整的逻辑(例如,通过简单的线性插值)。
- 从源GpuMat的(y, x)位置读取 B, G, R 三个值。
- 在写入目标缓冲区时,直接进行通道交换和归一化。例如,要写入R通道 (c=0),就读取源的B值,然后计算 (float)B / 255.0f,最后写入目标位置。
- 这样,仅用一次Kernel启动就完成了所有转换。