轨道矿车与人员检测数据集实战:YOLOv8训练调优与边缘部署 简介这份资源是面向矿业自动化与计算机视觉方向的开发者、算法工程师及高校研究者的YOLO格式目标检测数据集聚焦轨道场景下矿车与人员的识别任务可用于训练和验证矿车运行状态是否伴随人员干扰。压缩包共2000个文件以1045张jpg图像和954个txt标注文件为主另含1个yaml配置文件整体约206.69MB图像与标注一一对应便于直接接入YOLO系列训练流程。数据集类别数为2分别为Normal与With People覆盖实际矿业轨道环境类别精简有助于模型专注学习矿车与人员两类目标。目前已有118人学习下载。借助该数据集读者可快速搭建检测实验、验证模型在工业场景下的实时性与准确率并据此优化安全生产监测方案降低事故风险。1. 轨道矿车与人员检测这个数据集到底能解决什么现场问题井下轨道运输最让人头疼的不是矿车跑得快而是人车混行。电机车拉着几节矿车在窄轨上走弯道、岔口、装卸点随时可能冒出巡检工或临时作业人员司机视野被矿车挡住等看到人已经来不及刹车。这类场景做视觉检测公开数据集基本帮不上忙——COCO 里没有井下矿车BDD100 是道路车辆crowdhuman 只关心人。所以看到「轨道上矿车和人员检测数据集」这个标题我第一反应是终于有人把这两个目标放进同一个标注体系里了。这个数据集要解决的核心问题是同一画面里同时定位矿车和人员并区分轨道环境下的不同姿态。它适合三类人做矿山智能化改造的算法工程师、想拿真实工业场景练 YOLO 的学生、以及需要给电机车装主动预警系统的集成商。矿车目标大、纹理重复、金属反光强人员目标小、被矿车遮挡多、井下光照差这两类目标放一起训难度比单纯做人检或车检高一个量级。下面按「数据集怎么读 → 模型怎么选 → 训练怎么调 → 坑在哪」的顺序拆开讲每一步都给能直接抄的命令和参数。2. 拆开压缩包先看什么目录结构、标注格式与类别分布拿到一个.zip数据集别急着写train.py。我见过太多人直接解压丢给 YOLO训到一半发现类别对不上、坐标越界、图片和标签数量不匹配白白烧几个小时 GPU。这一章讲清楚解压后该按什么顺序检查以及这个数据集大概率长什么样。2.1 解压后的目录长什么样先跑一遍体检脚本工业检测数据集常见的组织方式是images/和labels/平行存放或者按train/val/test分好再各自带images、labels。矿车人员这类数据集通常还会多一个classes.txt或data.yaml说明类别顺序。先解压再列目录unzip MineCarWithPeople-yolo-data-轨道上矿车和人员检测数据集.zip -d minecar_dataset cd minecar_dataset find . -maxdepth 3 -type d | sort find . -name *.jpg -o -name *.png | wc -l find . -name *.txt | wc -l第一行解压到指定目录避免污染当前工作区。后面两条统计图片和标签数量这两个数字必须相等差一个都说明有图片没标或标签丢失。如果图片是.jpg而标签是.txt说明是 YOLO 格式如果标签是.xml那是 VOC 格式需要转换。我一般还会看一眼单张标签内容head -5 labels/000001.txtYOLO 格式每行是class_id x_center y_center width height五个值全部归一化到 0~1。如果看到坐标大于 1 或者出现负数说明标注工具导出时没归一化这种数据直接训会让损失爆炸。血泪经验先体检再训练省下的不是几分钟是几小时。2.2 类别顺序决定一切data.yaml 必须自己核对YOLO 训练时类别索引是隐式的0代表什么、1代表什么全靠data.yaml里的names列表。矿车和人员两个类如果标注时0person, 1minecar而你写反了模型会把矿车当人、人当矿车mAP 看着还行但实际完全不能用。常见做法是打开data.yaml逐行核对path: ./minecar_dataset train: images/train val: images/val nc: 2 names: 0: person 1: minecarnc是类别数必须和names长度一致。train和val路径是相对path的写错会报No labels found。如果数据集没给data.yaml就自己建一个放在数据集根目录。注意类别顺序一旦定了就不能改训练中途改names顺序等于让模型重新学之前权重全废。2.3 用脚本统计类别分布判断要不要重采样两个类别的样本数往往极不平衡——人员可能几千个框矿车只有几百个。这种长尾分布会让模型偏向多数类。写个脚本统计每个类别的框数import os from collections import Counter label_dir labels/train counter Counter() for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue with open(os.path.join(label_dir, fname)) as f: for line in f: cls int(line.split()[0]) counter[cls] 1 print(类别框数统计:, dict(counter)) total sum(counter.values()) for cls, cnt in counter.items(): print(f类别 {cls}: {cnt} 框, 占比 {cnt/total:.2%})这段代码遍历所有标签文件按第一个字段类别 id计数。如果发现person占比超过 80%训练时就要考虑给minecar类加权或者对矿车样本做增强。参数说明label_dir指向训练集标签目录验证集单独统计一次确认两个集合分布一致否则验证指标会失真。3. 用 YOLOv8 跑通第一个基线环境、配置与训练命令数据集体检完下一步是尽快跑出一个能看的基线。别一上来就调超参先用默认配置训 50 轮看看 loss 曲线和验证集表现心里有个底。这一章给一套在 PyCharm 或命令行都能用的流程。3.1 环境安装ultralytics 一条命令别装一堆重复包YOLOv8 现在统一在ultralytics包里不需要单独装 darknet 或 torch 之外的依赖。我一般用 conda 建个干净环境conda create -n minecar python3.10 -y conda activate minecar pip install ultralytics opencv-pythonultralytics会自动带上匹配版本的torch和torchvision。如果你在 AGX Orin 上跑需要装 NVIDIA 官方适配的 torch wheel别直接用 pip 默认源否则 CUDA 用不了。装完验证一下yolo checks这条命令会打印环境信息重点看CUDA是否可用、torch版本和 GPU 型号。如果显示CPU说明 torch 装成了 CPU 版训练会慢到无法接受。踩坑记录PyCharm 里如果开了多个解释器yolo命令可能指向另一个环境务必在终端确认which yolo和 PyCharm 项目解释器一致。3.2 训练命令与关键参数imgsz、batch、workers 怎么定基线训练命令如下yolo detect train \ data./minecar_dataset/data.yaml \ modelyolov8n.pt \ epochs50 \ imgsz640 \ batch16 \ workers4 \ device0 \ projectruns/minecar \ namebaseline逐项说明modelyolov8n.pt用 nano 版先跑通速度快、显存占用低适合验证数据管线。imgsz640是输入分辨率矿车目标大640 够用如果人员目标在画面里很小比如远景巡检工可以提到 960 或 1280但显存翻倍。batch16在 8G 显存上比较稳显存不够就降到 8 或 4。workers4是数据加载线程数Windows 下设太高容易卡死Linux 可以到 8。device0指定第一块 GPU多卡用device0,1。训练开始后重点看三件事box_loss是否稳定下降、cls_loss有没有震荡、验证集mAP50是否在涨。如果box_loss前几轮就变成nan八成是标签坐标越界或图片损坏回到第 2 章重新体检。3.3 训练完怎么读结果mAP、混淆矩阵和误检样本训练结束会在runs/minecar/baseline/下生成results.csv、confusion_matrix.png、val_batch0_pred.jpg。先看results.csv最后几行的metrics/mAP50-95两个类的平均值能到 0.5 以上说明基线可用。然后打开混淆矩阵重点看person和minecar有没有互相误判——如果矿车被大量判成人说明两类纹理特征没拉开需要加背景负样本或调整锚框。val_batch0_pred.jpg是验证集第一批的预测可视化直接看框的位置和置信度。我习惯挑几张漏检的图用yolo detect predict单独跑yolo detect predict \ modelruns/minecar/baseline/weights/best.pt \ source./minecar_dataset/images/val \ conf0.25 \ saveTrueconf0.25是置信度阈值调低能看到更多候选框方便判断是漏检还是置信度不够。参数说明source可以是单张图、目录或视频输出默认在runs/detect/predict/。4. 矿车与人员混检的调优锚框、增强与类别不平衡处理基线跑通只是及格线。矿车金属反光、人员被遮挡、井下低照度这三个问题会让默认配置的模型在实际场景里翻车。这一章讲怎么针对性调。4.1 锚框重聚类矿车宽高比和通用锚框差多少YOLOv8 虽然是无锚框anchor-free架构但检测头的初始先验仍受数据分布影响。矿车在轨道上通常是横向长条宽高比可能到 3:1 甚至 4:1而通用数据集锚框偏正方形。用脚本统计自己数据的宽高比分布import os ratios [] for fname in os.listdir(labels/train): if not fname.endswith(.txt): continue with open(os.path.join(labels/train, fname)) as f: for line in f: _, _, _, w, h map(float, line.split()) if h 0: ratios.append(w / h) ratios.sort() print(f宽高比中位数: {ratios[len(ratios)//2]:.2f}) print(f宽高比 90 分位: {ratios[int(len(ratios)*0.9)]:.2f})如果中位数明显大于 1.5说明目标偏宽训练时可以适当增大imgsz的宽度方向感受野或者用mosaic增强时注意别把矿车裁得太碎。常见做法是保持默认增强但在data.yaml同级加一个hyp.yaml覆盖部分参数比如把mosaic概率从 1.0 降到 0.5避免小目标被过度拼接。4.2 数据增强井下低照度该用哪几种别乱开ultralytics默认开启mosaic、hsv_h、hsv_s、hsv_v、flipud、fliplr。井下场景我一般这样调hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 0.0 translate: 0.1 scale: 0.5 shear: 0.0 perspective: 0.0 flipud: 0.0 fliplr: 0.5 mosaic: 0.5 mixup: 0.0hsv_v调到 0.4 是模拟井下明暗变化flipud设 0 是因为井下场景上下翻转不合理轨道不会在天上fliplr保留 0.5 做左右镜像。mosaic降到 0.5 是防止矿车被拼接到不相关背景里导致模型学到错误上下文。注意增强不是越多越好开错增强等于给模型喂噪声。4.3 类别不平衡用 copy-paste 补矿车还是调损失权重如果统计发现矿车框数远少于人员两条路一是对矿车做 copy-paste 增强把矿车实例抠出来贴到不同背景二是用cls_pw给类别加权。YOLOv8 没有直接暴露类别权重参数常见做法是在data.yaml里复制矿车样本路径或者用sampler重采样。更简单的是在训练时用fraction参数控制采样比例但会丢数据。我一般先试 copy-paste用albumentations写个离线增强脚本把矿车样本扩到和人员同一量级再重新训练。踩坑记录copy-paste 时如果贴图边缘没做羽化模型会学到硬边伪影验证集看着好实拍全挂。5. 避坑与排查训练矿车人员检测最常见的 5 个翻车现场这一章全是实际调过的坑每条按现象、原因、解决写。现象一训练 loss 正常下降但验证集 mAP 一直是 0。原因通常是data.yaml里val路径写错或者验证集标签目录名和图片目录名不匹配比如images/val对应labels/val但实际是labels/val2017。解决用yolo detect val data...单独跑验证看报错信息里找不找得到标签文件找不到就改路径。现象二模型把矿车全判成 person混淆矩阵一边倒。原因是两类目标在低分辨率下纹理接近且人员样本远多于矿车。解决提高imgsz到 960给矿车类做 copy-paste 增强或者在推理时对minecar类单独调低置信度阈值。现象三训练到一半显存爆了CUDA out of memory。原因可能是batch设太大或者workers太多导致内存泄漏。解决先把batch减半再把workers降到 2用nvidia-smi监控显存。如果还爆检查是不是开了cacheTrue把整个数据集缓存到内存。现象四推理时框位置对但类别置信度极低0.1。原因是训练时cls_loss权重被box_loss压制或者标签里类别 id 写成了浮点数如0.0而不是0。解决检查标签第一列是不是整数训练时适当提高cls损失增益YOLOv8 里通过hyp.yaml的cls参数调。现象五换到新矿井实拍模型完全失效。原因是训练集背景单一模型过拟合到特定光照和轨道纹理。解决收集新场景的未标注图片用yolo detect predict跑一遍把高置信度误检和漏检的图挑出来人工标注做增量训练。后悔药如果一开始就留了 10% 的跨场景验证集这个问题早就能发现。6. 从能跑到能用导出 ONNX、量化与边缘部署的验证技巧训练出best.pt只是实验室成果真正要装到电机车上跑得考虑推理速度和部署环境。这一章讲导出和验证的具体操作。6.1 导出 ONNX 并在 CPU 上验证一致性yolo export modelruns/minecar/baseline/weights/best.pt formatonnx imgsz640 opset12 simplifyTrueopset12兼容性最好simplifyTrue会做图优化。导出后用onnxruntime跑一张图和 PyTorch 输出对比import onnxruntime as ort import numpy as np import cv2 sess ort.InferenceSession(best.onnx) img cv2.imread(test.jpg) img cv2.resize(img, (640, 640)) img img[:, :, ::-1].transpose(2, 0, 1)[None].astype(np.float32) / 255.0 out sess.run(None, {sess.get_inputs()[0].name: img}) print(ONNX 输出形状:, out[0].shape)如果输出形状和 PyTorch 一致通常是[1, 6, 8400]6 是xywhconfcls说明导出成功。参数说明imgsz必须和训练时一致否则框会偏移。6.2 INT8 量化校准集怎么选掉点多少算正常边缘设备上 FP32 太慢一般做 INT8 量化。ONNX Runtime 的量化工具需要校准集from onnxruntime.quantization import quantize_static, CalibrationDataReader class MinecarCalib(CalibrationDataReader): def __init__(self, img_dir, size640): self.files [os.path.join(img_dir, f) for f in os.listdir(img_dir) if f.endswith(.jpg)] self.size size self.idx 0 def get_next(self): if self.idx len(self.files): return None img cv2.imread(self.files[self.idx]) img cv2.resize(img, (self.size, self.size)) img img[:, :, ::-1].transpose(2, 0, 1)[None].astype(np.float32) / 255.0 self.idx 1 return {images: img} quantize_static(best.onnx, best_int8.onnx, MinecarCalib(calib_images))校准集选 100~200 张有代表性的图覆盖不同光照和遮挡。量化后 mAP 掉 1~3 个点算正常掉超过 5 个点说明校准集分布不对重新选。注意量化后的模型在 AGX Orin 上要用 TensorRT 再跑一遍ONNX Runtime 的 INT8 和 TensorRT 的 INT8 精度不完全一样。6.3 一个验证技巧用视频抽帧做时序一致性检查单张图 mAP 高不代表视频里能用。我习惯把实拍视频抽帧逐帧推理后看同一个矿车的框是否跳变ffmpeg -i minecar_test.mp4 -vf fps5 frames/%04d.jpg yolo detect predict modelbest_int8.onnx sourceframes/ conf0.3 save_txtTrue然后写脚本对比相邻帧的框中心点位移如果同一目标在两帧间跳超过 50 像素说明模型不稳定需要加跟踪算法如 ByteTrack做平滑。这个技巧帮我省过好几次返工——视频里框乱跳装到车上司机根本没法看。最后说个习惯每次训完模型我都会把best.pt、data.yaml、训练命令和results.csv一起打包存档命名带日期和场景。井下项目迭代慢半年后回头查某个版本为什么效果好没有这些记录就是黑匣子。希望帮到你。本文还有配套的精品资源点击获取