
简介YOLOv10汽车轮胎检测项目提供训练好的轮胎识别权重与配套数据集主要面向自动驾驶、智能交通、车辆检测等场景下的轮胎目标检测需求适合有一定PyTorch基础、需要快速获取完整训练流程或参考数据组织方式的开发者。项目类别定义为tire使用PyTorch框架并以Python代码实现标签文件分别按txt和xml两种格式保存在独立文件夹中便于切换不同标注工具或复现训练。压缩包共1701个文件核心内容包括450张JPG轮胎图像、450个txt标签、158个Python脚本、67个yaml配置以及训练好的pt权重文件同时附带PR曲线、loss曲线、训练日志、说明文档和部分推理示例代码整体大小148.39MB。资源还提供了作者在实际轮胎检测数据集上的训练结果与配套参考链接可帮助读者快速复现检测效果权重既可直接用于推理也可基于数据集继续微调。当前已有933人浏览学习适合YOLOv10入门学习或轮胎识别项目开发者直接参考使用。1. YOLOv10 轮胎检测为什么通用权重在部件级识别上不香很多工程师拿到 COCO 预训练权重就直接跑车辆检测结果发现车框得很准轮胎单独框出来却总是一半、漏检、或者把轮毂和轮胎混在一起。原因很简单COCO 的 80 类里没有“轮胎”模型在训练时只见过“car”“truck”这种整体语义没见过“tire”这种部件级目标。你真正需要的是一个在轮胎数据集上专门收敛过的权重以及能复现这个收敛过程的一整套配置。这份 YOLOv10 汽车轮胎检测资源包里恰好同时给了训练好的权重和配套数据集。资源包的核心内容是一个训练好的轮胎识别权重类别名tire单类别、包含txtYOLO 格式和xmlVOC 格式两种标签的完整数据集以及训练过程中产生的events.out.tfevents日志文件——里面有 PR 曲线和 loss 曲线可以直接复盘模型的收敛过程。这对两类人最有用一是正在做车辆部件识别、轮胎缺陷检测预研的 CV 工程师二是准备用 YOLOv10 训练自己的单类别数据集、但不想从零开始做数据标注的人。下文从数据集解析、配置文件改造、推理验证和事件文件复盘四个维度把这个项目完全拆开。2. 数据集解剖txt 标签与 xml 标签的对应关系与转换2.1 目录结构里的隐藏信息解压资源包后先看目录通常会出现images、labels包含 txt、Annotations包含 xml三类目录以及顶层散落的labels.cache、events.out.tfevents.1719203393.USER-20231125JB.7292.0等文件。labels.cache是 YOLO 训练过程中自动生成的标签缓存作用是加速数据集校验和样本读取如果改动过标签文件它不会自动重建而会在训练时报数据不匹配错误需要手动删除后重新生成。find . -maxdepth 2 -type d | sort find . -name *.xml | wc -l find . -name *.txt -path *labels* | wc -l第一条命令梳理目录层级第二、三条用来快速核对两种格式的标签数量是否一致。数量不一致时优先检查是不是有纯背景图没有标注这类图片需要保留但只留 txt 空标签文件否则训练时会抛数据集不匹配异常。2.2 YOLO 格式 txt 标签解析与归一化坐标YOLO 格式的每一行代表一个目标结构为class_id x_center y_center width height后四个值都是相对于图片宽高的归一化数值。注意这里不是边界框的左上角坐标很多新人在手工修改标签时会把x_center当成左上角x_min导致训练出的权重在推理时框整体左移。with open(labels/train/000001.txt, r) as f: lines f.readlines() img_w, img_h 1280, 960 # 实际数据集中图片的宽高 for line in lines: cls_id, x_c, y_c, w, h map(float, line.strip().split()) x_min int((x_c - w / 2) * img_w) y_min int((y_c - h / 2) * img_h) x_max int((x_c w / 2) * img_w) y_max int((y_c h / 2) * img_h) print(f类别: {int(cls_id)}, 左上角: ({x_min}, {y_min}), 右下角: ({x_max}, {y_max}))这段代码把归一化坐标还原成像素坐标方便和图片上的实际轮胎位置做肉眼对比。x_c - w / 2是从中心点反推左上角的核心逻辑除以 2 这一半最容易漏掉。转换后发现框比轮胎大一圈或小一圈时不要怀疑公式先回看labelling标注时的框线贴边程度——标注习惯不同会导致同一种转换逻辑在视觉上有偏差。2.3 VOC xml 标签到 YOLO txt 的完整转换脚本Annotations里的 xml 是 Pascal VOC 风格结构简单且标签类别名就是tire摘要里已说明类别名为 tire有些版本可能是car_tire以你自己那份 xml 里的name节点为准。训练或迁移时需要把 xml 转换成 YOLO txt按同样的规律落到labels目录。import xml.etree.ElementTree as ET import os def xml_to_yolo(xml_path, out_dir, class_mapNone): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) yolo_lines [] for obj in root.iter(object): cls_name obj.find(name).text cls_id 0 if class_map is None else class_map[cls_name] box obj.find(bndbox) x_min float(box.find(xmin).text) y_min float(box.find(ymin).text) x_max float(box.find(xmax).text) y_max float(box.find(ymax).text) x_c (x_min x_max) / 2 / img_w y_c (y_min y_max) / 2 / img_h w (x_max - x_min) / img_w h (y_max - y_min) / img_h yolo_lines.append(f{cls_id} {x_c:.6f} {y_c:.6f} {w:.6f} {h:.6f}) txt_name os.path.splitext(os.path.basename(xml_path))[0] .txt with open(os.path.join(out_dir, txt_name), w) as f: f.write(\n.join(yolo_lines)) xml_to_yolo(Annotations/000001.xml, labels/train)这个脚本中(x_min x_max) / 2 / img_w分两步先算两个端点之和的平均值得到中心点像素坐标再除以图片宽度做归一化。面积计算时注意VOC 的xmaxymax通常是从 1 开始计数而 PASCAL VOC 坐标换算成 COCO 的像素坐标时会涉及减一还是不减一的问题但 YOLO 在做归一化时差异在万分位上可以忽略不计。实际转换完抽样三张图用mAP评估一次比肉眼逐个检查更高效也更能发现系统性偏移。2.4 标签质量检查的一个关键指标用脚本统计每一张图的标注框数量与面积分布轮胎数据集很容易出现“轮毂内侧被标成背景”“两个轮胎被标成一个框”两种情况这类样本会直接拉低 mAP50。一个通用做法是计算label_area_ratio标注框面积占整图面积的比值轮胎部件级的比值一般在 0.03 到 0.2 之间若超过 0.4 大概率是误标成整车了。import os def check_label_area(img_dir, label_dir): for img_name in os.listdir(img_dir): stem os.path.splitext(img_name)[0] txt_path os.path.join(label_dir, stem .txt) if not os.path.exists(txt_path): print(f缺少标签: {stem}) continue total_ratio 0.0 with open(txt_path) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(f格式异常: {txt_path} - {line}) continue _, _, _, w, h map(float, parts) total_ratio w * h print(f{stem} 标注面积占比: {total_ratio:.3f})补充一句labels.cache文件在这套检查流程里只能说明 YOLO 曾经成功读过一次标签不能把它当成标签正确的证据真正要验证的是缓存重建的日志里没有WARNING: corrupted image这行字样。3. 配置 YOLOv10 环境与创建 tire.yaml 训练文件3.1 YOLOv10 官方仓库的安装与目录确认实现训练流程前先把基础环境立住。YOLOv10 是 2024 年提出的方案整体逻辑和 YOLOv8 高度一致直接使用 Ultralytics 仓库代码可以跑通大部分训练任务仓库内置了yolov10s.yaml、yolov10m.yaml、yolov10l.yaml等模型结构定义以及对应的预训练权重。git clone https://github.com/THU-MIG/yolov10.git cd yolov10 pip install -r requirements.txt pip install -e .pip install -e .把 yolov10 包以可编辑模式装进当前 Python 环境这样你在任意目录下执行from ultralytics import YOLO都能导入。装完后先确认版本是否正常import ultralytics; ultralytics.__version__能正常输出版本号即可开始下一步。若环境里本来就装过老版本ultralytics建议先pip uninstall ultralytics再装避免 YOLOv10 的检测头配置被旧版本覆盖——这个问题在带 torch 2.x 的既有环境里特别常见。3.2 解析固有配置文件yaml 的结构层次网上搜 “yolov10 yaml 文件怎么创建” 的答案五花八门本质上你要创建的是数据集配置文件不是模型结构文件。模型结构文件在ultralytics/cfg/models/v10/下里面的yolov10s.yaml描述了骨干网络、颈部结构和检测头而数据集配置文件放在ultralytics/cfg/datasets/两者职责不同。# tire.yaml path: /path/to/your/tire-dataset # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 nc: 1 # 类别数量只有轮胎一类 names: 0: tire # 类别名必须与训练数据中的 cls_id 对应这份配置里path可以写绝对路径也可以写成相对根目录的路径YOLOv10 会拼接path train得到完整的图片目录。最常翻车的点在于names是从 0 开始的字典如果第 0 类写成了car训练出来的权重依然会输出轮胎框但类别名在推理时显示为 car混淆矩阵和 PR 曲线的类别语义也会跟着错位。写完配置后运行一次python -c from ultralytics.data import build_yolo_dataset; build_yolo_dataset(tire.yaml, images/train, batch_size8, modetrain)这一步能在不启动训练的情况下提前暴露路径错误、标签缺失和图片损坏等问题比直接训练到一半再报错要高效得多。构建失败时优先检查labels目录命名是否正确YOLOv10 默认把标签放在labels/train和labels/val下与images/train、images/val严格对应。3.3 结构配置文件里与 tire 相关的三个关键参数打开yolov10s.yaml除了nc: 80改成nc: 1之外还有几个参数直接影响轮胎这个小目标的召回。scale: - 0.33 # depth_multiple统一控制模型的深度倍数 - 0.50 # width_multiple控制每层通道数 - 1.0 # max_channels限制最大通道数不超过 1024 backbone: - [-1, 1, Conv, [64, 3, 2]] - [-1, 1, Conv, [128, 3, 2]] ...depth_multiple值越大网络越深对轮胎的纹理细节如胎纹、轮毂边缘提取越充分但显存消耗同步上升。轮胎在车辆图像中往往只占 5% 到 15% 的像素面积属于中小目标如果数据集中远距离轮胎样本多建议保持 depth0.33 而把max_channels从 1024 调到 1280相当于给高层特征图更多通道去表达小目标语义。另一个值得关注的是yolov10s.yaml里的max_det参数推理阶段专用默认 300 个检测框轮胎场景一般不会超过 30 个目标保持默认即可不需要像工业零件密集检测那样调大到 600。数据集配置文件与结构配置文件的完整关系是tire.yaml指向数据源和类别语义yolov10s.yaml定义网络容量与计算量训练命令把两者传参给 Trainer。修改任何一处 yaml 后删除labels.cache再重启训练才能让新配置完全生效。若你对 yaml 创建工具不熟建议直接复制coco128.yaml改名后逐行替换路径与类别名比从空白文件新建少踩很多格式坑。4. 训练后的权重推理与评估指标解码4.1 使用 CLI 快速推理测试图片资源包里的权重是训练好的tire.pt也可能命名为best.pt优先找 val 指标最高的那个拿到图和权重后先用命令行跑一遍确认推理链路无损。yolo detect predict modeltire.pt sourcetire_test.jpg conf0.25 iou0.7 saveTrue projectruns/detect nametire_infer这里conf0.25表示置信度阈值低于 0.25 的预测框被过滤iou0.7是 NMS非极大值抑制的 IoU 阈值。YOLOv10 的核心改动之一是去掉了 NMS 依赖模型直接输出一组稀疏的候选框但在推理脚本里依然保留了 NMS 后处理以保证老代码兼容性所以iou参数仍然可以调节——车轮相互遮挡的场景把 IoU 降到 0.5 能保留更多被抑制但实际存在的轮胎框。saveTrue会把标注了预测框的图片输出到runs/detect/tire_infer目录便于直接观察错检和漏检。4.2 脚本方式推理拿到张量结果CLI 适合快速验证但如果你想在二次开发的检测系统里集成这个权重必须理解模型输出张量的结构。from ultralytics import YOLO model YOLO(tire.pt) results model.predict(sourcetire_test.jpg, conf0.25, verboseFalse) for r in results: boxes r.boxes for box in boxes: x1, y1, x2, y2 box.xyxy[0].tolist() conf float(box.conf[0]) cls_id int(box.cls[0]) print(f轮胎框: ({x1:.1f}, {y1:.1f}) - ({x2:.1f}, {y2:.1f}), 置信度: {conf:.3f}) # 可视化保存 r.save(filenameinfer_result.jpg)r.boxes.xyxy返回的是像素坐标不是归一化坐标直接用于画矩形框。box.conf是每个框的置信度分数多个轮胎时排序后取前 K 个即可以实现“只保留置信度最高的轮胎”的业务逻辑——比如停车场入口只关心最近的一个轮胎。cls_id在这种单类别模型里基本都是 0但不要硬编码逻辑代码里仍应以cls_id作为类别分支依据方便以后升级为多类别tire, wheel hub, brake disc。4.3 理解 PR 曲线和 loss 曲线对应的数据字段权重包里带有events.out.tfevents.1719203393.USER-20231125JB.7292.0这个文件是 TensorBoard 的日志格式里面记录了训练过程的train/loss、val/box_loss、metrics/mAP50()等标量数据以及验证阶段计算得到的 PR 曲线、F1 曲线和混淆矩阵。不要直接双击打开要用解析脚本读。from tensorboard.backend.event_processing.event_accumulator import EventAccumulator acc EventAccumulator(events.out.tfevents.1719203393.USER-20231125JB.7292.0) acc.Reload() tags acc.Tags()[scalars] print(可用指标:, tags) mAP50 acc.Scalars(metrics/mAP50()) for step_item in mAP50[-3:]: print(fstep{step_item.step}, mAP50{step_item.value:.4f}) train_loss acc.Scalars(train/box_loss) print(f最终训练损失: {train_loss[-1].value:.4f})mAP50()是 IoU 阈值为 0.5 时的平均精度均值对轮胎这种刚体目标来说mAP50 在 0.9 以上说明模型整体可靠而mAP50-95()在不同 IoU 阈值下的平均值更能反映定位精度如果 mAP50 高但 mAP50-95 偏低说明预测框虽然位置对但边缘贴合不紧此时优先考虑数据集中增加遮挡样本而不是加训练轮数。train/box_loss和val/box_loss两条曲线之间的差距如果越拉越大就是过拟合信号需要提前停止或在配置里增加weight_decay。表格整理这几项的核心用途指标数据来源轮胎场景解读优调手段mAP50TensorBoardmetrics/mAP50()目标检测的召回与精度综合表现调整 conf 阈值、增加正样本mAP50-95TensorBoardmetrics/mAP50-95()定位框贴合度越高越好优化标注边缘、提高输入分辨率val/box_lossTensorBoardval/box_loss验证集的边框回归误差调节学习率、增加数据增强PPrecisionPR 曲线顶点误检少提高 conf 阈值、增加难负样本RRecallPR 曲线右端漏检少降低 conf 阈值、增加目标样本CLI 推理时修改conf0.5会在 Precision 和 Recall 之间来回摆务必要配合 PR 曲线图选定业务阈值。PR 曲线里靠近右上角的点对应的置信度就是理论和实测比较匹配的平衡点我一般先取这个值做落地部署再根据线上误报率上下浮动 0.05。5. 基于已有权重继续微调与 TensorBoard 可视化技巧5.1 用预训练权重做初始化而非重新训练很多人在新数据集上习惯weightsyolov10s.pt从头训其实更好的选择是直接用本资源包里的tire.pt做初始化特别是当你的新数据只有几百张轮胎图时。预训练权重已经学到了轮胎的边缘纹理和轮毂结构特征它在新数据集上的收敛速度比 COCO 预训练权重要快得多通常只需一半的 epoch 就能到达相同 mAP。yolo train datamy_tire_v2.yaml modeltire.pt epochs100 imgsz640 batch16这里modeltire.pt既是结构定义也是权重初始化来源如果想让最后一层检测头重新初始化以适配新的类别数可以在配置里加上freeze10冻结前 10 层骨干网络只训练特征融合和检测头部分。冻结层数的选择有一个快捷经验先跑 10 个 epoch记录每层权重更新量的梯度范数把梯度范数接近零的层全部冻结这样显存占用更低且训练稳定性更可控。5.2 TensorBoard 实时观察训练过程启动训练后如果需要远程查看训练曲线可以在任意一台机器上指向日志目录启动 TensorBoard 服务。tensorboard --logdirruns/detect --port6006 --host0.0.0.0浏览器打开http://服务器IP:6006在 SCALARS 面板里可以按步骤勾选metrics/mAP50()与metrics/mAP50-95()两条曲线这个对比是评估模型是否有持续优化空间的性价比最高的方式。如果 mAP50 在提升而 mAP50-95 停滞甚至下降说明模型过拟合于粗定位此时在ultralytics/cfg/default.yaml中加大hsv_h、hsv_s等颜色增强幅度可以改善边缘回归的多样性而对轮胎这种纹理相对单一的目标degrees15适度旋转也能帮助泛化。5.3 推理提速的细节配置最后一个实操技巧是推理阶段的批量预处理。轮胎检测在车辆入口、安检通道等场景中往往需要接入 RTSP 视频流此时不要逐帧调用model.predict()而是用批量推理from ultralytics import YOLO import cv2 model YOLO(tire.pt) cap cv2.VideoCapture(rtsp://your_camera_stream) batch_frames [] while True: ret, frame cap.read() if not ret or len(batch_frames) 8: if batch_frames: results model.predict(batch_frames, conf0.3, imgsz640) for r in results: print(len(r.boxes)) batch_frames [] if not ret: break batch_frames.append(frame)model.predict(batch_frames)内部会自动做一批推理相比 for 循环逐帧调用省去了多次前处理的重复计算吞吐量能提升 40% 以上。注意imgsz640是推理输入尺寸实际图片大于这个分辨率时 YOLOv10 会等比缩放后填充灰边padding 部分不会产生误检。若视频流卡顿优先把imgsz降到 480 而不是调低conf分辨率下降导致的检测率损失小于阈值下降带来的误报增加。另外一点我在多个轮胎项目里验证过权重包里如果有yolov10tire.pt与yolov10tire-s.pt两个文件优先用参数量更大的那个做离线检测参数小的留给嵌入式设备把权重用torch.jit.trace导出成 TorchScript 后在 Jetson 这类边缘设备上的推理延迟一般能压到 20ms 以内转换前在 Python 环境里复现一次 PR 曲线确保转换过程没有破坏检测头的输出分布。本文还有配套的精品资源点击获取