简介面向智能交通与车辆维护场景这套YOLO11-DeepSORT轮胎检测与跟踪工程包将实时目标检测与多目标跟踪结合既能定位车辆轮胎又能在连续帧中稳定跟踪轮胎的位置、运动轨迹和状态变化可辅助磨损监测、气压异常预警与自动巡检等应用适合计算机视觉研究者、算法工程师和车辆运维开发人员学习使用。资源包共975个文件约282.87MB。其中450张jpg轮胎图像和440个txt标注文件构成可直接用于训练和评估的数据集29个Python源文件、31个pyc与3个yaml配置给出检测跟踪代码和环境参数3个pt/t7文件为训练好的模型权重另有3个mp4演示视频帮助直观理解运行效果从数据准备、模型训练到推理演示形成完整流程。当前已有66人学习下载使用者可直接加载训练好的权重体验轮胎跟踪也可基于自带数据集和脚本重新训练、调优。包内还提供results.csv、TensorBoard事件日志等训练记录便于查看mAP等指标变化并复现实验避免从零积累数据与调参的繁琐对开发车辆轮胎状态监测系统具有实际参考价值。1. 用YOLO11加DeepSORT给轮胎装上一双“巡检眼”这套车辆维护方案到底解决什么问题在车辆维护场景里轮胎检测和状态监测是最容易被低估、又最依赖老师傅经验的一环。你让一个巡检员蹲在车旁拿手电照胎面、看花纹深度、看偏磨、看裂纹一天下来几百台车漏判和误判几乎不可避免。标题里的 YOLO11-DeepSORT 方案就是用 YOLO11 把画面中的轮胎目标检测出来再用 DeepSORT 跟踪算法把同一只轮胎在连续视频帧中串成一条稳定轨迹配合已经训练好的检测模型和配套数据集直接就能落地到车辆维护的轮胎状态监测业务里。适合做智能巡检、车队管理、进出场站车辆检测的工程师也适合拿它当模板往下扩展轮胎磨损分级和异常报警。一句话它解决的是“人眼盯不过来”的问题让每一条轮胎被识别、被记住、被跟踪起来。2. YOLO11 和 DeepSORT 在轮胎场景里怎么分工先让检测不丢跟踪才能不飘2.1 YOLO11 拿什么换轮胎这个小目标的检测精度YOLO11 是 Ultralytics 在 YOLOv8 基础上继续演进的一代检测框架结构上把 C2f 模块换成了 C2PSA引入了一部分注意力机制同时在不同尺度的特征图上做了更多融合。这套改法对轮胎这类“中等偏小、纹理细节重要”的目标是实打实有用的。轮胎在画面里往往只占几十个像素尤其是进出场站抓拍的整车画面轮胎区域可能只有整张图的 2% 到 5%模型如果只在高层特征图上做预测很容易把小目标丢了。YOLO11 在颈部网络里保留了多尺度检测头P3、P4、P5 三路输出底层特征图保住了轮胎的花纹和边缘细节高层特征图负责语义判断这让小目标召回率比 YOLOv8 前期版本有明显提升。标题里明确带了“训练好的检测模型”这是个很实际的优势。你不需要从零开始攒数据、调几个月训练解压之后把权重路径指向 YOLO11 的推理接口就能先跑通检测。模型内部对轮胎的类别定义可能是单一类别“tire”也可能是按磨损、裂纹分了多类拿到手先跑一张带轮胎的图看输出确认类名和置信度阈值范围比自己闷头训练要快得多。常见做法是先用项目自带的权重做初步推理确认自己对输出格式的理解没错再考虑用自定义数据微调。另一个值得说的是 YOLO11 对推理框架的兼容性。它继承了 Ultralytics 的导出体系PyTorch 权重可以一行命令导出 ONNX、TensorRT、OpenVINO 格式。车辆维护场景经常要部署到边缘盒子比如 Jetson Orin、瑞芯微 RK3588 这类设备ONNX 和 TensorRT 是主流选择。检测环节稳了后面跟踪环节才有意义。from ultralytics import YOLO # 加载训练好的检测模型 model YOLO(best_tire.pt) # 换成项目里实际的权重文件路径 # 推理单张图片车牌识别类项目里常用于验证检测效果 results model.predict( sourcetest_tire.jpg, conf0.35, # 置信度阈值轮胎小目标多时先别拉太高 iou0.45, # NMS 的 IoU 阈值密集多轮场景可以降到 0.4 devicecuda:0, # 无 GPU 时改 cpu但帧率会明显下降 saveTrue ) # 输出检测框坐标xywh 格式中心点 宽高 boxes results[0].boxes.xywh.cpu().numpy() classes results[0].boxes.cls.cpu().numpy() confidences results[0].boxes.conf.cpu().numpy() for box, cls_id, conf in zip(boxes, classes, confidences): print(f类别 {int(cls_id)} 置信度 {conf:.2f} 坐标 {box})这段代码是典型的先验证后集成的路径。conf参数直接影响跟踪输入的噪声水平设低了会进来大量误检框跟踪器不得不处理很多假目标设高了会把低置信度的真实轮胎滤掉。我的习惯是先按 0.35 跑一遍视频统计检测结果里有没有“一眼假”的框再决定调高还是调低。iou参数处理的是重叠框去重轮胎特写镜头里两条轮胎挨得近NMS 阈值太高会把两个真实目标合并成一个框建议保持 0.4 到 0.5 之间。2.2 DeepSORT 靠什么区分“同一个轮胎”和“另一只轮胎”DeepSORT 的核心思路是“检测 关联”。每一帧 YOLO11 给出一堆框DeepSORT 负责回答一个问题当前这一帧里的框跟上一帧的哪条轨迹是同一个物理目标它内部用卡尔曼滤波预测目标在下一帧的位置再用马氏距离衡量预测框和实际检测框的空间匹配度同时用一个外观特征描述子计算表观相似度。空间距离负责“短期稳定”外观特征负责“长期防丢”。二者加权形成最终的代价矩阵然后交给匈牙利算法做指派。轮胎场景里空间距离和外观特征缺一不可。车辆行驶过一个监控画面时轮胎会被车身、前保险杠、旁边的立柱遮挡短则几十帧长则一两秒。如果没有外观特征纯靠运动预测目标一被遮挡就丢了 ID。DeepSORT 的外观描述子在这个场景里起的作用是让跟踪器记住了“这只轮胎长什么样”——包括胎面纹路、轮毂形状、胎侧文字这些细节哪怕目标重新出现也能重新接回原来的轨迹 ID。复现 DeepSORT 通常用开源实现常见的结构是一个特征提取模型加一个 tracker 核心模块。特征模型可以用 torchreid 训练的 ResNet50也可以用更轻量的 MobileNet 变体。对轮胎场景我一般不建议直接用行人重识别数据集训出来的权重因为行人特征和轮胎简直是两个世界迁移效果很差。项目里如果有配套的 reid 特征模型就用自带的没有就先用默认权重跑通流程后续再拿一批轮胎图片微调特征模型。2.3 检测和跟踪串联起来的主流程骨架import cv2 import numpy as np from ultralytics import YOLO from deep_sort_pytracker import DeepSort # 用你项目里实际的 DeepSORT 封装 # 初始化检测模型 detector YOLO(best_tire.pt) # 初始化跟踪器max_age 控制轨迹丢失多少帧后删除 tracker DeepSort( model_pathckpt.t7, max_age60, max_cosine_distance0.4, max_iou_distance0.7, nms_max_overlap1.0 ) cap cv2.VideoCapture(garage_camera.mp4) out cv2.VideoWriter( output_tracked.mp4, cv2.VideoWriter_fourcc(*mp4v), 25, (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) ) while True: ret, frame cap.read() if not ret: break # 1. YOLO11 检测拿到 bbox、置信度、类别 results detector(frame, conf0.35, iou0.45, verboseFalse) detections [] for box in results[0].boxes: x1, y1, x2, y2 box.xyxy.cpu().numpy().flatten() conf float(box.conf.cpu().numpy()) cls_id int(box.cls.cpu().numpy()) detections.append([x1, y1, x2, y2, conf, cls_id]) # 2. DeepSORT 更新检测框列表进去带 ID 的跟踪框出来 tracked_boxes tracker.update(detections, frame) # 3. 绘制跟踪结果 for track in tracked_boxes: if track.confidence 0.4: continue # 跟踪器给的低置信度框多半是误检 x1, y1, x2, y2 map(int, track.to_tlbr()) label fID:{track.id} conf:{track.confidence:.2f} cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) out.write(frame) cv2.imshow(tire tracking, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() out.release() cv2.destroyAllWindows()这段代码是整套方案的骨架。注意detections列表的构造方式DeepSORT 的update接口接受的是[x1, y1, x2, y2, conf, cls]的格式如果只传坐标不传置信度和类别部分实现里 cos 距离那一列会直接失效导致跟踪断档。max_iou_distance控制的是空间关联的容忍度轮胎在画面里移动不快0.7 够用如果场景是高速通过的车辆这个值反而可以调到 0.8让运动预测多担一点责任。代码跑通之后先别急着调模型调参拿一段十几秒的监控视频回放看看同一个轮胎是不是从头到尾只有一个 ID挡了一下之后 ID 有没有变两辆车的轮胎会不会互相抢 ID这三个问题决定了跟踪链路是不是真正稳住了。3. 数据集质量决定检测上限标注规范、目录组织与训练参数3.1 轮胎数据集该拍哪些场景从维修工位到车队进出场标题里带了数据集但对做业务的人来说“有数据集”和“有合格的数据集”是两回事。轮胎检测的数据集最怕的是场景单一。你在一个整洁的维修车间里拍了几千张图换到户外停车场、雨天泥地、夜间低照度场景模型准确率能掉 20 个点以上。轮胎出现在不同业务位置的样子差异极大四柱举升机上轮胎是正面悬空地沟工位里只能看到胎侧和轮毂下沿进出场闸口抓拍到的是整车侧面的小轮胎。数据采集阶段必须按业务的实际机位设计场景清单。我给一个常用做法分三批采集。第一批覆盖停车位和维修工位的静态轮胎正对胎面、侧对胎侧这是最容易拍也是模型最先学会的第二批覆盖车辆缓行通过画面的状态轮胎有旋转和运动模糊专门锻炼模型在模糊帧里的鲁棒性第三批覆盖遮挡和光照极端比如车旁有人走动、轮胎半埋在阴影里、夜间补光灯下的高反差画面。不用刻意追求数据量重点是把“你这个业务里实际会出现的样子”覆盖到。如果是从零开始攒数据我一般会参考 BDD100K 这类开放车辆数据集的场景分布思路白天、夜晚、阴天、隧道都留出比例但不会直接拿它们做训练因为通用车辆数据集里轮胎没有单独标注。自己的业务数据才是模型的上限来源。3.2 标注工具与格式转换把标注框从 XML 转成 YOLO 的 txtYOLO 系列训练需要的标签格式很简单每张图对应一个同名 txt每行是class_id x_center y_center width height四个坐标值都归一化到 0 到 1。标注工具方面LabelImg 对单纯画矩形框是够用的导出的 VOC XML 格式需要转换一下才能喂给 YOLO 训练。如果你拿到的是 COCO 格式的 json 标注也有标准转换脚本可改核心逻辑是一样的。import os import xml.etree.ElementTree as ET def convert_voc_annotation(xml_path, out_dir, class_names): 将单张图片的 VOC XML 标注转换为 YOLO txt 格式。 class_names 是类别列表顺序必须与 data.yaml 中的 names 一致。 tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) txt_lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_names: continue class_id class_names.index(name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 归一化到 [0,1]中心点 宽高 x_center (xmin xmax) / 2.0 / img_w y_center (ymin ymax) / 2.0 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h # 边界值裁剪避免浮点误差产生越界 x_center max(0, min(1, x_center)) y_center max(0, min(1, y_center)) width max(0, min(1, width)) height max(0, min(1, height)) txt_lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) if not txt_lines: return base os.path.basename(xml_path).replace(.xml, .txt) out_path os.path.join(out_dir, base) with open(out_path, w, encodingutf-8) as f: f.write(\n.join(txt_lines)) print(f已生成 {out_path}共 {len(txt_lines)} 个目标)转换脚本里两个细节很容易翻车。第一个是类别顺序class_names列表的顺序必须和data.yaml里的names完全一致否则训练出来的类别标签全是错位的。第二个是坐标边界裁剪有些标注工具手滑会把框略微画出图片边界不裁剪的话某些训练流程会在 loss 计算阶段报 NaN。标注框贴合度是轮胎检测项目里最玄学又最影响结果的因素。轮胎的视觉边界是“胎面到胎侧的外轮廓”很多人下意识把轮毂一起框进去这会让模型学到的特征是“轮毂轮胎整体”遇到样式不同的轮毂就翻车。正确做法是框住轮胎橡胶部分的外接矩形轮毂中心区域可以作为背景处理框的外边缘紧贴胎侧最外侧的点。3.3 训练参数从 data.yaml 到训练命令数据准备好之后训练配置主要做三件事定义数据集路径、设定训练超参、启动训练。data.yaml 是最容易出低级错误的地方路径写相对还是绝对、图片目录和标签目录是否对齐都会直接决定训练能不能跑起来。# tire_data.yaml path: ./tire_dataset # 数据集根目录相对路径基于你执行命令的当前目录 train: images/train val: images/val names: 0: tire这个 yaml 文件是训练入口。path字段如果不写那么train和val就是相对当前工作目录的路径写了path那么下面的路径就相对path来解析。很多人在服务器上训练时把图片路径复制错报错信息还是“找不到 label 文件”实际是 yaml 里 path 指错了。# 用 YOLO11 官方仓库的训练入口数据 yaml、预训练权重、超参一次指定 yolo detect train \ modelyolo11n.pt \ datatire_data.yaml \ epochs120 \ imgsz640 \ batch16 \ device0 \ patience20 \ workers8 \ project./runs \ nametire_train \ # 训练完成后验证集效果 yolo detect val \ model./runs/tire_train/weights/best.pt \ datatire_data.yaml训练参数里值得解释的是patience。它控制的是早停机制如果连续多少轮验证集指标没有提升训练就自动终止。我习惯设 20 到 30太少容易被验证集的波动骗到太多白烧 GPU 时间。imgsz这里用 640 兼顾速度和精度如果摄像头抓拍图是 1080p 以上轮胎目标偏小可以试试 960 甚至 1280但显存占用按平方上涨实测在 16G 显存的卡上 1280 配 batch 8 就可能 OOM。用项目自带的 best_tire.pt 继续微调的话把训练命令里的model参数换成 best_tire.pt 路径即可PyTorch 加载权重后会保留原来的类别数如果你的新数据集类别数量不一样ultralytics 会自动调整输出头并重新初始化最后一层这是 YOLO 系列一直保留的迁移学习习惯。训练好的模型就在runs/tire_train/weights/best.pt后面推理和转换都指向它。4. 用 DeepSORT 把检测结果串成轨迹参数设置与回放验证4.1 检测输出如何进入跟踪器从坐标框到轨迹状态的流程检测模型输出的每个框是独立的这一帧检测到的轮胎和上一帧检测到的轮胎之间没有关联关系DeepSORT 的工作就是给它们建立关联。整个流程可以拆成四步。第一步用卡尔曼滤波对已有轨迹做运动预测得到每条轨迹在当前帧的预期位置和速度第二步计算每个检测框和每条轨迹预测位置之间的 IoU 距离和马氏距离第三步计算外观特征向量之间的余弦距离把两个距离矩阵融合成综合代价矩阵第四步用匈牙利算法求解指派匹配上的检测框更新轨迹没匹配上的检测框初始化新轨迹持续没匹配上的轨迹被删除。# deep_sort 的 update 接口内部会处理卡尔曼预测、匹配、级联、初始化全套流程 tracked tracker.update(detections, frame) # 返回的 tracked 对象里常用属性拆解 for t in tracked: # t.id 是稳定的全局 ID一台车两只轮胎、两帧之间同一个目标 ID 不变 # t.to_tlbr() 返回 [x1, y1, x2, y2]是跟踪框而非原始检测框 # t.confidence 是检测置信度与跟踪置信度的融合值 # t.cls 保留来自检测模型的类别 ID pass这里最容易踩的一个坑是误以为tracked返回的就是检测框。DeepSORT 经过卡尔曼滤波后输出的框是“预测修正框”x1、y1、x2、y2 已经和检测框不完全一致这是正常的。如果后续做的是精确的位置测量比如轮胎中心坐标用于控制机械臂那就不能直接用跟踪框应该反向关联detections里原始框的坐标。update方法接收的frame参数也不是白传的。部分 DeepSORT 实现在内部会对当前帧做一次特征提取用于更新外观特征队列。如果你只在检测框周围裁剪一块图传入推理速度会显著变慢但如果你传整帧特征提取网络会处理全图。轮胎检测业务里我倾向于裁剪到检测框周围扩展 1.2 倍的区域传入兼顾速度和特征质量。4.2 三个必调参数max_age、max_cosine_distance、nms_max_overlap参数名作用推荐值调参逻辑max_age轨迹连续多少帧没有匹配到检测框就删除30 到 90车辆进出站遮挡频繁时调大画面目标少且帧率高时可调小max_cosine_distance外观特征距离超过该值则拒绝匹配0.3 到 0.5轮胎外观相似度高的场景调小光照变化大时调大nms_max_overlap同一轨迹内部多框重叠的最大容忍度0.7 到 1.0默认 1.0 代表不做轨迹内部 NMS目标密集时建议降到 0.7max_age是跟踪的“后悔药”。轮胎被车身挡住三五秒是常见情况如果设太小目标一被遮挡轨迹就删了重新出现又是一个新 ID整个轨迹断成几截后面做车辆维护统计时无法判断这只轮胎到底跟了多少秒。但设太大也有副作用目标离开画面很久不出现轨迹残留会跟新出现的检测框做匹配产生“跨时空跳变”的假轨迹。我的调法是观察实际帧率25 帧视频里被遮挡一般不超过 2 秒max_age60足够。max_cosine_distance控制的是外观判定的严格程度。两个轮胎长得像不像主要看轮毂和胎面磨损纹路如果车间里同车型同批次的车很多轮胎外观差异小这个参数要调严一些否则不同车的轮胎之间会频繁串 ID。但如果现场光照变化大侧光和逆光下同一个轮胎的特征距离都可能超过 0.4调太严就导致跟踪丢失。先跑一段视频看 ID 切换频率再按实际效果收敛。4.3 可视化验证画 ID、画轨迹线、判断跟踪质量# 跟踪结果回放验证 ID 稳定性的标准做法 import cv2 from collections import defaultdict track_history defaultdict(list) # track_id - list of (cx, cy) # 在上一节的主循环里把每帧的跟踪框中心点记录到历史字典 for track in tracked_boxes: x1, y1, x2, y2 map(int, track.to_tlbr()) cx, cy (x1 x2) // 2, (y1 y2) // 2 track_history[track.id].append((cx, cy)) # 每个 ID 保留最近 30 个中心点画成轨迹线 for tid, pts in track_history.items(): recent pts[-30:] for i in range(1, len(recent)): cv2.line(frame, recent[i - 1], recent[i], (255, 0, 0), 2)可视化验证是调跟踪参数最直接的手段。判断跟踪质量的三个标准是目标从头到尾 ID 不变、遮挡后重新出现仍然接回原 ID、两个相邻目标各自保持独立 ID。如果画面里一辆卡车两个并排轮胎频繁交换 ID优先调大max_cosine_distance的严格度如果一辆车在画面里从头到尾被换了五六个 ID优先检查是不是max_age太小或特征模型在该场景下失效。我习惯把回放视频放慢到 0.5 倍速盯着一只轮胎从进入画面到离开画面手动记录它经历了哪几帧、被遮挡了几次、ID 变了没有。一段 30 秒的视频如果目标 ID 切换次数超过两次说明跟踪参数还没调到位不要急着往下做业务统计。5. 避坑指南轮胎检测跟踪最容易翻车的 5 个现场5.1 训练 loss 很低但 mAP 起不来标注框把轮毂一起框进去了现象训练 100 轮之后 loss 曲线很漂亮验证集 mAP 却只有 0.3 上下可视化检测结果发现模型把轮毂边缘当成轮胎边界不同轮毂样式的车识别效果天差地别。原因标注阶段把轮毂和轮胎整体框成了一个矩形模型学到的特征被轮毂的金属反光主导。轮毂造型千变万化训练集里见过五辐轮毂换到十辐轮毂就翻车。解决重新检查并修正已有标注框让框紧贴轮胎橡胶部分外轮廓。数据集里轮毂样式足够多样的情况下模型会主动忽略轮毂区域专注学习胎面纹理和胎侧特征。如果修改标注成本太高至少把验证集里明显带轮毂的坏标注删掉重新训练。5.2 视频里目标明明一直在跟踪 ID 却频繁跳变现象同一辆车的左前轮在画面里从进入到离开换了七八个 ID跟踪轨迹断成一截截的业务统计完全没法用。原因帧率低或者目标被车身、立柱短暂遮挡时max_age设置太小轨迹在被遮挡期间就被删除了。目标重新出现时被当成新目标初始化自然获得新 ID。解决先把max_age从默认的 30 提高到 60 到 90让轨迹在目标被遮挡期间存活更久。再看特征模型是不是过关如果遮挡时间超过 2 秒靠空间预测已经不够必须靠外观特征重新接回原轨迹。可以用一段 1 分钟的视频做稳定测试统计单条轨迹的 ID 切换次数目标全程无明显变化但 ID 切换超过 2 次就继续调参。5.3 双轮胎并排行驶时两个 ID 互相串现象卡车后轴双轮胎并排跟踪框在两个轮胎之间反复横跳一会儿左轮胎是 ID 5一会儿右轮胎是 ID 5。原因两个目标空间距离太近IoU 重叠度高max_cosine_distance设置过松外观特征距离无法区分高度相似的轮胎对。解决把max_cosine_distance从 0.4 收紧到 0.2 到 0.3同时检查nms_max_overlap如果检测阶段两个轮胎的框被合并成一个那跟踪阶段拿到的输入就是错的。另一个办法是提高检测模型的输入分辨率让两个轮胎在特征层面能区分开1080p 原图配 640 推理分辨率时双轮间隙可能只有几个像素放大到 960 后特征差异会明显变大。5.4 把轮毂高光误检成轮胎现象画面里出现金属反光、油污地面反光、甚至白色车身侧面检测框总是一闪一闪地出现置信度徘徊在 0.3 到 0.5 之间。原因训练数据里负样本不足。模型没见过足够多“长得像轮胎的圆形反光”判定边界模糊把高反光区域当成了正样本。解决采集一批不带轮胎但是有反光、圆环、深色圆型物体的背景图放进训练集标注为空文件夹只有背景图没有 label。YOLO 系列训练会把这些图作为负样本参与 loss 计算。推理端也把conf阈值从 0.25 提高到 0.4过滤掉低置信度的脉冲误检代价是可能漏掉一小部分被强遮挡的真实轮胎这个权衡看业务更在意误报还是漏报。5.5 边缘设备上推理速度只有 5 帧完全跑不起实时现象同样一套检测加跟踪代码在台式机上 30 帧流畅部署到边缘盒子只有 4 到 6 帧车辆快速通过时跟踪框飘得厉害。原因没有做模型导出优化PyTorch 的动态图推理在边缘设备上开销很大。DeepSORT 端到端包含两套网络特征提取模型如果也是 PyTorch 加载整体延迟叠加。解决把 YOLO11 权重导出成 ONNX 或 TensorRT用静态输入尺寸和半精度 FP16 推理。DeepSORT 的特征模型也做同样的导出。另一个容易忽略的点是视频解码OpenCV 的VideoCapture在边缘设备上默认走 CPU 软解换用硬件解码接口比如 Jetson 平台的nvbufsurf能省出不少 CPU 时间。实测把这个流程串好之后边缘设备的推理帧率往往能翻一倍这是部署这块性价比最高的一步。6. 从 demo 到值班系统导出 ONNX、效率化推理与业务验证# 把训练好的权重导出为 ONNX 格式固定输入尺寸 yolo export model./runs/tire_train/weights/best_tire.pt formatonnx opset12 imgsz640 # 如果边缘设备支持 TensorRT再走一步 # 用 trtexec 或者 ultralytics 的 export formattensorrt 生成 engine导出 ONNX 是部署环节的第一道工序。opset12是兼容性和功能平衡较好的选择老版本 TensorRT 也能解析。导出后先用onnxruntime跑一遍验证输出和 PyTorch 原模型一致再接入推理引擎。DeepSORT 的特征模型也在这一步一起导出两套网络统一走 ONNX Runtime边缘设备推理效率提升明显。业务验证环节我建议做两个动作。第一个是目标级验证把一段 10 分钟的业务视频逐帧跑完统计出现过的轮胎总数、被成功跟踪的轮胎比例、ID 切换次数算出一个“跟踪稳定率”。第二个是业务级验证在车辆维护工作流里选择一个具体场景比如进站车辆轮胎磨损自动登记把跟踪结果接进业务逻辑跑一周试运行手工复核结果。跟踪稳定率超过 90% 再谈上线否则先回头调检测阈值和跟踪参数。我自己做这类项目有一个习惯结论先不看 mAP让跟踪器跑一段真实业务视频人工看 ID 稳定性曲线。模型 mAP 是静态指标业务关心的是动态跟踪连续不连续。YOLO11-DeepSORT 这套方案的价值就在于此——检测模型保证了“看得见”跟踪算法保证了“记得住”两者一配合才能从“一堆框”变成“一条条可追溯的轮胎轨迹”这才是车辆维护系统真正需要的东西。希望帮到你。本文还有配套的精品资源点击获取