概述
qtimlvconverter 元素是 AI 管道中的关键组件,负责 AI 预处理——具体来说,就是为神经网络推理准备视频帧数据。它高效地处理 YUV 或 RGB 格式的输入缓冲区,并将其转换为与机器学习模型兼容的张量。
这一转换包含以下几项关键操作:
- 裁剪(Cropping):选择输入帧中的特定区域进行聚焦处理。该操作使用提供的 ROI 元数据来确定每一帧的裁剪区域。
- 缩放(Rescaling):调整输入帧的空间尺寸,使其与目标模型期望的张量尺寸匹配,以确保兼容性和一致的性能。
- 格式转换(Format Conversion):在支持的格式之间转换像素数据(例如从 YUV 到 RGB),以满足目标模型的输入要求。
- 批处理(Batching):将多个帧或图像聚合成批次,以优化推理吞吐量并利用并行处理能力。
- 归一化(Normalization):应用像素值缩放和归一化技术(如均值减法和标准差除法),对输入数据进行标准化以提升模型精度。
- 时间批处理(Temporal Batching):通过沿深度维度堆叠多个时间上连续的帧,生成形状为 NDHWC 的输入张量。这使其能够兼容需要跨帧时间上下文的基于视频的模型。
示例管道
1
下载所需文件
如果下载的任何文件是
.zip 压缩包,请在复制前先在主机上解压:
unzip filename.zip2
将文件复制到设备
3
连接到设备
4
设置环境变量
在设备上运行以下命令
5
运行管道
层级结构
GObjectGstObject
GstElement
GstBaseTransform
qtimlvconverter
Pad 模板
sink
src
元素属性
图像/视频张量特性
图像或视频张量具有若干关键特性,这些特性定义了机器学习管道中数据的表示和处理方式:-
NCHW(批次、通道、高度、宽度):
一个通道的所有像素连续存储。许多深度学习框架(如 PyTorch、Caffe)偏好这种格式,因为它可以优化 GPU 上的卷积运算。
以 RGB 为例:
- 首先是整幅图像的所有红色(Red)值
- 然后是所有绿色(Green)值
- 最后是所有蓝色(Blue)值
-
NHWC(批次、高度、宽度、通道)
通道按像素交错排列。在 TensorFlow 和 IM SDK 中很常见,因为它更符合某些硬件加速器的内存访问模式。
以 RGB 为例:
- 像素 1:R、G、B
- 像素 2:R、G、B
- 依此类推
-
NDHWC(批次、深度、高度、宽度、通道)
该格式在 NHWC 布局的基础上增加了深度(D)维度,使其适用于视频序列或体数据(例如用于动作识别的时间堆叠)。
帧按顺序存储,每一帧内的像素按 NHWC 顺序排列(每个像素的通道交错存储)。
例如:
- 帧 1:每个像素的 R、G、B
- 帧 2:每个像素的 R、G、B
- 依此类推。
- 0-255 - 原始 UINT8 图像数据的典型范围
- -128-127 - 原始 INT8 图像数据的典型范围
- 0.0-1.0 - FLOAT16 和 FLOAT32 张量常用的归一化浮点数据范围
- -1.0-1.0 - 部分期望中心化数据的模型使用,用户必须显式配置归一化参数(偏移和缩放)
- 根据模型的训练设置,也可能使用自定义范围
- RGB – 红、绿、蓝(大多数模型的标准格式)
- BGR – 蓝、绿、红(部分基于 OpenCV 的模型使用)
- Grayscale – 用于单色图像的单通道格式
图像放置方式对模型性能的影响
在使用计算机视觉模型时,我们通常关注图像的内容——但图像在输入张量中的放置位置同样会产生重大影响。默认情况下,它会保持原始宽高比,确保输出中物体的几何形状不失真。如果输入帧的宽高比与目标张量的宽高比不同,调整大小后的帧会被放置在左上角,其余区域填充为黑色背景。这种方法确保整个张量都被填充,保留原始图像内容的完整性,并避免裁剪或失真,非常适合需要一致空间表示的模型。
然而,某些模型在图像居中或拉伸以填满整个张量而不留填充区时表现更好。为支持此类用例,qtimlvconverter 提供了三种可配置的放置模式:
- top-left(默认)- 保持图像的原始宽高比,并将其放置在输出张量的左上角。
- centre - 同样保持宽高比,但将图像在张量中居中。这是期望主要目标位于中间的模型的常用选择。
- stretch - 忽略原始宽高比,将图像拉伸以完全填满张量。这可能引入失真,但确保完全覆盖,某些模型需要这种方式
- centre-crop - 忽略源图像的宽高比(AR,Aspect Ratio),必要时围绕中心裁剪源图像,使其完全适配输出张量。
如果需要裁剪怎么办?
在某些情况下,与其调整或重新定位整幅图像,你可能需要裁剪特定区域——例如输入图像的随机或目标部分——并只将该部分送入模型。当模型被训练为关注局部特征时,这种方法非常有用。虽然 image-disposition 有助于处理放置和宽高比,但裁剪是一个独立的预处理步骤,可以让你更精确地控制模型看到图像的哪个部分。
为实现这一点,你可以在 qtimlvconverter 之前插入一个 qtivtransform 步骤。它允许你在输入图像到达转换器之前执行必要的裁剪操作。这使你能够精确控制使用图像的哪个部分。
各组件的工作方式如下:
- source:这是你的输入流。
- qtivtransform:此阶段允许你对图像应用变换,例如裁剪、缩放或旋转。在此上下文中,你可以通过直接传递给 qtivtransform 的属性定义一个裁剪区域,从而在图像到达模型之前提取输入图像的特定部分。
- qtimlvconverter:裁剪之后,该组件为推理准备图像。它根据 image-disposition 属性(例如 top-left、centre、stretch)处理缩放、颜色转换、归一化和定位
- sink - 这是张量传递到的下一个元素
此示例展示了如何转换预定义区域。虽然 qtivtransform 支持运行时更新裁剪窗口,但这种方案并不总是可扩展的。
在更高级的用例中,qtimlvconverter 可以自行执行裁剪,而无需依赖 qtivtransform。例如,如果你有两个顺序工作的模型——检测模型后接姿态估计模型——qtimlvconverter 可以自动为第一阶段检测到的每个边界框裁剪并生成张量。
归一化
像素值的归一化会根据协商的张量数据类型自动执行。对于浮点张量类型 (FLOAT16、FLOAT32),像素值被归一化到 (0,1) 范围。对于有符号和无符号整数类型(如 INT8、UINT8、INT16、UINT16),归一化根据每种类型的完整取值范围进行——例如,INT8 归一化到 [−128 , 127],UINT8 归一化到 [0 , 255],INT16 归一化到 [−32,768 , 32,767]。 除了这种自动归一化外,插件还通过 mean 和 sigma 属性提供进一步的自定义功能,使用以下公式实现按通道归一化:批处理
批处理是 AI 推理管道中的一项关键优化技术,允许同时处理多个帧。这可以提高吞吐量,并支持在硬件加速器上并行执行。 在 qtimlvconverter 的上下文中,输入视频缓冲区可能来自:- 单个源(例如一个摄像头或视频文件),其中每个 GstBuffer 包含一个 GstMemory 块。
- 多路复用流(例如多个摄像头或视频文件),其中每个 GstBuffer 包含多个 GstMemory 块。此配置通过 qtibatch 插件启用,该插件将来自不同源的帧聚合成单个批处理缓冲区。
- 缓冲区中的每个 GstMemory 块代表一帧
- *qtimlvconverter 遍历所有内存块,并对每一帧分别应用预处理步骤(裁剪、缩放、格式转换、归一化)。
- 处理后的帧随后被打包成形状为 [N, H, W, C] 或 [N, C, H, W] 的单个张量,具体取决于所选布局。
- 批次大小 N 由缓冲区中内存块的数量推断得出。
- 并行推理:使模型能够同时处理多个帧,提高吞吐量并降低延迟。
- 高效的 GPU 利用:减少逐帧开销,最大化硬件加速能力。
- 灵活的输入处理:支持单流和多流场景,无需手动配置。
- NHWC: 交错布局(例如 [4, 480, 640, 3],批次大小为 4,RGB)。
- NCHW: 平面布局(例如 [4, 3, 480, 640]),常用于 CNN。
- NDHWC: 用于需要时间深度的模型(例如 [1, 4, 480, 640, 3]),其中 D 表示历史帧。
时间批处理
时间批处理扩展了标准批处理的概念,将同一流中随时间产生的多个帧分组到单个张量中。这种方法对于需要时间上下文的模型至关重要,例如:- 动作识别(例如跨连续帧检测手势或活动)。
- 目标跟踪(例如跨帧保持身份)。
- 处理序列而非单张图像的 3D CNN 或基于 RNN 的视觉模型。
- 时间批处理不是聚合来自不同源的帧,而是收集来自同一流的 D 个连续帧。
- 这些帧被打包成形状如下的张量:
- NDHWC:[N, D, H, W, C]
- N = 批次大小(同时处理的序列数量)
- D = 深度(每个序列的帧数)
- H、W = 空间维度
- C = 通道(例如 RGB)
- NDHWC:[N, D, H, W, C]
- qtimlvconverter 自动处理:
- 根据配置的深度(D)进行帧累积。
- 每帧的预处理(缩放、归一化、格式转换)。
- 按模型所需的正确布局组装张量。
- 保留时间连续性,使模型能够学习运动模式。
- 提高依赖帧间关系的任务的推理准确性。
- 通过并行处理序列充分利用 GPU 资源。
- 对于期望 4 帧序列的模型:
- 张量形状:[1, 4, 480, 640, 3](批次大小 = 1,深度 = 4,RGB)。
- 各帧分别进行归一化和缩放,然后按时间顺序堆叠。
基于 ROI 处理的多阶段推理管道
在高级 AI 管道中,推理通常分多个阶段执行——每个阶段由预处理、推理和后处理组成。这些阶段可以在完整图像上运行,也可以在由前面阶段识别的特定感兴趣区域(ROI)上运行。 为支持这一点,qtimlvconverter 可以处理包含多个 GstVideoRegionOfInterestMeta 条目的缓冲区。这些 ROI 通常由上游 ML 组件或自定义插件生成,代表输入帧中需要进一步分析的目标区域。 默认情况下,qtimlvconverter 处理整幅图像,忽略任何 ROI 元数据。但是,通过 mode 属性进行配置后,它可以切换到基于 ROI 的处理,从而仅对标记为需要进一步推理的区域进行选择性变换。 ROI 处理模式 mode 属性定义了输入区域在转换为张量之前的处理和批处理方式。主要分为两大类:- 图像批处理模式:
- image-batch-non-cumulative: 立即处理每个缓冲区,无论批次大小如何。
- image-batch-cumulative: 累积全帧输入,直到满足批次大小。
- ROI 批处理模式:
- roi-batch-non-cumulative: 立即处理 ROI 元数据,丢弃多余条目。
- roi-batch-cumulative: 累积 ROI 条目,直到满足批次大小。
- 非累积(Non-Cumulative): 在非累积子模式下,输入缓冲区在收到后立即处理,无论图像内存块或 ROI 元数据条目的数量是否满足模型指定的张量批次大小(N)。当多路复用流和/或 ROI 元数据的数量预计不会超过模型的批次大小(N)时,推荐使用此方式。超过批次大小(N)的任何 ROI 元数据或多路复用 GstMemory 块都将被丢弃。此子模式的一个潜在缺点是,如果批次未被完全填满——例如批次大小设置为 N=4 但只填充了三个位置——推理插件仍会处理整个批次,因未利用的位置导致资源效率降低。然而,非累积子模式的主要优势是消除了处理延迟:缓冲区不会为了积累额外输入以满足批次大小要求而被延后处理。这确保了及时处理和快速生成预测结果,使其适合对延迟要求极低的实时应用。
- 累积(Cumulative): 在累积子模式下,输入缓冲区会被聚合,直到 ROI 元数据条目和/或多路复用的 GstMemory 块的数量满足模型所需的张量批次大小(N)。如果收到 GAP 缓冲区,或在 ROI 批处理模式下输入缓冲区不包含 ROI 元数据,累积可能会提前中断。这种累积策略会给处理管道引入可变的延迟,受帧生成间隔以及每个缓冲区接收到的 ROI 或多路复用图像数量等因素影响。累积子模式的主要优势在于所有输入的 ROI 元数据和多路复用 GstMemory 块都会被处理,确保没有任何数据因批次大小限制而被丢弃。当模型的批次大小(N)大于 1 且推理处理时间足够短时,特别推荐使用此模式,以便高效利用资源并全面处理可用的输入区域。
累积:
预处理元数据
在某些情况下,后处理需要了解每个输入帧的预处理方式——例如它在输入张量中的位置、其尺寸,或批次中哪些帧是有效的。为支持这一点,qtimlvconverter 使用 GstProtectionMeta 将描述预处理详情的元数据附加到每个张量。推理插件随后将此元数据从其输入传播到输出,使后处理插件能够访问关于每一帧在预处理期间如何被处理的必要信息。 GstProtectionMeta 包含以下字段:- 输入张量维度:
- input-tensor-width [G_TYPE_UINT] - 指定帧被映射到的张量宽度(以像素为单位)。这是 qtimlvconverter 执行任何缩放操作后的最终宽度。
- input-tensor-height [G_TYPE_UINT] - 指定预处理后张量的高度(以像素为单位)。此值反映目标模型期望的输入尺寸。
- 输入张量中实际数据占据的区域:
- input-region-x [G_TYPE_INT] - 张量中放置实际图像数据的区域的 X 坐标(水平偏移)。在保持宽高比时,可用于确定填充或定位。
- input-region-y [G_TYPE_INT] - 张量中图像数据起始区域的 Y 坐标(垂直偏移)。
- input-region-width [G_TYPE_INT] - 张量内实际图像内容的宽度。如果应用了填充,该值可能与 input-tensor-width 不同。
- input-region-height [G_TYPE_INT] - 张量内实际图像内容的高度。指示张量中有多少被真实图像数据占据。
- 批次序列信息:
- sequence-index [G_TYPE_UINT] - 此条目在当前批次中的索引。例如,在大小为 4 的批次中,有效值为 0–3。
- sequence-num-entries [G_TYPE_UINT] - 批次中的条目总数。这有助于后处理插件理解批次上下文。
- 缓冲区的时间戳:
- timestamp [G_TYPE_UINT64] - 缓冲区被 qtimlvconverter 处理时的时间戳。用于同步和延迟测量。
- 生成此批次条目的流 ID:
- stream-id [G_TYPE_INT] [可选] - 标识生成此批次条目的源流。在多流管道中,可用于将推理结果与其来源关联起来。
- 生成此批次条目的流缓冲区的时间戳:
- stream-timestamp [G_TYPE_UINT64] [可选] - 帧在预处理前来自源流的原始时间戳。为跟踪或分析保留时间上下文。
- 生成此批次条目的 ROI 元数据的 ID:
- source-region-id [G_TYPE_INT] [可选] - 如果帧来源于某个 ROI,此字段包含定义裁剪区域的 GstVideoRegionOfInterestMeta 条目的 ID。使下游组件能够将推理结果关联回原始 ROI。
用法
单摄像头流 — 将张量保存到文件
单摄像头流,手动设置 UINT8 ML GstCaps,输出张量保存到单独的文件中。 常见数据类型:UINT8— 量化模型的典型类型,范围 0–255INT8— 用于有符号量化模型,范围 −128 到 127FLOAT16/FLOAT32— 用于需要高精度的模型,归一化到 0.0–1.0 或 −1.0–1.0(需要偏移和缩放)
1
连接到设备
2
设置环境变量
在设备上运行以下命令
3
运行管道
Run the pipeline
实时摄像头流上的两阶段人体检测与姿态估计
在实时摄像头流上运行两个 ML 阶段的演示管道。第一阶段执行人体检测,并将结果附加到每一帧。qtiobjtracker 随后跨帧关联检测到的人员,并添加持久的跟踪 ID。第二阶段使用基于 ROI 的预处理裁剪每个被跟踪的人员并运行姿态估计,生成叠加在显示器上的骨架关键点。
1
下载所需文件
如果下载的任何文件是
.zip 压缩包,请在复制前先在主机上解压:
unzip filename.zip2
将文件复制到设备
3
连接到设备
4
设置环境变量
在设备上运行以下命令
5
运行管道
Run the pipeline
使用合成器的四源批处理目标检测
对 4 个源进行批处理的演示管道。运行检测推理,并通过合成器将结果叠加到屏幕上。
1
下载所需文件
2
将文件复制到设备
3
连接到设备
4
设置环境变量
在设备上运行以下命令
5
运行管道
Run the pipeline

