4、目标检测基础:基于深度学习的目标检测概述、YOLO系列在Autoware中的集成、检测结果可视化

好,咱们今天聊聊目标检测。这是Autoware感知模块里最核心的一环。说白了,就是让车“看见”路上有什么——行人、车辆、自行车,一个都不能漏。

我刚开始接触自动驾驶那会儿,觉得目标检测不就是个分类问题嘛。后来踩了坑才明白,它既要回答“这是什么”,还要回答“它在哪”。两个问题一起解决,难度直接翻倍。

4.1 基于深度学习的目标检测概述

传统方法靠手工特征,比如HOG+SVM。效果嘛,只能说凑合。直到深度学习杀进来,整个领域才真正起飞。

目前主流的目标检测框架分两大流派:

  • 两阶段检测器:比如Faster R-CNN。先提候选区域,再分类+回归。精度高,但慢。我早期做项目时用过,在嵌入式设备上根本跑不动。
  • 单阶段检测器:比如YOLO、SSD。一步到位,直接预测边界框和类别。快,但小目标容易漏。

你想想看,在自动驾驶场景里,车速60km/h,每帧处理时间必须控制在30ms以内。两阶段检测器基本没戏。所以YOLO系列成了行业标配。

核心知识点:目标检测 = 分类 + 定位。输出格式通常是 (x, y, w, h, class_id, confidence)。

4.2 YOLO系列在Autoware中的集成

YOLO发展到今天,已经出了v8、v9甚至v10。但在Autoware里,最常用的还是YOLOv5和YOLOv8。为什么?因为成熟、稳定、社区支持好。

我在项目中遇到过一个问题:直接用官方YOLO权重,在Autoware里推理结果很差。后来发现是输入尺寸和预处理方式不匹配。嗯,这里要注意——Autoware的image_proc节点输出的图像尺寸,和YOLO训练时用的尺寸可能不一样。

4.2.1 集成步骤

  1. 模型转换:PyTorch模型转ONNX,再转TensorRT。这一步最关键,直接影响推理速度。
  2. 编写推理节点:订阅/image_raw话题,跑推理,发布/objects话题。
  3. 配置参数:置信度阈值、NMS阈值、类别列表。

下面是一个简化的推理节点代码片段:

// 伪代码,实际用C++或Python
void DetectorNode::imageCallback(const Image::ConstPtr& msg) {
    // 1. 图像预处理:resize到640x640,归一化
    cv::Mat img = cv_bridge::toCvCopy(msg, "bgr8")->image;
    cv::Mat blob = blobFromImage(img, 1/255.0, Size(640,640));

    // 2. TensorRT推理
    float* output = engine->infer(blob);

    // 3. 后处理:解析输出,NMS去重
    vector<Detection> dets = postProcess(output, 0.5, 0.45);

    // 4. 发布Autoware格式的检测结果
    autoware_msgs::DetectedObjectsArray msg_out;
    for (auto& d : dets) {
        msg_out.objects.push_back(toAutowareObject(d));
    }
    pub_.publish(msg_out);
}

避坑指南:我曾经在TensorRT int8量化上栽过跟头。量化后模型小了,但小目标(比如远处的行人)直接消失。建议先用FP16,稳定后再尝试int8。

4.2.2 性能对比

模型 输入尺寸 推理时间 (RTX 3060) mAP (COCO) Autoware兼容性
YOLOv5s 640x640 12ms 37.2 高
YOLOv8s 640x640 14ms 44.9 高
YOLOv8n 640x640 8ms 37.3 高

我个人习惯用YOLOv8s。精度和速度的平衡点最好。如果你算力紧张,YOLOv8n也能用,但小目标会差一些。

4.3 检测结果可视化

光有检测结果还不够,你得能“看到”它。调试阶段,可视化是救命稻草。

Autoware里自带了一个可视化工具——rviz。但默认配置只显示3D bounding box。如果你想看2D检测框,得自己动手。

4.3.1 在图像上绘制检测框

我一般会在推理节点里直接画框,然后发布一个带标注的图像话题:

cv::Mat drawDetections(cv::Mat img, vector<Detection> dets) {
    for (auto& d : dets) {
        // 画矩形框
        cv::rectangle(img, d.bbox, cv::Scalar(0,255,0), 2);
        // 写标签和置信度
        string label = classes[d.class_id] + " " + 
                       to_string(d.confidence).substr(0,4);
        cv::putText(img, label, d.bbox.tl(), 
                    cv::FONT_HERSHEY_SIMPLEX, 0.5, 
                    cv::Scalar(0,255,0), 1);
    }
    return img;
}

然后发布为sensor_msgs::Image,在rviz里用Image显示。这样你就能实时看到检测效果了。

注意:可视化会消耗CPU资源。生产环境建议关闭,只在调试时开启。我曾经因为忘记关可视化,导致推理帧率从30fps掉到15fps。

4.3.2 在rviz中显示3D检测框

Autoware的检测结果最终要映射到3D空间。这需要相机-激光雷达联合标定。标定好了,2D检测框就能投影到3D点云上。

具体做法:

  • 用相机内参将2D框中心点反投影到相机坐标系
  • 用外参将相机坐标系转换到激光雷达坐标系
  • 在点云上绘制3D bounding box

这一步我建议用Autoware自带的calibration_publisher工具。手动标定太痛苦了,我当年标了一整天,结果偏差5个像素,3D投影直接歪了。

4.4 本章知识体系

下面这张图总结了目标检测在Autoware中的完整流程:

Autoware目标检测流程 图像输入 /image_raw 预处理 resize + 归一化 YOLO推理 TensorRT 后处理 NMS 可视化 (rviz + 图像) 发布 /objects 反馈:可视化用于调试

从图像输入到最终发布检测结果,整个流程环环相扣。任何一个环节出问题,都会影响最终效果。

我的建议:刚开始做联调时,先别追求精度。先把流程跑通,看到图像上有框了,再慢慢优化。我见过太多人一上来就调参,结果连图像都没订阅到。

好了,目标检测基础就聊到这儿。记住三个关键词:YOLO模型、TensorRT加速、可视化调试。把这三点吃透,Autoware感知联调就成功了一半。

可可精品资料库