7. 视觉检测与 ONNX 推理

本文描述 Autonomy 视觉感知基础设施 autonomy/common/network 的架构、API 与 YOLO 检测管线。


7.1 模块定位

common/network 提供与业务无关的深度学习推理框架,供 Perception 插件(如 YoloDetector)调用。命名空间:autonomy::common::network

network/
├── network.hpp              # 推荐入口
├── common/                  # Tensor, InferenceOptions
├── backend/                 # Backend, BackendFactory, Engine
│   ├── onnx/                # ONNX Runtime
│   └── tensorrt/            # TensorRT(可选)
├── pipeline/                # RunPipeline
└── detail/
    ├── preprocess/          # 图像 resize, normalize, layout
    └── postprocess/           # YOLO decode, NMS, 分类

7.2 推理流程

输入图像 (uint8/float)
    │
    ▼
预处理 (detail/preprocess/)
    ├─ Resize → 模型输入尺寸 (H×W)
    ├─ Normalize → [0,1] 或 ImageNet mean/std
    └─ Layout → NCHW / NHWC
    │
    ▼
Engine::Run(TensorMap)
    ├─ ONNX Runtime / TensorRT
    └─ 输出 TensorMap (float)
    │
    ▼
后处理 (detail/postprocess/)
    ├─ Decode → 网格预测 → 边界框
    ├─ NMS → 去重
    └─ Detection2D / BoundingBox2D

7.3 核心 API

7.3.1 创建引擎

#include "autonomy/common/network/network.hpp"

InferenceOptions opts;
opts.model_path = "models/yolov8n.onnx";
opts.onnx.execution_provider = "cpu";       // 或 "cuda"
opts.onnx.intra_op_num_threads = 4;

auto engine = BackendFactory::Create(opts);
if (!engine->Warmup()) {
    // 动态 shape 模型 Warmup 为 no-op
}

7.3.2 执行推理

FloatTensorMap inputs;
inputs["images"] = input_tensor;  // shape: [1, 3, H, W]

FloatTensorMap outputs;
auto status = engine->Run(inputs, &outputs);

7.3.3 一体化管线

Sample sample;
sample.image = cv_image;
sample.named_tensors = {};  // 可选:直接提供量化张量

auto result = RunPipeline(sample, opts);
// result.detections → BoundingBox2D 列表

7.4 预处理细节

步骤

文件

说明

Resize

detail/preprocess/resize.cpp

双线性插值至模型输入尺寸

Normalize

detail/preprocess/norm.cpp

(pixel - mean) / std

Layout

detail/preprocess/layout.cpp

HWC → CHW 转换

Dims

detail/preprocess/dims.cpp

解析输入 spatial size

GetSpatialSize:从模型 metadata 读取 \(H \times W\)


7.5 YOLO 后处理

7.5.1 网格解码

detail/postprocess/boxes.cpp 实现 grid-style YOLO head 解码:

\[ b_x = \sigma(t_x) + j, \quad b_y = \sigma(t_y) + i \]

详见 03_math.md §3.3

7.5.2 NMS

detail/postprocess/nms.cpp

  1. score 降序排列

  2. 贪心抑制 IoU \(> \tau_{nms}\) 的框

  3. 返回保留框索引

7.5.3 输出转换

解码结果映射到 commsgs::vision_msgs::BoundingBox2D

BoundingBox2D box;
box.center.position.x = cx;   // 像素
box.center.position.y = cy;
box.center.theta = 0.0;
box.size_x = width;
box.size_y = height;

7.6 ONNX Runtime 配置

字段

说明

默认

execution_provider

"" / "cpu" / "cuda"

CPU

device_id

CUDA 设备索引

0

use_io_binding

静态 shape 时跳过 output memcpy

false

intra_op_num_threads

算子内并行线程

0(ORT 默认)

graph_optimization_level

图优化级别 0–3

-1(默认)


7.7 线程安全与性能

约束

说明

线程安全

Engine 线程安全;每线程一个实例或外部 mutex

动态 shape

Warmup() 对非静态 shape 为 no-op

IoBinding

仅当所有输出 shape 完全静态时启用

INT8 量化

通过 Sample::named_tensors 直接提供校准张量


7.8 与 Perception 插件的集成(规划)

class YoloDetector : public PerceptionInterface {
    std::unique_ptr<network::Engine> engine_;

    void Process(const sensor_msgs::Image& img) override {
        Sample sample{ .image = ToCvMat(img) };
        auto result = RunPipeline(sample, opts_);
        detections_ = ToVisionMsgs(result);
    }
};

7.9 构建依赖

依赖

CMake 选项

说明

ONNX Runtime

USE_ONNX

默认推理后端

TensorRT

USE_TENSORRT

NVIDIA GPU 加速

OpenCV

默认

图像读写与 resize

源码列表见根 CMakeLists.txtNETWORK_CXX17_SRCS