ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YOLOv8的杂草检测系统实战:从训练到部署

基于YOLOv8的杂草检测系统实战:从训练到部署 简介面向农业智能化和计算机视觉入门开发者这份基于Python与YOLOv8的杂草检测系统源码包提供了从数据准备、模型训练、验证评估到推理部署的完整工程实现。项目采用collagefilter30originales Dataset 5数据集包含2427张标注图像覆盖作物与杂草两类目标通过YOLOv8网络训练得到检测模型并配套train.py、val.py、predict.py与ui.py脚本可分别完成训练启动、精度验证、单张/批量预测以及图形界面交互流程清晰且易于复现。压缩包共24个文件以19张可视化图表、4个Python程序文件和1个说明文档为主整体大小仅5.5MB目录精简但要素齐全。目前已有75人学习下载参考README并结合train.py中的参数配置可快速搭建自己的检测流程对论文复现、课程设计或农业检测方向的毕业设计而言是一套低成本、可扩展的基线项目。通过ui.py还能直观体验模型输出便于理解检测框与置信度等关键概念。 收到一个很有意思的项目包基于Python和YOLOv8的杂草检测系统还带了完整源码。这几年做视觉落地的项目杂草识别算是农业AI里需求最明确、落地性价比最高的方向之一但真正把系统做完整的人不多。这套系统核心是拿YOLOv8做目标检测在田间环境下识别杂草、定位杂草位置为后续精准喷洒或机械除草提供坐标依据。它适合正在学YOLO系列、想找个实战项目练手的同学也适合做智慧农业、农机自动化的工程师拿来当基线。这篇文章不搞那种下载-解压-运行-完事的糊弄教程我们把整个系统拆开为什么选YOLOv8数据怎么准备训练怎么调参源码怎么组织部署会遇到哪些坑——逐个环节过一遍。1. 为什么选YOLOv8杂草检测的选型逻辑1.1 杂草检测为什么难传统方案卡在哪田间杂草检测和一般的通用目标检测不太一样它有自己非常刁钻的难点。第一是小目标密集杂草刚出苗的时候可能只有几十个像素而且一平米土地上可能密密麻麻长着几十株普通检测模型很容易漏检。第二是类间相似幼苗期的杂草和作物叶片形态高度相似都是绿色、叶脉纹理接近别说模型人眼都要凑近才能分清。第三是光照和背景干扰大田环境里有阴影、反光、土壤颗粒、碎石、残茬这些都会成为背景噪声。传统方案大多是颜色分割加形态学处理比如基于超绿特征ExGExcess Green把绿色植被从土壤背景里分出来再用连通域找杂草轮廓。这类方法在实验室环境下的盆栽实验里效果不错一进大田就崩——光照一变、土壤湿度一变阈值就失效鲁棒性很差。后来有人用传统机器学习方法比如提取HOG特征、LBP特征丢进SVM分类器但特征需要人工设计泛化能力也有限。深度学习目标检测模型火起来以后这类问题才真正有了靠谱的解法而YOLO系列因为速度和精度平衡得好成了农业视觉落地的主流选择。1.2 YOLOv8的检测流与部署优势YOLOv8是Ultralytics团队在2023年初发布的版本相比YOLOv5它在网络结构上做了几处明显改动骨干网络换成了C2f模块用更丰富的梯度流提升特征提取能力检测头改成解耦头结构分类和回归分支分开走收敛更快还引入了Anchor-Free机制不再依赖预设锚框简化了训练难度对小目标更友好。这套改动带来的直接收益就是在相同算力下YOLOv8的mAP普遍比YOLOv5高2到4个点推理速度基本持平。选YOLOv8做杂草检测还有个很实在的原因——生态成熟。Ultralytics把训练、验证、导出、部署的链路都打通了一条命令行就能从训练干到导出ONNX对于农业场景这种要快速验证方案的落地场景非常关键。而且它对硬件要求不苛刻一张GTX 1660 Ti这种入门级显卡就能训练小模型Jetson Nano这种边缘设备也能跑推理后期做嵌入式部署不用换模型架构。这些都是我们选型时重点考虑的因素。2. 环境搭建与数据集准备2.1 环境配置6步跑通训练环境这套系统用的是Python生态环境配置本身不复杂但很多新手会卡在版本兼容上。我按实测下来的稳定组合给你列一份参考配置Python 3.9 ~ 3.11 PyTorch 2.1.0 CUDA 11.8NVIDIA显卡环境 ultralytics 8.1.x安装步骤按顺序来每一步做完再进下一步# 1. 创建独立虚拟环境别往base环境里装后面依赖冲突有你受的 conda create -n weed python3.10 conda activate weed # 2. 安装PyTorch从官网复制对应CUDA版本的命令 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 3. 安装ultralytics它会自动带上opencv、numpy等依赖 pip install ultralytics # 4. 验证安装是否成功 python -c from ultralytics import YOLO; print(YOLO.__version__)看到版本号就说明基础环境OK了。这里有个容易踩的坑不要用pip install ultralytics的时候让它自动装一个莫名其妙的PyTorch CPU版本如果你之前用conda装过一次torch后面又被覆盖成CPU版训练慢到你怀疑人生。建议装完ultralytics后马上检查一下python -c import torch; print(torch.cuda.is_available())输出True才说明CUDA可用如果你是纯CPU环境训练后面的参数配置就得多注意建议直接换云端GPU。另外Windows用户如果碰到dll加载失败或者opencv报错大概率是Visual C运行库缺失去微软官网装一下最新版运行库就行。2.2 数据集从哪来公开数据集与自采集标注杂草检测系统能不能干活数据集决定了大半模型反而不是瓶颈。项目里如果自带数据集先用自带的跑通流程如果打算做自己的场景数据集来源一般有两条路第一是公开数据集。农业视觉领域有不少开源数据集可用比如Weed-AI、CottonWeedID这类包含了多种田间杂草的标注图像。用公开数据集的好处是省去标注时间适合先验证方案可行性。第二是自采集加标注。这个过程最花时间但效果最贴近你的实际场景。采集图像时要注意覆盖不同生长阶段幼苗期、分蘖期、不同光照顺光、逆光、阴天、强日照、不同土壤背景。一般来说单个杂草类别至少需要1500到3000个标注实例太少了模型学不到稳定的特征。标注工具推荐LabelImg或X-AnyLabeling前者轻量后者支持半自动标注和SAM辅助分割能省不少工作量。标注时有个细节杂草检测的标注框尽量紧贴叶片边缘不要包进太多背景对于重叠密集的杂草能分开标就分开实在分不开的可以适度省略被严重遮挡的个体。标完之后格式是YOLO的txt格式——每行五个数字类别ID、归一化中心x、归一化中心y、归一化宽、归一化高训练前一定要抽查几个文件确认bbox坐标没有越界或为负。3. 训练配置与超参数调优3.1 data.yaml与模型选型YOLOv8训练前要准备好data.yaml配置文件这是数据集的索引文件训练脚本靠它找到图片和标注。一个标准的杂草检测data.yaml长这样# data.yaml path: D:/weed_detection/dataset # 数据集根目录 train: images/train # 训练集图片目录 val: images/val # 验证集图片目录 nc: 3 # 类别数量 names: [broadleaf_weed, grass_weed, crop] # 类别名称按实际项目调整路径建议用绝对路径尤其Windows环境下相对路径拼接经常出莫名其妙的问题。类别名称顺序必须和标注文件里的类别ID一一对应顺序错了模型训练出来就是张冠李戴。模型尺寸选择方面YOLOv8提供了n/s/m/l/x五个档位显存和精度成正比模型尺寸参数量推理速度显存占用batch8, imgsz640适用场景yolov8n3.2M最快约2GB边缘设备快速试验yolov8s11.2M快约4GB大多数训练入门推荐yolov8m25.9M中等约8GB精度优先的常规场景yolov8l43.7M慢约12GB高精度、大算力yolov8x68.2M最慢约16GB追求极致精度对杂草检测来说除非目标特别小否则不建议一上来就上l或x。实测下来yolov8s在640输入尺寸下已经能取得不错的精度训练速度也要快得多。迭代试验用s起步效果满意再换m提精度这是性价比最高的路线。3.2 训练命令与超参数的心得基础训练命令只需要一行yolo detect train datadata.yaml modelyolov8s.pt epochs150 imgsz640 batch8 projectruns nameweed_exp1这里有个小知识点modelyolov8s.pt会自动从GitHub下载预训练权重。对杂草检测这种场景强烈建议用预训练权重做迁移学习而不是从随机初始化开始训。COCO数据集上学到的底层特征边缘、纹理、颜色对植物叶片同样有效迁移学习能让收敛速度提升好几倍最终精度也更高。超参数方面我按优先级排序给你几个实测经验imgsz训练分辨率。硬件允许的情况下尽量用640或更高杂草这种密集小目标对分辨率敏感用320训练会漏检严重。epochs建议从150起步配合早停在验证集loss不再下降时自动停止。不要盲目训300轮过拟合风险高。batch显存不够就调小不要硬顶。batch8跑不动就换4梯度累积也能缓解。如果batch2还爆显存直接换更小的模型或者降imgsz。optimizer默认的SGD适合大多数场景AdamW收敛更快但最终精度略低经验法是先用SGD训150轮训完看结果再决定要不要换。训练过程会生成runs/detect/weed_exp1/目录里面有weights/best.pt和weights/last.pt。best.pt是验证集上表现最好的权重实际使用选它别误用了last.pt——那是最后一轮的权重未必是最优的。另外训练日志里的results.csv保存了每个epoch的指标曲线数据可以直接用pandas读取画图比截图保存命令行输出靠谱得多。3.3 数据增强让模型扛住真实农田农业场景的数据增强是最值得花时间的调参方向。YOLOv8默认开了不少增强策略但默认值是在COCO这种通用数据集上调出来的直接用于杂草检测会水土不服。几个关键参数我贴一下# yolo配置里的增强参数在训练命令里覆盖 hsv_h: 0.02 # 色调扰动杂草对颜色敏感不宜太大 hsv_s: 0.05 # 饱和度扰动 hsv_v: 0.3 # 亮度扰动模拟早晚不同光照 degrees: 10.0 # 旋转角度田中杂草角度随机但不能太大否则叶片形态失真 translate: 0.1 # 平移扰动 scale: 0.4 # 缩放扰动模拟不同拍摄距离 fliplr: 0.5 # 水平翻转注意如果杂草有左右不对称形态别开太大 mosaic: 1.0 # Mosaic增强四个图拼一张对小目标检测提升明显 mixup: 0.1 # MixUp增强试试0.1太高会让模型混淆实测过一个明显的例子增强关闭时模型mAP只有72开了适度增强后直接跳到81这里面mosaic的贡献最大。但注意mosaic在训练最后10轮建议关掉因为拼接图像和真实分布有差异全程开着会让模型对真实尺度感知偏差。可以用ultralytics的分阶段回调来实现或者简单粗暴一点训练80%轮数后用关闭mosaic的命令再来一次微调。4. 源码工程结构与核心模块解析4.1 工程目录一图看懂拿到源码包解压后的第一件事先摸底目录结构。这套系统的工程组织是典型的训练-推理分离设计我整理一份常见结构给你对照参考weed_detection/ ├── data/ # 数据集目录 │ ├── images/ │ │ ├── train/ │ │ └── val/ │ ├── labels/ │ │ ├── train/ │ │ └── val/ │ └── data.yaml # 数据配置 ├── models/ # 预训练权重存放目录 │ └── yolov8s.pt ├── utils/ │ ├── dataset_tools.py # 数据集划分、格式转换工具 │ ├── visualization.py # 检测结果可视化、标注检查 │ └── metrics.py # 准确率、召回率、F1统计 ├── train.py # 训练入口 ├── detect.py # 图片/视频推理入口 ├── predict_web.py # Web接口推理Flask ├── requirements.txt # 依赖清单 └── README.md # 使用说明这种结构让训练和推理解耦utils里放了数据工具和可视化工具换数据集的时候不需要动主脚本改data.yaml就行。拿到源码先跑通README里的示例命令确认环境和权重没问题再进代码二次开发。4.2 训练脚本与推理脚本的调用关系训练脚本train.py核心就是封装了ultralytics的API但和一行命令不同的是很多项目会在里面加入迁移学习的冻结策略——前50轮冻结骨干网络只训练检测头后面再解冻全模型微调。这在数据量不够大的杂草数据集上效果明显能有效防止过拟合。代码大概长这样# train.py 关键片段 from ultralytics import YOLO model YOLO(models/yolov8s.pt) # 冻结前10层骨干网只训练检测头 for name, param in model.named_parameters(): if model.0 in name or model.1 in name: param.requires_grad False model.train( datadata/data.yaml, epochs150, imgsz640, batch8, projectruns, nameweed_train, patience30, )推理脚本detect.py做的事情主要是三件加载模型、读取输入、后处理输出。多类别杂草检测的推理结果是一个个边界框加上类别置信度detect.py里通过置信度阈值和NMS去重把置信度低于阈值的结果过滤掉再输出检测结果。这里埋了个坑置信度阈值设太低背景误检会猛增设太高低置信度的杂草漏检。实际操作中阈值放在0.35到0.5之间调先跑一批真实图片看效果再定。4.3 从检测结果到喷洒坐标很多用了这套系统的人只看检测框就完事了但真正的自动化作业系统必须把检测框转成执行机构的动作指令。源码里通常会有一个坐标换算模块把像素坐标映射到喷雾器的执行坐标系。核心思路是标定——先拍一张标定板建立像素到实际物理距离的映射关系然后根据相机安装高度和俯仰角算出每个检测框中心的实际位置# 坐标换算伪代码像素坐标 - 相机坐标 - 世界坐标 import numpy as np def pixel_to_world(bbox, K, R, T): u, v (bbox[0] bbox[2]) / 2, (bbox[1] bbox[3]) / 2 # 检测框中心 uv_homogeneous np.array([[u], [v], [1]]) cam_coords np.linalg.inv(K) uv_homogeneous # 相机坐标 cam_coords * Z_c # Z_c是目标点在相机坐标系下的深度通过相机安装高度和地面方程求 world_coords R cam_coords T # 世界坐标 return world_coords[0][0], world_coords[1][0]这个模块在纯软件项目里可能只是简单实现但到实际机器人平台标定精度会直接影响喷洒覆盖率。我自己的经验是相机离地面越近像素误差换算到物理距离的误差越小倾斜安装的相机比垂直安装的覆盖范围大但标定难度也更高。5. 推理部署与真实场景应用5.1 单张图片、视频流、摄像头三种推理推理是这套系统另一个核心入口源码里一般会提供三种模式的调用方式。单张图片检测最适合验证模型效果命令行直接出结果yolo detect predict modelweights/best.pt sourcetest_images/001.jpg conf0.35 imgsz640 saveTrue视频流和摄像头检测的代码逻辑类似predict方法传入视频路径或者摄像头设备号就行。源码里比较常见的做法是把ultralytics的predict封装成一个生成器逐帧处理视频流。实测过程中要注意用摄像头实时检测时视频帧率要和模型推理速度匹配。如果显卡推理一张图要50毫秒那实际处理上限也就20fps超过这个帧率就该考虑换更小的模型或降低输入分辨率。在Jetson Nano这类边缘设备上yolov8n用FP16推理可以跑到25fps左右yolov8s就只有10fps上下。5.2 换一种部署形态ONNX与嵌入式这套系统如果只停留在PC端跑那还只是个demo真正要装机下地必须做模型转换。ultralytics提供了非常方便的一键导出yolo export modelweights/best.pt formatonnx imgsz640 opset12导出ONNX后可以用ONNX Runtime做CPU推理摆脱对PyTorch的依赖部署体积小很多。如果想要更高的推理速度NVIDIA平台可以导出TensorRT引擎Jetson系列设备上性能提升接近3倍。这里有一个我踩过多次的坑ONNX导出时输入尺寸要固定。如果你导出的时候写imgsz640那推理时只能使用640x640的输入换分辨率要重新导出。实际部署时最好根据你的相机分辨率和视野需求算好一个固定尺寸再导出不要在推理阶段动态改。比如相机拍摄1920x1080的图检测时直接resize到640x640会让小目标更小建议先用1280x1280导出或者用更大输入尺寸的模型代价是推理时间增加。杂草检测里很多小目标输入尺寸太小真的会漏检。5.3 和硬件联动变量喷洒与机械除草这套系统真正落地的时候输出端通常接两类设备。一类是变量喷洒系统控制器根据杂草密度检测结果调节喷头开度和流量做到哪儿有草喷哪儿。另一类是机械除草机器人机械臂带动除草铲或激光模块移动到杂草坐标执行物理清除。这两类都依赖检测系统的坐标输出和置信度输出所以源码里通常会有把检测结果格式化成JSON的模块def detection_to_json(results, image_id): output [] for result in results: for box in result.boxes: output.append({ image_id: image_id, category_id: int(box.cls[0]), category_name: result.names[int(box.cls[0])], bbox: box.xyxy[0].tolist(), # 边界框 confidence: round(float(box.conf[0]), 4), center_x_norm: round((box.xyxy[0][0] box.xyxy[0][2]) / 2 / result.orig_shape[1], 4), center_y_norm: round((box.xyxy[0][1] box.xyxy[0][3]) / 2 / result.orig_shape[0], 4) }) return outputJSON格式的好处是解耦下游不管接PLC还是串口大家约定好JSON协议就能对接。如果是项目交付我会建议在源码基础上写一个interface/模块把检测输出统一成这个格式再走MQTT或者串口发给执行机构这样前后端联调时不用反复改模型代码。6. 常见问题排查与避坑实录6.1 显存不足与训练卡死训练过程中报CUDA out of memory是最常见的问题尤其在batch调大的时候。这不是代码问题是显存超了。处理办法按优先级排列先把batch减半再把imgsz降一档还不行就换更小的模型。如果连yolov8n都跑不动就该换显卡或者上云GPU了。另一个容易忽视的因素是显存碎片化多次训练中断重启后显存里残留了上次分配的缓存用nvidia-smi确认没有残留进程后再重新训练。训练卡死则一般是数据加载瓶颈特别是机械硬盘上直接读几万张小图dataloader的worker进程会卡在I/O上。解决方法是把数据集拷到SSD上或者加cacheTrue参数让数据集预加载到内存速度立竿见影。6.2 mAP低、过拟合、漏检mAP低先别急着调参按照数据-标注-模型-超参的顺序排查。第一看训练集里有没有大量标错的框用utils/visualization.py把标注画出来抽查第二看是不是类别不均衡比如某个杂草类别只有几十个实例模型根本学不到特征第三看模型是否过拟合训练loss降了但验证loss升高优先增加数据增强和正则化第四才轮得到调超参。漏检小目标杂草这个老大难问题有三个实际有效的办法。一是提高输入分辨率从640提到960或者1280对小目标的效果提升比换大模型更明显二是做测试时增强TTA虽然推理速度慢但能多召回一些低置信度目标三是改进网络结构在源码的模型定义中加入注意力机制比如引入多头自注意力模块MHSA来增强小目标的特征表达这类改进在热词里也经常被讨论。不过要提醒的是结构改进得跟着实验走别盲目叠加模块每一个改动单独做对比实验哪个涨点就留哪个。6.3 项目后续还能怎么扩展源码包跑通只是起点我建议拿到这套系统后按自己的场景做三个扩展方向。第一个是多尺度检测能力当前系统是固定输入分辨率如果后续要用在不同高度的无人机和地面小车上可以加一个自适应分辨率模块根据图像内容自动选择推理ruler。第二个是增量训练脚本农田是动态变化的新地块新草种不断出现总不能每次重新标注几万张图再从头训。更好的做法是把新采集的数据整理成增量集用已有权重做short cut微调代码里加一个train_incremental.py脚本加载best.pt继续训练。第三个是轻量化部署把所有推理逻辑写进一个独立的类用TensorRT加速这样以后要移植到Jetson或树莓派都不用改上层逻辑。最后再分享一个体会杂草检测这类农业AI项目技术指标mAP很重要但现场跑得稳更重要。训练出的best.pt在测试集上mAP可能有90但到了真实田间杂草密度高、遮挡严重、天气变化实际效果经常打个七八折。源码系统的好处是方便二次开发所以拿到手之后花一周时间收集一批自己场景的现场图片用这套代码做迁移微调远比你直接拿通用模型去现场碰运气强。说到底这套系统的价值不只是帮你把模型训出来而是给了你一条从数据到部署的完整路径顺着这条路径走杂草检测才能从跑通demo变成真正能用。本文还有配套的精品资源点击获取
返回列表