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 集成步骤
- 模型转换:PyTorch模型转ONNX,再转TensorRT。这一步最关键,直接影响推理速度。
- 编写推理节点:订阅/image_raw话题,跑推理,发布/objects话题。
- 配置参数:置信度阈值、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中的完整流程:
从图像输入到最终发布检测结果,整个流程环环相扣。任何一个环节出问题,都会影响最终效果。
我的建议:刚开始做联调时,先别追求精度。先把流程跑通,看到图像上有框了,再慢慢优化。我见过太多人一上来就调参,结果连图像都没订阅到。
好了,目标检测基础就聊到这儿。记住三个关键词:YOLO模型、TensorRT加速、可视化调试。把这三点吃透,Autoware感知联调就成功了一半。