尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

基于VisDrone的农业机械目标检测:YOLO格式转换与训练实战

基于VisDrone的农业机械目标检测:YOLO格式转换与训练实战 简介这份资源是面向无人机俯视视角的农场场景目标检测数据集适合从事农业智能化、无人机巡检或目标检测算法实践的开发者与研究者使用可解决农场中车辆、农机与行人识别任务缺乏高质量标注数据的问题。数据集包含1000余张图像压缩包共2000个文件其中497张jpg为无人机航拍原图1502个txt为对应的YOLO格式标注文件另有1个yaml配置文件整体约522.36MB。目录已按train、valid、test划分完毕data.yaml中定义car、people、tractor、van四类目标yolov5、yolov7、yolov8等主流框架可直接加载训练省去自行整理与转换格式的步骤。目前已有452人学习下载配套的检测结果与数据集说明可参考作者博文便于快速验证模型效果并复现实验流程适合作为农业场景目标检测的入门与进阶训练素材。1. 农场里的农机检测VisDrone 数据集为什么值得单独拎出来做去年帮一个做智慧农业的朋友调无人机巡田的检测模型他一开始图省事直接拿 COCO 预训练的 YOLO 权重去跑农田航拍图结果拖拉机、收割机、旋耕机全被识别成 truck、car甚至有一台停在田埂上的联合收割机被框成了 bus。问题不在模型在数据分布——COCO 里根本没有俯视角度的农业机械样本模型没见过这个视角下的目标形态。这就是 VisDrone 这类无人机视角数据集的价值所在它天然是俯视、小目标、密集场景和农场航拍巡检的成像条件高度重合。VisDrone 本身是无人机视觉领域被引用最多的公开数据集之一原始任务覆盖目标检测、跟踪、计数标注类别以人、车、自行车为主。而「VisDrone-农场中农业机械目标检测数据集-yolo」这个标题本质是在 VisDrone 的采集风格和标注体系上把类别体系替换或扩展成农业机械——拖拉机、收割机、插秧机、旋耕机、农用三轮、灌溉设备等并整理成 YOLO 训练所需的 txt 标注格式。它解决的核心问题是你不需要自己飞几百架次去采集和标注就能拿到一批俯视视角、带边界框、可直接喂给 YOLOv5/v8/v11 的农机检测数据。适合谁用三类人最直接一是做农业无人机巡检、需要快速验证检测可行性的算法工程师二是拿这个数据集做课程设计或毕设、想跑通完整 YOLO 训练链路的学生三是已经在做农机调度、想用检测结果做作业面积统计的落地团队。如果你手上只有几十张自己拍的图想先验证「俯视农机检测到底能不能做」这个数据集就是最省时间的起点。下面从数据格式、环境搭建、训练调参到踩坑一步步拆开讲。2. 从 VisDrone 原始标注到 YOLO txt格式转换与目录组织2.1 先搞清楚 VisDrone 标注和 YOLO 标注的差异VisDrone 原始检测标注是单文件 CSV 风格每行一个目标字段顺序是bbox_left, bbox_top, bbox_width, bbox_height, score, object_category, truncation, occlusion。坐标是左上角加宽高的绝对像素值类别是数字编号。而 YOLO 要的是每张图一个.txt每行class_id x_center y_center width height且后四个值全部归一化到 0~1。这两个体系之间差了三件事坐标原点表达方式、是否归一化、类别编号映射。转换脚本写错任何一处训练时 loss 会正常下降但框全偏这是最常见的翻车点。农业机械版本的数据集通常已经把类别重映射过比如 0 代表 tractor、1 代表 harvester、2 代表 transplanter。你要做的第一件事是确认classes.txt或data.yaml里的类别顺序别想当然按字母序排。2.2 转换脚本把 VisDrone 标注转成 YOLO txt下面这段脚本处理的是「每张图对应一个 VisDrone 标注文件」的常见组织方式如果你的数据集是单个大 CSV把读取部分换成按文件名分组即可。import os import cv2 # 类别映射VisDrone 原始类别 - 农业机械自定义类别 # 这里假设数据集已给出农机类别编号按实际 classes.txt 修改 CATEGORY_MAP {0: 0, 1: 1, 2: 2} # 示例tractor/harvester/transplanter def convert_one(anno_path, img_path, out_path): img cv2.imread(img_path) if img is None: return # 图片损坏或路径错误跳过 h, w img.shape[:2] lines [] with open(anno_path, r) as f: for row in f: parts row.strip().split(,) if len(parts) 6: continue x, y, bw, bh map(float, parts[:4]) cat int(parts[5]) if cat not in CATEGORY_MAP: continue # 忽略不需要的类别 # 过滤无效框宽高为 0 或越界 if bw 0 or bh 0: continue # 转中心点并归一化 cx (x bw / 2.0) / w cy (y bh / 2.0) / h nw bw / w nh bh / h # 裁剪到 [0,1]防止浮点误差越界 cx, cy min(max(cx, 0), 1), min(max(cy, 0), 1) nw, nh min(max(nw, 0), 1), min(max(nh, 0), 1) lines.append(f{CATEGORY_MAP[cat]} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}) with open(out_path, w) as f: f.write(\n.join(lines)) if __name__ __main__: anno_dir VisDrone/annotations img_dir VisDrone/images out_dir VisDrone/labels os.makedirs(out_dir, exist_okTrue) for name in os.listdir(anno_dir): stem os.path.splitext(name)[0] img_path os.path.join(img_dir, stem .jpg) if not os.path.exists(img_path): continue convert_one(os.path.join(anno_dir, name), img_path, os.path.join(out_dir, stem .txt))逻辑说明脚本先读图拿真实宽高因为归一化必须基于原图尺寸不能凭标注文件里的最大值猜。CATEGORY_MAP是唯一需要你手动对齐的地方映射错了类别全乱。归一化后做了一次min(max())裁剪是因为 VisDrone 里存在少量框超出图像边界的标注不裁剪会让 YOLO 在训练时产生大于 1 的坐标触发警告甚至 NaN。参数上:.6f保留六位小数足够YOLO 官方也是这个精度。2.3 目录结构YOLO 只认这一种排布转换完必须按 YOLO 的约定组织目录否则训练脚本找不到标签。标准结构如下dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml内容path: ./dataset train: images/train val: images/val nc: 3 names: [tractor, harvester, transplanter]注意nc必须等于names长度且和转换脚本里CATEGORY_MAP的值域一致。我见过有人nc写 3 但类别编号从 1 开始结果第 0 类永远学不到训练完混淆矩阵第一行全空——这就是编号没从 0 开始的锅。3. 用 YOLOv8 在本地跑通农机检测训练环境、命令与参数3.1 环境搭建别在 CUDA 版本上浪费时间YOLOv8 走 ultralytics 包环境比早年 YOLOv5 干净很多。我的习惯是 conda 建一个独立环境Python 3.10然后按显卡驱动装对应 CUDA 的 PyTorch。这里有个血泪经验不要一上来就装最新版 torch先nvidia-smi看驱动支持的最高 CUDA 版本再去 PyTorch 官网找对应命令。驱动版本低却硬装高 CUDA 的 torch会报CUDA driver version is insufficient这个报错和数据集、代码都没关系纯环境问题。conda create -n agri_yolo python3.10 -y conda activate agri_yolo # 按 nvidia-smi 结果选择下面以 CUDA 11.8 为例 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics opencv-python装完验证一句yolo checks它会打印 torch 版本、CUDA 是否可用、GPU 型号。如果CUDA available是 False先解决环境再谈训练别急着跑。3.2 训练命令与关键参数怎么设最小可跑命令yolo detect train \ datadataset/data.yaml \ modelyolov8n.pt \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/agri \ nameexp1参数逐个说清楚。modelyolov8n.pt是 nano 版预训练权重农机检测如果类别少、数据量在几千张级别n 版先跑通最划算别一上来上 x 版显存和时间都吃不消。imgsz640是输入分辨率VisDrone 风格的数据小目标多如果你发现小农机漏检严重可以提到 1024但显存占用会翻倍batch 要相应降到 8 或 4。batch16在 8G 显存上跑 640 分辨率基本安全12G 以上可以上 32。device0指定第一块卡多卡用device0,1。训练过程中重点盯三个输出box_loss、cls_loss、mAP50。box_loss 前期快速下降是正常的如果它一直不降八成是标注格式错了cls_loss 震荡大说明类别不平衡或学习率偏高mAP50 在 30 个 epoch 后还没起来先回去查 data.yaml 路径和标签是否一一对应。3.3 训练完怎么验证混淆矩阵和预测可视化训练结束会在runs/agri/exp1/下生成confusion_matrix.png、results.png、weights/best.pt。混淆矩阵是判断类别混淆的第一手材料——如果 tractor 大量被预测成 harvester说明这两类在俯视角度下形态太像需要补样本或做类别合并。用 best.pt 跑单张预测yolo detect predict \ modelruns/agri/exp1/weights/best.pt \ sourcetest_images/ \ conf0.25 \ saveTrueconf0.25是置信度阈值农机检测场景我一般从 0.25 起调漏检多就降到 0.15误检多就提到 0.4。预测结果图会存到runs/detect/predict/肉眼过一遍比看数字更直观尤其是小目标密集的田块。4. 农机检测训练避坑5 个真实踩过的坑4.1 现象loss 正常下降但框全部偏移原因归一化时用了错误的宽高基准比如拿标注文件里的最大坐标当图像尺寸而不是真实读图。VisDrone 图像分辨率不统一猜尺寸必错。解决转换脚本里强制cv2.imread拿shape拿不到图的样本直接跳过不要用默认值兜底。4.2 现象训练到一半报 NaNloss 变 inf原因标签里存在坐标大于 1 或小于 0 的框或者宽高为负。VisDrone 原始标注有少量越界框直接转就会带进来。解决转换时做min(max())裁剪并过滤bw0 or bh0的行。已经训到一半才发现的用脚本扫一遍 labels 目录把越界行删掉重训。4.3 现象mAP 一直卡在 0.1 以下上不去原因data.yaml里nc和实际类别数不一致或者names顺序和标签里的 class_id 对不上。YOLO 不会报错只会默默学错。解决写个脚本统计所有 label 文件里出现过的 class_id 最大值和nc对比不一致就是映射错了。4.4 现象小农机漏检严重大农机框得挺好原因输入分辨率太低小目标在 640 下只剩几个像素。VisDrone 本身小目标占比高农机在航拍图里更小。解决把imgsz提到 1024 或 1280同时开mosaic增强YOLOv8 默认开batch 相应下调。如果显存不够用yolov8s.pt换掉 n 版特征提取能力更强。4.5 现象验证集 mAP 很高实际部署误检一堆原因训练集和验证集来自同一批航拍、同一光照条件模型过拟合了采集环境。农田场景光照、季节、机型差异极大。解决划分验证集时按采集批次或地点分不要随机分。有条件的话留一个完全不同地块的图做测试集那个数字才是真实水平。5. 进阶用 VisDrone 预训练权重做迁移把农机检测 mAP 再抬一截如果你手上除了这个农机数据集还有一批无标注的农田航拍图最划算的进阶做法是先拿 VisDrone 官方检测权重做一次领域预训练再在农机标注数据上微调。VisDrone 官方权重在无人机视角的小目标特征上已经学得比较充分直接迁移比从 COCO 权重起步收敛快得多尤其在小目标召回上差距明显。具体操作分两步。第一步用 VisDrone 原始类别权重在你的无标注农田图上做自监督式的伪标签训练或者更简单——直接拿 VisDrone 权重当初始化在农机数据上微调把model换成 VisDrone 的.ptyolo detect train \ datadataset/data.yaml \ modelvisdrone_pretrained.pt \ epochs80 \ imgsz1024 \ batch8 \ lr00.001 \ device0注意lr0要从默认的 0.01 降到 0.001 左右因为预训练权重已经接近收敛学习率太大会把学到的特征冲掉这是迁移学习里最常见的后悔药场景。第二步训练完对比两次的results.png重点看小目标那一档的 mAP。我实测下来VisDrone 迁移比 COCO 迁移在农机小目标上通常能高 3~8 个点具体取决于你的数据量和农机与 VisDrone 原始类别的形态接近程度。再补一个验证技巧把best.pt导出成 ONNX用onnxruntime跑一遍和 PyTorch 结果对比确认导出没掉精度再上边缘设备。导出命令yolo export modelruns/agri/exp1/weights/best.pt formatonnx imgsz1024导出后拿同一张图分别用 PyTorch 和 ONNX 推理框的坐标差在 1~2 像素内算正常差得多说明导出时的imgsz和训练不一致。我自己踩过的坑是训练用 1024、导出忘了写imgsz默认成 640结果边缘设备上小目标全丢查了半天才想起来是导出参数没对齐。做检测这行参数对齐比模型选型更影响最终效果养成每次导出都核对imgsz、conf、iou的习惯能省掉大量返工。希望帮到你。本文还有配套的精品资源点击获取
返回列表