YOLOv11 车辆跟踪 ROS 功能包
基于 YOLOv11 + TensorRT 的高性能车辆检测与跟踪 ROS 节点,采用多线程流水线和 IoU 跟踪,实时输出可视化结果和 ROS 消息。
📘 概述
yolov11 功能包为 ROS 提供了基于 YOLOv11 的车辆检测与跟踪能力。它利用 TensorRT 对模型进行推理加速,通过多线程架构实现摄像头/视频流的高效处理,并集成了一个轻量级的基于 IoU 的跟踪器,可为每个车辆分配唯一 ID 并绘制运动轨迹。
系统实时发布带有绘制信息的图像话题 (/debug_image) 和可视化 Marker 话题 (/detected_objects),方便集成到更大的自动驾驶或监控系统中。
✨ 核心特性
🚀 TensorRT 加速
使用 FP16/INT8 优化,显著降低推理延迟,提高吞吐量。
🧵 三线程流水线
捕获、推理、显示分离,充分利用 CPU 和 GPU 资源。
🎯 实时 IoU 跟踪
基于 IoU 的轻量级跟踪,为车辆分配稳定 ID,绘制轨迹。
📊 性能监控
实时显示 FPS、处理耗时、跟踪数量等仪表盘。
📡 ROS 原生集成
发布可视化 Marker 和调试图像,易于集成和调试。
📸 多源输入
支持 USB 摄像头、CSI 摄像头、视频文件。
📁 功能包结构
yolov11/
├── CMakeLists.txt # 编译配置 (CUDA / TensorRT / OpenCV)
├── package.xml # 功能包清单
├── include/ # 头文件
│ ├── block.h # 网络模块构建 (C2f, SPPF, C2PSA...)
│ ├── calibrator.h # INT8 校准器
│ ├── config.h # 全局配置 (类别数, 阈值, 输入尺寸)
│ ├── cuda_utils.h # CUDA 错误检查宏
│ ├── logging.h # TensorRT 日志封装
│ ├── macros.h # 导出宏 & TRT 版本兼容
│ ├── model.h # 引擎构建接口 (det/seg/pose/obb)
│ ├── postprocess.h # 后处理函数 (NMS, 坐标映射)
│ ├── preprocess.h # CUDA 预处理 (warpaffine)
│ ├── track.h # 早期跟踪器定义
│ ├── tracker_enhanced.h # 增强跟踪器 (带关键点)
│ ├── types.h # Detection 结构体
│ ├── utils.h # 文件/图像工具
│ └── yololayer.h # YOLO 插件层
├── src/
│ ├── yolo11_car_ros_node.cpp # ROS 主节点 (跟踪版本)
│ ├── yolo11_car_tracking.cpp # (同上, 备份)
│ ├── block.cpp # 网络层实现
│ ├── calibrator.cpp # 校准器实现
│ ├── model.cpp # 引擎构建 (det/seg/pose/obb)
│ ├── postprocess.cpp # CPU 后处理 (get_rect, nms)
│ ├── postprocess.cu # CUDA 后处理 (decode, nms 核函数)
│ ├── preprocess.cu # CUDA warpaffine 预处理
│ └── tracker_enhanced.cpp # 增强跟踪器实现 (带关键点)
├── plugin/
│ ├── yololayer.cu # YOLO 插件 CUDA 实现 (CalDetection)
│ └── yololayer.h # 插件声明
└── launch/
├── yolo11_tracking.launch # 车辆跟踪启动文件
└── yolo_pose_tracking.launch # 姿态跟踪启动文件 (另一项目)
🔧 依赖项
ROS 依赖 (package.xml)
roscpp、sensor_msgs、std_msgstf2_ros、cv_bridge、image_transportvisualization_msgs(用于 MarkerArray)prometheus_msgs(可选, 用于无人机版本)
系统依赖
- OpenCV (≥ 4.2) — 图像处理
- Eigen3 — 线性代数
- CUDA (≥ 11.0) — GPU 计算
- TensorRT (≥ 8.6) — 推理引擎
- SpireCV (可选) — 用于部分视觉功能
libnvinfer.so 在链接路径中。CMake 中已包含 /usr/local/cuda 和自定义 TensorRT 路径变量。⚡ 快速开始
1. 编译功能包
cd ~/catkin_ws/src
git clone <your-repo>/yolov11.git
cd ~/catkin_ws
catkin_make -DCMAKE_BUILD_TYPE=Release
source devel/setup.bash
2. 准备 TensorRT 引擎文件
将训练好的 YOLOv11 模型(.wts)转换为 .engine 文件(可使用 model.cpp 中的构建函数)。假设引擎文件位于 /home/sutpc/car_ws/car.engine。
3. 运行节点
# 使用 launch 文件 (摄像头 ID 4, 分辨率 640x480)
roslaunch yolov11 yolo11_tracking.launch
# 或直接运行节点并传递参数
rosrun yolov11 yolo11_car_ros_node _camera_id:=0 _engine_file:=/path/to/your.engine _width:=640 _height:=480
启动后,将显示 OpenCV 窗口 "YOLOv11 Vehicle Tracking",并发布 ROS 话题。
🏗️ 系统架构
- Capture Thread: 从摄像头或视频读取帧,放入
ThreadSafeQueue<cv::Mat>。若队列满则丢弃帧(避免内存爆炸)。 - Inference Thread: 从队列取帧,执行 CUDA 预处理 → TensorRT 推理 → 后处理 (解码+NMS) → IoU 跟踪,生成
FrameData放入处理队列。 - Display Thread: 取处理后的帧,绘制跟踪框/ID/轨迹/仪表盘,发布 ROS 图像和 Marker 消息,并在窗口显示。
🎯 跟踪器 VehicleTracker
轻量级 IoU 跟踪器,维护内部轨迹列表,为每个检测框分配唯一 ID。
数据结构 Track
id— 唯一标识符bbox— 当前边界框 (浮点)age— 总存活帧数consecutive_invisible_count— 连续未匹配帧数trajectory— 历史中心点轨迹
核心算法
输入:当前帧检测框集合 + 置信度
步骤:
- 所有现存轨迹 age++、invisible_count++
- 对每个轨迹,与未匹配检测框计算 IoU,选择最大 IoU (>阈值) 作为匹配
- 匹配到的检测更新轨迹框、重置 invisible_count、更新轨迹点
- 未匹配的检测创建新轨迹
- 移除 invisible_count 超过 max_age 的轨迹
VehicleTrack (包含 ID、框、颜色、轨迹等)
🧵 多线程安全队列
使用自定义 ThreadSafeQueue<T> 实现线程间数据传递,内部使用 std::mutex 和 std::condition_variable。
template <typename T>
class ThreadSafeQueue {
void push(const T& value);
bool try_pop(T& value); // 非阻塞
int size() const;
bool empty() const;
};
捕获线程和生产线程之间通过 raw_frame_queue 传递 cv::Mat,推理线程和显示线程之间通过 processed_frame_queue 传递 FrameData。
📡 ROS 接口
发布话题
| 话题名 | 类型 | 描述 |
|---|---|---|
/detected_objects | visualization_msgs/MarkerArray | 包含每个车辆的 3D 框(投影到地面)、轨迹线和 ID 标签。 |
/debug_image | sensor_msgs/Image | 带有绘制信息(框、ID、轨迹、性能仪表盘)的图像。 |
参数 (私有命名空间 ~)
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| engine_file | string | /home/sutpc/car_ws/car.engine | TensorRT 引擎文件路径 |
| camera_id | int | 4 | 摄像头设备ID (如 /dev/video4) |
| width | int | 1280 | 图像宽度 |
| height | int | 720 | 图像高度 |
| fps | float | 30.0 | 期望帧率 |
| iou_threshold | float | 0.3 | 跟踪匹配的 IoU 阈值 |
| max_lost_frames | int | 30 | 轨迹最大丢失帧数 |
| output_frame | string | "camera" | 输出消息的 frame_id |
⚙️ TensorRT 集成细节
系统通过以下步骤使用 TensorRT 进行推理:
- 反序列化引擎
deserialize_engine()从 .engine 文件加载。 - 准备缓冲区
prepare_buffer()分配 GPU 输入/输出内存。 - 预处理
cuda_preprocess()执行 warpaffine + BGR→RGB + 归一化 + 通道转换 (NHWC→NCHW)。 - 推理
context.enqueueV2()异步执行。 - 后处理 CUDA 核函数
cuda_decode()和cuda_nms()在 GPU 上完成候选框筛选。
所有 CUDA 操作均在同一个流 (cudaStream_t) 中执行,确保异步并发。
📌 关键配置 (config.h)
| 宏 | 默认值 | 说明 |
|---|---|---|
kUserNumClass | 8 | 检测类别数 (根据模型修改) |
kUserInputSize | 640 | 模型输入尺寸 |
kUserConfThresh | 0.5f | 检测置信度阈值 |
kUserNmsThresh | 0.45f | NMS IoU 阈值 |
kBatchSize | 1 | 批处理大小 (当前仅支持 1) |
kGpuId | 0 | 使用的 GPU 设备 ID |
📐 核心类速览
FrameData— 包含原始图像、检测结果、跟踪结果、ROS 头的结构体。VehicleTrack— 对外暴露的跟踪结果(ID、框、轨迹、颜色等)。PerformanceMonitor— 计算滑动平均 FPS 和处理时间。DrawingUtils— 静态绘制方法(框、轨迹、仪表盘)。
💡 示例:自定义调用
在其他节点中订阅 /debug_image 和 /detected_objects 的示例:
#include <ros/ros.h>
#include <visualization_msgs/MarkerArray.h>
#include <sensor_msgs/Image.h>
void markerCallback(const visualization_msgs::MarkerArray::ConstPtr& msg) {
ROS_INFO("Received %lu tracked objects", msg->markers.size());
for (const auto& m : msg->markers) {
if (m.ns == "tracks") {
// 处理边界框
}
}
}
void imageCallback(const sensor_msgs::Image::ConstPtr& msg) {
// 显示或处理调试图像
}
int main(int argc, char** argv) {
ros::init(argc, argv, "custom_listener");
ros::NodeHandle nh;
ros::Subscriber sub_marker = nh.subscribe("/detected_objects", 1, markerCallback);
ros::Subscriber sub_img = nh.subscribe("/debug_image", 1, imageCallback);
ros::spin();
return 0;
}
🔍 故障排除
camera_id,使用 ls /dev/video* 查看可用设备。kConfThresh (在 config.h 中) 或检查模型是否适配。TENSORRT_ROOT 路径。📊 性能调优建议
- 启用 FP16/INT8 — 在 config.h 中取消注释
USE_FP16或USE_INT8并重新构建引擎。 - 调整图像分辨率 — 降低
width/height可提高 FPS,但可能影响小目标检测。 - 队列大小 — 减小
max_queue_size(capture_thread_func 参数) 可降低延迟。 - 线程亲和性 — 可考虑使用
pthread_setaffinity_np将推理线程绑定到特定 CPU 核心。
❓ 常见问题
Q: 支持哪些 YOLOv11 模型变体?
A: 代码中支持检测(det)、分割(seg)、姿态(pose)、旋转框(obb),当前节点使用检测模型。可通过修改 model.cpp 中的构建函数适配。
Q: 如何修改类别数?
A: 修改 config.h 中的 kUserNumClass,然后重新导出 .wts 并构建引擎。
Q: 是否可以跟踪行人或其他目标?
A: 可以,只需将模型替换为对应的检测模型,并修改 VehicleTrack 中的 type 字段。
📝 更新日志
版本 0.0.1 (2026-03-20)
- 初始版本:基于 YOLOv11 的车辆跟踪 ROS 节点。
- 实现三线程流水线、IoU 跟踪、性能监控。
- 支持 ROS Marker 和图像发布。
⚖️ 许可证
TODO — 目前未指定许可证,请在使用前联系维护者。
© 2026 jiamufengyue
© 2026 YOLOv11 Tracking ROS Package · 文档基于实际代码生成