做农业目标检测这一行,最磨人的不是模型本身,而是“数据从哪里来、标注怎么做、模型落地后用户怎么用”。之前我做过一个基于YOLOv11的生菜生长周期检测系统,从数据集采集、训练,到把模型封装成带登录注册界面的桌面应用,完整走了一遍。这个项目不算复杂,但牵扯的环节特别多——数据集质量、训练策略、界面集成的坑、模型部署的细节,每一样都会实打实影响最终效果。这篇文章把整套流程拆开讲清楚,项目源码和模型也都整理好了,希望能给正在做V3系检测器落地、或者想用YOLO做农业场景识别的人一点参考。
1. 项目整体拆解:生菜生长周期检测到底在解决什么问题
1.1 场景需求分析:为什么要单独做一个生菜识别系统
生菜是叶菜里种植周期比较短的作物,从播种到采收大约40到60天。这个阶段里,植株的状态判断直接影响浇灌策略、施肥方案和采收时机。传统做法是种植户自己下地观察,靠经验判断“现在该不该追肥了”“这批能不能采了”。这个方式有问题——大田种植面积上来以后,人不可能每天把所有区域都看一遍,而且不同人判断标准不一样,同一个生长阶段,有人觉得能采了,有人觉得还差两天。
生菜生长周期检测系统的核心价值,就是把“人眼判断”变成“模型判断”。摄像机或者手机拍一张图,模型自动告诉你这是苗期、生长期、结球期还是成熟期。再往后可以接自动灌溉、智能采收机器人,也可以做产量预测。我这次做的时候,需求方其实只提了一个要求:能准确区分四个生长阶段,并且给一个能操作的界面。但真正做起来才发现,需求简短的背后,数据和工程的坑一点都不少。
用YOLOv11而不是其它版本,主要考虑三点。第一是精度和速度的平衡。生菜检测不需要识别几百个类目,就四个生长阶段,但需要部署在普通设备上实时跑,YOLOv11在同样算力下比v5、v8能多拿几个点的mAP,而且推理帧率不掉。第二是训练和部署生态成熟。YOLOv11的文档、权重、工具链都很完整,遇到问题网上有大量踩坑记录,对做落地项目很重要。第三是这个项目后期要接摄像头实时流,YOLOv11对视频流的处理更稳定,检测头设计对小目标的响应也更好。
1.2 系统模块概览:从数据到模型的完整链路
这套系统从功能上可以分为四个模块:数据模块、训练模块、推理服务模块、UI交互模块。
数据模块负责采集生菜图片、清洗筛选、标注、切分数据集。这个部分听起来最不起眼,但实际占了我整个项目60%的时间。生菜图片不像通用目标检测数据集那样网上随便找就有,需要自己跑大棚、拍实景,甚至是自己种几盆来补数据。
训练模块就是基于YOLOv11的detect任务,配置模型结构、设置超参数、跑训练、看指标曲线、调优。这个模块决定了模型能到什么精度。推理服务模块负责加载训练好的权重,把图像输入转换成检测结果,输出类别、置信度、检测框。UI交互模块是一个Python桌面程序,带登录注册,用户登录后从本地选择图片或打开摄像头,界面左侧显示原图,右侧标记检测框和类别信息,底部显示识别结果和模型运行状态。
这四个模块是串在一起的——数据决定上限,训练逼近上限,推理和UI只是把能力暴露给用户。很多第一次做这类项目的人,容易盯着训练环节调参,却忽略了真正决定成败的数据清洗和标注质量,后面我会展开聊。
2. 数据集构建与标注:决定生菜检测上限的关键环节
2.1 生菜生长周期怎么划分:四阶段定义与类目设置
做检测之前,先把生长周期阶段定义清楚。这个看起来是农业问题,其实是建模问题——类目边界模糊,模型根本学不会,你标注得再辛苦也没有用。
我参考了农业种植规范,结合实地观察把生菜整个生育期归成四类:
| 类别标签 | 中文名称 | 形态特征 | 大约周期 |
|---|---|---|---|
| Seedling | 苗期 | 子叶展开,真叶出现,植株高度小于5cm,叶片稀疏 | 播种后1-15天 |
| Growth | 生长期 | 叶片展开增多,株型向外扩展,莲座叶开始形成 | 播种后15-30天 |
| Heading | 结球期 | 心叶向内卷曲,开始形成松散或紧实的叶球 | 播种后30-45天 |
| Mature | 成熟期 | 叶球紧实,外层叶片完整,达到可采收标准 | 播种后45-60天 |
这里有一个重点:苗期和生长期的边界是最难的。小苗刚出土的时候,和生长初期的形态差异其实很微妙,靠单张图判断经常会有歧义。我处理的办法是放弃了“单一时刻绝对准确”的思路,而是让标注员按照植株的实际状态标,如下图:苗期强调“真叶少、株体小”,生长期强调“莲座叶展开但未包心”,有歧义的图片直接删掉,不强行归类。
2.2 数据采集与清洗:别让脏数据毁了训练
采集方面我和需求方跑了几趟种植基地,用手机和相机在不同光照、不同角度、不同密度下拍了大概2200多张生菜图片。这里有个建议:采集的时候有意识地覆盖“坏天气”和“逆光”条件。因为部署的时候不会每次都是好天气,如果训练集里全是光线充足、顺光拍摄的图,模型一遇到阴天泛化能力立刻下降。
采集回来的图不是拿来就能用的。我做了几轮清洗:
第一步是剔除模糊图片。生菜叶片边缘细节多,一旦画面糊了,标注出来的框边缘不准确,模型会被误导。判断方法很简单,把图片放大到100%看叶脉是否清晰。
第二步是删除目标太小或占比过低的图片。YOLOv11虽然在迭代优化,但训练时如果检测目标只有几十个像素,很难学到有效特征。我控制在“单株生菜在图片中至少占30x30像素以上”,小于这个标准的直接从数据集里去掉。
第三步是处理重复度极高的图。连拍的照片虽然机位略有变化,但背景信息几乎一样,会变成“高相似重复样本”,导致训练集有效信息量被稀释。我把过于相似的图人工抽稀,留下信息增益最大的那些。
清洗完实际保留下来大约1800张图,这个量对四个类别的检测来说不算多,但能用。
2.3 标注规范与工具选型:LYOLO格式的实战经验
标注工具我用的labelimg,它对YOLO格式输出非常友好,导出的是txt文件,每行对应一个目标,格式是“class_id x_center y_center width height”,坐标都是归一化后的相对值。
标注规范必须提前定好,不然返工会让你怀疑人生。我这次定了几条硬规则:
- 检测框贴合植株最外围叶片,不用包括花盆、土壤、水滴这些无关物。
- 重叠严重的植株分开框,但如果一个植株被另一个遮挡超过一半,就只标完整可见的那一株。
- 边界上的植株如果不完整(比如一半被图片边缘裁掉),选择放弃这张图,而不是硬标一个残缺框。
- 同一张图里有多株生菜时全部标出来,不挑着标。
实际操作中有个很不舒服但是很管用的事:四分类任务最容易翻车的就是“生长期”类别标得太含糊。我自己第一批标注的生长期图片就出了不少问题——有的连心叶都开始卷了还在生长期里放着,导致模型训练初期结球期和生长期严重混淆。后来改了策略,生长期只保留“叶片完全展开、株型蓬松、无卷心趋势”的图,宁可数量少一点也不能要边界样本。
标注完成后,我用脚本统计了各类别的样本分布。Seedling大约只有280个目标框,Growth有870个,Heading有650个,Mature有570个。这个分布对模型不友好——YOLO的类别是基于锚框分类的,类别样本不平衡会拉低少数类mAP。我做了两件事:一是对Seedling类别做了4倍增强(上下翻转、左右翻转、HSV扰动、随机小角度旋转),二是训练时给少数类加了类别权重。
数据增强不能瞎做,农业场景有其特殊性。生菜图片的翻转是安全的,因为生菜无论朝哪个方向都一样。但是旋转角度别超过30度——田间生菜有规律朝向,旋转太多反而引入了不真实样本。HSV扰动里,饱和度扰动范围控制在±25%之间,太高会让叶片颜色失真,模型会错误地依赖“颜色深浅”去判断阶段。
数据准备好之后,我按约8:1:1划分训练集、验证集、测试集。一个容易忽略的坑是划分时不能随机乱分。如果同一株生菜的多角度照片既出现在训练集又出现在测试集,模型等于提前见过答案,验证指标虚高。我按“拍摄场景/时间批次”划分,同一个批次进同一边。
3. 模型训练与调优:YOLOv11从零到能用的全过程
3.1 YOLOv11相比以往版本的改进要点
YOLOv11是Ultralytics推出的新版本,相比v8在结构上有几个关键改动:在骨干(C2PSA模块替换原C2f模块)上加了注意力机制,能更好关注目标区域,小目标检测能力提升;Neck部分融合了更多尺度特征,适合目标尺寸差别大的场景——生菜从小苗到成熟期目标跨度非常大,正好吃这个特性;检测头解耦得更好,分类分支和回归分支的梯度干扰被削弱。
不过我要泼一盆冷水:YOLOv11不是无脑比v8强。模型性能提升的前提是训练数据足够丰富、任务本身能受益于更强的骨干。如果数据集只有几百张,v8和v11的差距很小,反而v11训练时间更长。我之所以坚持用v11,主要还是考虑到后续有扩展场景——比如从生菜拓展到其他叶菜、加入病虫害检测,这些任务需要更强的特征提取底座。
3.2 实验环境与训练配置
我的训练环境:Ubuntu系统,显卡算力大约在16GB显存级别,CUDA 11.8,PyTorch 2.1。这套配置对YOLOv11来说算是标准配置,不值得炫耀,但能说明一点:这个项目的训练成本普通人能承担。如果你手头只有8GB显存的显卡,把batch size调到8或者用梯度累积一样能跑,就是耗时翻倍。
关键训练参数如下表:
| 参数 | 设定值 | 说明 |
|---|---|---|
| 输入尺寸 | 640x640 | 兼顾小目标和显存占用 |
| batch size | 16 | 显存范围内尽量大,稳定BN |
| epoch | 200 | 带早停,避免过拟合 |
| 初始学习率 | 0.01 | AdamW优化器默认值偏大时降为0.005 |
| 权重衰减 | 0.0005 | 防止权重过大 |
| 类别权重 | Seedling权重1.5 | 缓解样本不平衡 |
| 增强策略 | 随机翻转/HSV/小角度旋转 | 控制增强幅度 |
训练日志输出那一大堆数据,我最关注的是三个:mAP50、mAP50-95、loss曲线。mAP50是“检测框和真实框的IOU达到0.5就判对”的指标,项目后期只要mAP50过90%,使用体验就很好。mAP50-95对框的精确度要求更高,是研究级指标,但工程落地不用太执着,95指标很难刷,刷高了时间成本也上去了。
loss曲线方面,多数人只看box_loss和cls_loss。box_loss代表检测框回归的准确度,cls_loss代表分类的置信度分配。这两个loss在150epoch后还在缓慢下降,说明模型还在学习,到了170epoch后趋于平台期。我的早停设置在“验证集mAP50连续30个epoch不提升就停”,实际跑到172个epoch就触发了早停。
3.3 训练中遇到的经典问题与调优记录
这次训练我踩了三个比较典型的坑。
第一个是初期分类严重偏向于生长期。看混淆矩阵能发现,只要预测拿不准,模型就倾向输出“Growth”。原因很简单:生长期样本最多,类别分布天然给了它“先验优势”。解决办法是加类别权重之后又衰减了一轮学习率,从0.01降到0.005继续训练了30个epoch,让模型把注意力重新放到少数类上。最终Seedling的recall从71%提到了86%,这个收益非常明显。
第二个问题是结球期和成熟期的混淆。这两个阶段视觉差异在于叶球紧实度,但单张二维图像上判断紧实度并不容易。我的对策有两个:一是在数据层面把“有明显黄色叶边的成熟期”图片增加(生菜成熟时外层叶尖微微泛黄),给模型一个更明确的外部特征;二是对结球期增加俯拍样本,因为紧实的叶球从正上方看,纹理和间隙和松散期差异更大。
第三个问题是小苗目标漏检率偏高。这个不是YOLOv11的缺陷,而是Seedling目标在图片中面积占比太小,特征经过多次下采样后弱化了。除了增强Seedling类样本外,我把输入尺寸从512调整到640,这个改变让小苗漏检率降了好几个点。如果你的显存够,甚至可以用768,但640已经是性价比很高的方案。
3.4 最终模型表现:指标到底怎么样
最终模型在测试集上的数据:
- mAP50: 93.6%
- mAP50-95: 71.2%
- Seedling recall: 86%
- Growth precision: 91.8%
- 单张图片平均推理耗时: 23ms (GPU) / 320ms (纯CPU)
这个指标放到真实农田里能不能用?我的判断是“足够做辅助判断,不够做无人决策”。如果模型输出“Mature”,参考价值已经很高,但最好还是留人工复核环节。生菜成熟晚摘一天、早摘一天,对品质的影响并不大,辅助判断的容错空间是够的。
顺带说一句,导出模型做部署的时候,我用了ONNX格式再转成推理引擎的格式,转换后单图推理耗时进一步压到了8ms左右。如果以后要上边缘设备或者摄像头实时流,转换这一步早晚要做的。
4. UI界面与登录注册:让模型真正变成能用的产品
4.1 界面技术选型:为什么用Python桌面应用
训练好的模型只是模型。给最终用户用,必须有一个图形界面。我之前也纠结过要不要做Web端——用Flask起一个服务,浏览器打开就能用,也不用考虑打包问题。但这个项目的使用场景是大棚监控室的电脑或者单机工作站,网络环境不稳定,而且用户不熟悉浏览器操作和端口配置。用Python桌面应用是更务实的选择。
桌面UI的框架我选了PySide6,也就是Qt for Python。这个框架编译出来的界面原生感不错,集成OpenCV显示图像,调用YOLO模型推理,信号槽机制处理按钮事件非常顺手。另一个备选是Tkinter,轻量但控件太简陋,做复杂布局要自己拼,后期维护成本高;还有pyqt5,和PySide6几乎等价,但授权协议对商业应用不友好,我这边项目没有商业化计划,但不想给自己埋雷,所以用PySide6。
4.2 登录注册模块的设计与实现细节
登录注册看起来是个基础功能,但在桌面应用里也有讲究。我没有用远程数据库做账号校验,因为部署环境不一定有网络。方案是本地SQLite数据库,密码用sha256加盐哈希后存储。这样既保证功能完整性,又不需要外部服务,开机就能用。
注册页面需要用户名、密码、确认密码。密码规则我设的是“至少6位,必须包含字母和数字”,太复杂的规则在小范围内部使用会把自己人也烦死。登录页面做三次失败锁定,锁定时间10分钟。这个锁定的目的不是防黑客——本地应用没多少黑客——是防止别人随手拿不同密码瞎试占用资源。
界面风格走简洁路线。登录窗口居中,背景用纯色加一个Logo位,不要花里胡哨。真正能用的桌面应用,界面好看是锦上添花,流程顺畅才是核心。
登录成功之后进入主界面,主界面布局是左侧操作区,右侧图像显示区。操作区从上到下三个功能块:图片导入、摄像头识别、检测结果面板。图片导入支持jpg/png/bmp格式,点击后在右侧主显示区弹出图片,模型自动进行检测,检测结果实时标注在原图上。摄像头识别走OpenCV的VideoCapture,在本机调用摄像头设备,连续读取帧送入模型,帧率控制在12FPS左右,避免UI线程卡顿。
4.3 模型集成与推理管线:UI和模型怎么配合
这是一个非常容易出问题的地方。很多第一次做项目的人,直接把模型的predict函数写在按钮的槽函数里,一按按钮页面就卡死。原因是推理是计算密集型操作,如果和UI渲染在同一个线程,CPU被占满,界面当然就没有响应了。
解决思路是用QThread把推理放到后台线程,推理完成后通过Signal把结果传回主线程更新界面。具体来说:新建一个Worker类继承QThread,把模型加载和推理逻辑写在run()方法里,检测完成后emit一个自定义信号,信号携带检测框坐标、类别和置信度数据。主线程拿到信号后,在界面上绘制矩形框和类别标签。
数据流上要注意坐标转换。YOLO模型输入是640x640归一化坐标,而界面显示的图片尺寸可能是800x600或者更大。直接拿归一化坐标往原图上画,框的位置必然不对。正确的做法是拿到检测框的归一化坐标后,按原图实际宽高还原成像素坐标,再交给绘图函数。
4.4 界面模块的关键代码骨架
先说推理线程的部分:
import threading import torch from ultralytics import YOLO class Detector: """模型封装:加载权重 + 图像推理 + 结果返回""" def __init__(self, weights_path, device="cuda:0"): self.model = YOLO(weights_path) self.device = device if torch.cuda.is_available() else "cpu" self.lock = threading.Lock() def predict(self, image_bgr): # 输入的图像是OpenCV读取的BGR格式 # ultralytics内部默认处理RGB,需做一次通道转换 image_rgb = image_bgr[:, :, ::-1] with self.lock: # 防止多线程并发调用导致模型状态错乱 results = self.model.predict( source=image_rgb, conf=0.35, iou=0.45, imgsz=640, verbose=False ) return results[0]再用QThread来接推理任务:
from PySide6.QtCore import QThread, Signal class InferenceThread(QThread): result_ready = Signal(object) # 推理完成的信号 finished_one = Signal(float) # 单帧耗时信号 def __init__(self, detector, image_bgr, parent=None): super().__init__(parent) self.detector = detector self.image_bgr = image_bgr def run(self): start_time = time.time() result = self.detector.predict(self.image_bgr) elapsed = time.time() - start_time self.result_ready.emit(result) self.finished_one.emit(elapsed)保存模型路径和界面数据分离:
# 关键参数建议写到config.py统一管理 class Config: MODEL_PATH = "models/best_yolov11s.pt" CONF_THRESHOLD = 0.35 IOU_THRESHOLD = 0.45 INPUT_SIZE = 640 CLASS_NAMES = ["Seedling", "Growth", "Heading", "Mature"] DB_PATH = "data/users.db"4.5 界面打包与交付踩过的坑
打包这步非常折磨人。PySide6应用打包体积大,里面包含Qt库、Python解释器、OpenCV等。我尝试过直接用PyInstaller一条命令打包,结果在干净的环境上跑起来直接报错,提示缺少某些Qt插件。排查半天,发现是资源文件没有被正确收集——PySide6的插件目录需要显式加进打包配置里。
解决方案是在spec文件的datas里加一行路径指向Qt插件目录,把platforms、iconengines等目录整个塞进包。打包完体积大概120MB左右,这在桌面应用里还过得去。
另一个坑是摄像头权限。在Windows环境打包后,首次打开摄像头经常黑屏,不是代码的问题,是系统没有给EXE授权摄像头权限。进了“隐私->相机”设置里把允许桌面应用访问摄像头的选项打开,问题就消失了。这个事虽小,但到了部署现场你自己排查起来特别浪费时间。
5. 常见问题与排查技巧实录
5.1 检测效果类问题排查速查表
我项目做完之后,模拟了用户自己使用时会遇到的几个典型问题,整理成一张速查表,直接给到现场部署的人,能省很多沟通成本。
| 问题现象 | 可能原因 | 解决建议 |
|---|---|---|
| 检测框位置乱跳 | 视频流帧率过高、没有做平滑 | 适当降帧,或用加权平均平滑框位置 |
| 小苗检测不到 | 目标太小、置信度阈值过高 | 调低conf到0.25,检查输入分辨率 |
| 类别全是生长期 | 类别样本不平衡 | 给少数类加类别权重,或补充数据 |
| 成熟期误判为结球期 | 视觉特征差异小 | 增加泛黄叶边样本,调整数据分布 |
| 程序启动后卡死 | 模型加载放在UI线程 | 把模型初始化放到后台线程或启动等待页 |
| 摄像头画面灰色 | 权限未开/编码格式不兼容 | 检查系统相机权限,手动指定摄像头index |
5.2 训练过程过拟合的实战处理
刚用1800张图训练YOLOv11的时候,遇到过一个典型问题:训练集loss一直下降,验证集mAP到60%左右死活不动了。这是典型的过拟合信号。我做了三个动作:
第一,增加更强的数据增强——把Mosaic增强打开(YOLOv11默认支持的),Mosaic会把四张图拼成一张,让模型看到更丰富的背景组合,等于数据集量翻了三四倍。
第二,把dropout打开并加大到0.15。YOLOv11的neck部分支持dropout,加一点能有效限制模型对训练集特征的过拟合。
第三,启动早停并缩短耐心值。我设的是“验证集mAP30个epoch不上升就停”,节省了不少无效训练时间,也让最终模型收敛在平台期,而不是继续往过拟合方向“精调”。
5.3 部署现场容易忽略的几个细节
现场部署时,有几个点特别容易翻车,值得单独强调。
一个是大棚现场用电脑性能参差不齐。很多农业场景的电脑没有独立显卡,YOLOv11在CPU上跑虽然能跑但偏慢,一张图320ms左右,视频流基本不现实。我的解决建议是:无GPU场景直接放弃摄像头实时检测,改成拍一张检测一张;或者机器上部署ONNX Runtime的CPU优化版,会比直接跑PyTorch模型快不少。
另一个是光线突变问题。大棚里的光照不是恒定的,早上、中午、傍晚差异很大,直接切换摄像头画面会导致检测置信度波动明显。我的方案是部署时在代码里加了一个“自动曝光稳定”的小逻辑:用OpenCV的createCLAHE做局部直方图均衡,先对画面做光照归一化再送进模型。这一步做完,全天候的检测稳定性好了很多。
还有一个容易被骂的问题是“界面提示不够友好”。用户不知道什么是置信度,也不知道什么是mAP,他看到的就是“模型说现在是成熟期,但我去地里看怎么感觉还能再长两天”。所以界面上的结果展示,我加了一句中文字样的判断依据说明:比如“成熟期:叶球紧实,外叶边缘轻微泛黄”,这比单纯显示英文类名和置信度数字要直观得多。
5.4 一个真实场景的完整排查案例
项目交付之后,收到一条反馈说“识别生菜图片时,死活检测不到任何目标”。远程看不到现场画面,只能让现场人员先发过来一张截图。我看到截图的第一反应就是——图片光线严重偏暗,生菜和土壤的对比度极低,模型输入后置信度普遍低于阈值。
这个问题的处理是三步走的:第一步,让现场确认是单张图片识别还是摄像头实时流;第二步,如果是单张图片,是图片本身质量差还是代码读图后处理出了问题;第三步,检查预处理的resize和normalize逻辑是否正确。排查下来发现是现场人员在黑暗环境下用手机拍的图,叶片颜色几乎和土壤融为一体。加了CLAHE预处理后问题得到改善,同时建议现场改善打光条件,毕竟模型不能解决所有问题,硬性拍摄条件是绕不过去的。
提示:遇到“检测不到任何目标”的时候,先不要急着改模型,用测试集图片在本地跑一次同样的代码。本地能出框,就是现场图片或环境问题;本地也不出框,才轮到模型和代码的排查。这个排查顺序能少走很多弯路。
6. 项目复盘与实用建议
如果我现在重新做一遍生菜生长周期检测系统,有几处会直接调整策略。
数据标注上会更早引入“预标注+人工修框”的工作流。第一次做的时候纯人工标注,一两千张图标到头昏眼花。后来发现可以先拿一个预训练模型对图片做初步检测生成标注框,人工只需要调整边界和修正类别,效率能提升至少40%。遇到边界类别的问题也更好解决,因为预标注的框天然带有模型自己的分类倾向,人只需要裁决同不同意。
训练策略上会把“补齐边界样本”做得更极端。比如生长期向结球期的过渡样本,不要觉得模棱两可就扔掉,而应该单独划一个“边界验证集”,专门用来测试模型在不同生长期临界状态下的稳定性。我这次做的是过滤边界样本,但如果再来一次,我会保留一批边界图作为挑战集,用来测试模型上线后的真实泛化能力。
UI层面还有很大扩展空间。目前的展示只有检测框和类别。用户其实更想看到的是“这个周期阶段还有几天进入下一阶段”这种决策性信息。这需要在模型输出的基础上再做一层统计和推断,比如根据当前检测到的生长阶段和持续天数,估算下一阶段大约什么时候到。这个不是YOLO的任务范围,但是是产品价值的大幅提升点。
最后说一点个人体会:农业AI项目最难的从来不是模型结构,甚至不是数据集数量,而是“真实场景的不可控性”。大棚里的光照、视角度、作物密度、叶片遮挡,每一项都在挑战模型的泛化能力。YOLOv11能做的是尽量把模型底座做扎实,但真要落地好用,必须回到场景里去,把数据采集和预处理做精细。这套思路不只适用于生菜,换到黄瓜、番茄、辣椒,方法论是通用的。
项目源码和训练好的模型权重我已经打包整理好了,同时也补了相关的数据集说明文档。有需要的可以直接用来当基础,改成自己的作物类别也不难——把数据换成你的场景,跑一轮训练就行。做农业检测这种事,最怕的就是纸上谈兵,真下地、真采集、真部署,遇到的问题和解决方案会比任何论文都来得有价值。