基于YOLOv10的大豆检测系统:从数据标注到UI界面完整落地指南

发布时间:2026/10/21 12:47:57
基于YOLOv10的大豆检测系统:从数据标注到UI界面完整落地指南 我最早开始碰农业视觉项目是把深度学习用到田间作物识别上。当时试过不少模型从Faster R-CNN到SSD再到YOLO系列一点点迭代说实话真正让我觉得能在实际场景里“落地”的还是这两年YOLO系列的演进。特别是最新的YOLOv10在保持实时性的前提下把精度和效率又往上推了一截。这次要聊的“基于YOLOv10的大豆检测系统”就是一个很典型的农业深度学习的落地项目涉及到YOLOv10深度学习模型、YOLO数据集的构建与标注、UI界面的开发以及完整的Python项目交付。我试着把整个系统的设计思路、训练过程和界面开发经验拆开来讲希望能给正在做类似目标检测项目的人一些参考。这类系统能解决什么问题简单说就是让计算机自动识别图像里的大豆颗粒完成计数、定位、筛选等操作。比如种子质量检测场景中需要统计一批大豆的数量、测量颗粒大小、判断是否饱满或者有无破损再比如育种实验里需要从大量培养皿图像中自动分析大豆的生长情况。靠人眼一个个数效率低且容易疲劳出错用模型自动检测是更靠谱的方案。适合谁来参考如果你正在做农业相关的视觉项目、想学习YOLO系列模型从训练到部署的完整流程或者需要在一个具体的垂直场景中快速搭建检测系统这篇内容应该能帮上忙。1. 整体设计与技术选型拆解1.1 为什么选YOLOv10而不是YOLOv5/v8目标检测模型的选择直接决定了项目后续的开发体验和落地效果。我在做这个大豆检测项目时最初也纠结过到底用哪一版YOLO毕竟YOLOv5和YOLOv8的生态很成熟遇到的坑少网上资料也多。但认真对比之后我还是选了YOLOv10原因主要有三点无NMS设计、端到端推理、更强的轻量化表现。传统YOLO系列模型包括YOLOv5和YOLOv8在推理阶段都需要做NMS非极大值抑制后处理用来去掉重复的检测框。这个过程挺烦人它需要额外调节置信度阈值和IOU阈值而且复杂的场景下容易出现小目标被误抑制或者两个贴近目标被合并成一个框的问题。大豆检测有一个特点颗粒之间经常是紧挨着的有些甚至密集堆叠在一起这时候NMS带来的不确定性就很麻烦。YOLOv10引入了双标签分配策略训练时同时使用一对多和一对一两种标签分配方式推理时直接使用一对一匹配把NMS整个去掉变成了真正的端到端模型。对大场景下密集目标检测来说这个改动可以说解决了长期以来的痛点。另外YOLOv10在结构上做了不少优化。它采用了大卷积核和更深层的P3检测头设计小目标的特征提取能力比前代更强。大豆颗粒在图像里通常占的像素比例不大特别是拍照距离稍远的时候每颗大豆可能就几十个像素这种尺度下小目标检测能力就直接影响最终精度。再加上YOLOv10提供了从N、S、M、B、L到X六个不同规模的模型版本可以根据部署环境灵活选择。比如我这个项目里最终部署用的就是YOLOv10s兼顾精度和推理速度在CPU上跑也能达到可用的实时性。1.2 大豆检测场景的难点与整体方案设计模型选型只是第一步真正要做一个能用的系统还必须把场景特性想清楚。大豆检测有几个明显的特点第一个特点是目标尺寸小且密集。一板大豆放在托盘里图像分辨率如果是1920像素单颗大豆的直径大概只有30到50像素几百颗大豆挤在一起检测框之间的重叠程度非常高。这种场景下传统的目标检测模型很容易出现漏检模型必须对细节纹理足够敏感。第二个特点是背景复杂度高。实验室里的图像还好说如果涉及田间拍摄背景里有泥土、叶片、杂草、阳光阴影等干扰因素大豆和小石块或者黄褐色叶片的颜色很像模型一旦过拟合到颜色特征就会产生大量误检。第三个特点是精度要求高。种子检测、农业科研这类场景对检测结果的准确率要求很高数错几颗可能整个实验就失真了。所以模型训练不是跑通就行需要反复调优。基于这些特点我设计的整体方案是数据采集阶段覆盖不同光照、不同摆放密度、不同背景的大豆图像。数据标注阶段使用LabelImg标注YOLO格式的txt文件所有目标统一标注为“soybean”一个类别。模型训练阶段基于YOLOv10s预训练权重微调设置合理的超参数和早停策略。推理与界面阶段开发一个基于PyQt5的GUI界面支持图片、视频、实时摄像头三种检测模式。模型优化阶段根据测试结果调整输入分辨率、置信度阈值、IOU阈值虽然YOLOv10推理不需要NMS但训练和评估阶段仍有相关参数以及数据增强策略。整个流程听起来不复杂但每个环节都有很多细节下面逐块展开。2. 数据集构建与标注细节2.1 数据采集与图像预处理经验模型效果的上限很大程度上是由数据的质量和数量决定的。我的数据采集思路是刻意制造“多样性”。如果只在一个固定环境、固定光照条件下拍一批图像训练出来的模型换个环境就不灵了。建议是至少分3批采集第一批实验室条件下托盘整齐摆放光线均匀手机或相机垂直俯拍。第二批模拟实际场景大豆散落在桌面上有部分阴影、有部分重叠拍摄角度稍有倾斜。第三批加入干扰条件比如混入几颗红豆、绿豆、石块或者光照偏暗、偏亮用来提升模型的泛化能力。采集完成后图像预处理有几个关键动作首先是统一格式与尺寸。采集到的图像可能是JPG、PNG甚至HEIC建议统一转为JPG格式减少体积并保证兼容性。训练前会统一缩放但注意不要在标注前就压缩分辨率不然小目标会丢失细节。其次是图像清洗。剔除模糊、严重过曝、完全不在焦距上的图像。这里有个小技巧可以通过计算图像的拉普拉斯方差Laplacian Variance来筛选清晰度——方差低于某个阈值的图像直接删除。比如像素值范围0到255的图像拉普拉斯方差低于80基本可以认定为模糊图像。这个阈值可以作为参考不同场景可以微调。还有一点容易忽略的是图像多样性检查。我习惯对每张图像做个简单的统计比如亮度直方图、颜色分布确保数据集没有大量集中在相似的曝光条件下。如果发现所有图像都是同样亮度最好增加一些变化否则后面做数据增强时基础不够丰富。2.2 标注规范与格式转换大豆检测项目的标注工作我推荐用LabelImg来做。这个工具虽然是老牌了但稳定、简单团队协作时也容易统一规范。标注的核心原则有两条只标注清晰可见的完整颗粒。边缘被截断一半的、严重模糊无法判断的不标。被遮挡的大豆尽量贴合可见部分画框。不要试图画一个“想象中的完整颗粒”的框那样会引入大量噪声。这里要特别说明YOLO格式的坐标系统。YOLO的标注文件是txt格式每行代表一个目标内容是class_id x_center y_center width height其中x_center、y_center、width、height都是归一化到0~1之间的相对坐标也就是相对于图像宽高的比例。比如图像宽度为1920像素某个目标的中心点x坐标为960像素那么x_center就是960/19200.5。归一化坐标的好处是不同分辨率的图像不需要重新标注。LabelImg标注完成后保存的是Pascal VOC格式的XML文件需要转换为YOLO格式的txt文件。转换脚本逻辑很简单核心就是读取XML里的bndbox节点计算中心点和宽高再除以图像的宽和高import xml.etree.ElementTree as ET def convert_to_yolo(xml_path, output_dir, class_list): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): class_name obj.find(name).text if class_name not in class_list: continue class_id class_list.index(class_name) bbox obj.find(bndbox) xmin int(float(bbox.find(xmin).text)) ymin int(float(bbox.find(ymin).text)) xmax int(float(bbox.find(xmax).text)) ymax int(float(bbox.find(ymax).text)) x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) txt_path os.path.join(output_dir, os.path.splitext(os.path.basename(xml_path))[0] .txt) with open(txt_path, w) as f: f.write(\n.join(lines))这个脚本我在实际项目中反复用过稳定可靠。注意一个坑有些代码会把宽高写成目标对角线或者原始坐标直接丢进去导致训练时损失函数直接爆炸——坐标系转换错误是YOLO训练新手最容易犯的错误没有之一。2.3 数据增强策略与数据集划分数据规模上大豆检测这类单类目标我建议至少准备800到1500张标注图像。每张图像里的大豆数量如果比较多比如超过50颗那么总样本量所有框的总数会非常可观这种情况下600张高质量图像也可能训练出不错的效果。为了提升模型的鲁棒性数据增强是必须做的。YOLOv10训练时本身就内置了Mosaic、MixUp、HSV扰动、随机翻转等增强策略配置文件里可以直接设置。我的经验是Mosaic增强开起来对密集小目标帮助很大。HSV扰动可以适度增加尤其是亮度hsv_v和饱和度hsv_s帮助模型适应不同光照条件。MixUp增强对大豆这种目标相对一致的场景不一定有明显收益可以保持默认强度或者干脆关掉。随机翻转和90度随机旋转可以开但要注意旋转增强只适用于这类方向不敏感的目标。如果是识别文字或者有明显方向性的目标旋转增强要非常谨慎。数据集划分方面我按8:1:1分成训练集、验证集、测试集。之前有人习惯按7:2:1但大豆检测任务里目标密集验证集图像数量太少会导致早停判断失真。同时注意划分时要以图像为单位而不是以检测框为单位否则同图像的内容同时出现在训练集和验证集评估结果会虚高。3. 模型训练与调优实操3.1 环境配置要点训练环境我推荐使用Linux NVIDIA显卡 CUDA的组合Windows也可以跑但有些坑。YOLOv10是Ultralytics团队维护的所以可以直接用Ultralytics的Python包来训练pip install ultralytics安装完后可以检查一下环境是否正常import torch print(torch.__version__) print(torch.cuda.is_available())如果torch.cuda.is_available()返回False说明PyTorch没有装到CUDA版本需要去PyTorch官网按照CUDA版本重新安装。这个坑很多新手会踩虽然代码能跑但训练速度慢到怀疑人生。YOLOv10的模型权重可以直接从官方仓库下载也可以用一行代码自动加载from ultralytics import YOLO model YOLO(yolov10s.pt) # 自动下载预训练权重预训练权重是模型训练的关键。不要每次从随机权重开始训练VOC或COCO数据集上的预训练权重已经让模型学会了通用的特征提取能力微调到自己的数据集上只需要少量迭代就能收敛。打个比方预训练模型像是读过很多书的毕业生你只需要告诉他“现在你要专注盯大豆”就行完全没必要从小学重新培养。3.2 关键训练参数的选择逻辑训练参数我直接给出一个能跑出不错效果的配置然后解释为什么from ultralytics import YOLO model YOLO(yolov10s.pt) results model.train( datasoybean_dataset.yaml, epochs100, batch16, imgsz640, patience20, lr00.01, device0, workers8 )各个参数的选择逻辑imgsz输入分辨率这是对精度影响最大的参数。YOLO默认是640但大豆颗粒小如果图像分辨率高、目标密集我建议直接用640训练后面在推理阶段可以适当提高到1280。如果显卡显存足够也可以直接用1024训练小目标召回率会明显上升但训练时间也显著增加。我的实测感受是对于90%以上的大豆检测场景640训练1280推理是一个性价比很高的组合。batch批大小取决于显存大小。以12GB显存为例YOLOv10s跑640分辨率、batch16基本是上限附近。batch太小比如4会导致梯度噪声大训练不稳定batch太大比如64则需要相应提高学习率不然收敛会慢。lr0初始学习率0.01是Ultralytics的默认值对大多数场景够用。如果发现自己数据集比较小比如只有500张图像建议降到0.005如果数据集很大3000张以上可以保持0.01。这个参数不要拍脑袋乱调因为模型内置了warmup和余弦退火前期会自动调整学习率。patience早停耐心值设置为20意味着连续20个epoch验证集指标没有提升就停止训练。这个参数非常重要能帮你省大量时间。我之前见过完全靠手工判断训练是否收敛的人守在电脑前等上半天其实早停机制就是干这个的。data配置数据集配置文件用YAML格式包含路径信息、类别数、类别名# soybean_dataset.yaml path: /path/to/soybean_dataset train: images/train val: images/val test: images/test nc: 1 names: [soybean]这里有几个细节要注意path最好写成绝对路径避免相对路径找不到文件。train和val指向的是包含图像的目录Ultralytics会自动去对应目录找同名txt文件。所以图像目录结构要和标注目录严格对应。nc: 1表示只有一个类别names里就是类别名列表顺序要和标注文件里的class_id一致。3.3 训练过程中的监控与判断训练开始后不要光盯着命令行输出发呆。我习惯同时关注几个关键指标train/box_loss边界框回归损失理论上应该持续下降。如果这个loss出现剧烈震荡大概率是学习率过高或者标注有问题。train/cls_loss分类损失。大豆是单类目标这个loss应该很快降到很低。metrics/precision精确率。预测为正的样本中真正为正的比例。如果精确率很低说明误检多模型把背景当成了大豆。metrics/recall召回率。所有正样本中被正确预测出来的比例。如果召回率低说明漏检多模型漏掉了不少大豆。精确率和召回率天然存在矛盾。阈值调高精确率上升、召回率下降阈值调低则相反。YOLOv10输出的是每个检测框的置信度分数后面做推理时可以灵活调整。训练阶段一般追求的是“P和R都高”也就是PR曲线下的面积大。还有一个经验训练完一个阶段比如50个epoch后用验证集里的几张图做一次可视化预测看看检测框画得是否准确。这比单看数值更直观。框偏大、框偏小、一个目标出多个框、相邻颗粒被错误合并这些问题单靠指标看不出来必须看实际图片。4. 推理优化与UI界面实现4.1 模型导出与加速方案训练完成后生成的best.pt权重文件就是效果最好的模型。但直接使用PyTorch的pt文件推理会有几方面问题依赖PyTorch框架环境、推理效率有提升空间、不方便部署。我的建议是导出为ONNX格式然后可以做进一步的优化。导出方式from ultralytics import YOLO model YOLO(best.pt) model.export(formatonnx, imgsz640, dynamicTrue)导出ONNX后可以用ONNX Runtime加载推理不依赖PyTorch。可以通过onnx-simplifier简化模型结构去掉冗余节点。可以转换成TensorRT engine格式如果目标机器有NVIDIA显卡推理速度提升非常明显。TensorRT优化这块我实际测试过YOLOv10s模型在GPU上从原本的几十毫秒降至个位数毫秒级别对于实时检测场景是质的提升。不过TensorRT的配置过程比较折腾涉及版本兼容性、动态shape设置等第一次配置需要耐心。对于不追求极致性能的场景直接用ONNX Runtime就够了CPU上也能跑只是速度相对慢一些。4.2 UI界面的功能设计与实现方案这部分是整个项目里用户能直接感受到的部分。我用的是PyQt5 OpenCV ONNX Runtime的组合开发了一套桌面UI界面。界面功能我设计为三个页面图片检测页面点击“选择图片”按钮加载本地图片右侧显示检测结果下方显示统计信息检测到的大豆总数、平均置信度、单框检测时间、图像分辨率等。视频检测页面支持选择本地视频文件播放过程中逐帧检测显示实时计数结果。这里的关键是保持一定的处理帧率如果每帧都做全分辨率检测帧率会很低需要做帧间隔或者降低推理分辨率。摄像头检测页面调用电脑摄像头实时检测。对实时性要求高建议把推理分辨率设为640并开启half精度FP16推理帧率能提升不少。界面代码的关键部分核心是把推理逻辑和UI刷新逻辑分开避免UI卡死。我的做法是class DetectThread(QThread): result_signal pyqtSignal(dict) def __init__(self): super().__init__() self.session onnxruntime.InferenceSession(best.onnx) def infer(self, image): # 预处理BGR转RGB、resize、归一化、CHW转NCHW img cv2.cvtColor(image, cv2.COLOR_BGR2RGB) img cv2.resize(img, (640, 640)) img img.astype(np.float32) / 255.0 img np.transpose(img, (2, 0, 1)) img np.expand_dims(img, axis0) # 推理 inputs {self.session.get_inputs()[0].name: img} outputs self.session.run(None, inputs)[0] # 后处理解析检测结果过滤低置信度目标 boxes, confidences postprocess(outputs, conf_threshold0.45) return boxes, confidences这里有一个对新手很友好的提醒ONNX Runtime的输入节点名和输出节点名不是固定的需要先打印出来。用下面的代码看一下for node in session.get_inputs(): print(node.name, node.shape) for node in session.get_outputs(): print(node.name, node.shape)了解节点信息后才可以正确构造输入字典和解析输出数组。很多人卡在这一步其实就是没打印节点信息凭猜测去对接输入输出。4.3 后处理逻辑阈值、过滤与计数前面提到YOLOv10推理不需要NMS但后处理仍然需要不过简单很多。YOLOv10输出的每个预测框本身就带有类别置信度只需要按置信度阈值过滤一遍然后把坐标还原到原图尺度就行。我习惯设置两个阈值置信度阈值conf_threshold默认0.45。过滤掉置信度低于这个值的框。IOU阈值虽然不需要NMS去重但我在实际测试中发现YOLOv10在密集场景下偶尔会出现一个目标上出现两个高度重叠的框这时候可以用一个轻量的NMS兜底。如果不想引入NMS可以设置一个很小的IOU阈值比如0.5仅用来合并极端重叠的情况。有一个实用技巧是启用置信度阈值自适应。在实际使用中如果检测结果中漏检比较多框的数量明显少于肉眼可见的大豆数量把置信度阈值降低比如从0.45降到0.25。如果误检比较多出现一些框在非大豆区域上就把阈值升高。这个调整可以直接做成UI里的一个滑动条用户可以实时调整极大提升系统的可用性。5. 常见问题与排查实录5.1 漏检严重的排查思路与解决漏检是大豆检测项目里碰到最多的问题表现形式是图像里明显能看到大豆但模型没有给框。排查思路按优先级走第一步检查训练集标注质量。随机挑几十张训练图像用可视化脚本把标注框画到图像上检查是不是有大量大豆没被标注。如果训练集本身不完整模型学到的模式就是“大豆有时候该被忽略”这个漏检就是模型老实的反馈。补标数据比调试模型更有效果。第二步检查推理分辨率。训练时的imgsz是640如果推理时输入的分辨率也是640但原图很大等于把所有小目标压成极小像素漏检概率自然增加。如果原图是1920x1080建议推理时按比例把长边缩放到1280左右检测小目标的召回率会显著提升。第三步检查数据增强是否过分。如果开了过高强度的增强模型可能被“训练得过于坚强”在验证集上反而表现不佳。特别是小幅度的平移和缩放增强大豆的边缘很敏感增强过度会让标注框和目标实际位置出现偏差。5.2 训练不收敛或Loss爆炸的处理Loss在训练开始阶段就出现NaN或者持续不下降常见的几个原因标注文件有非法值。坐标归一化后有负数、大于1的数或者宽高为0。用Python检查一下所有txt文件是否满足0 x_center 1、0 y_center 1、width 0、height 0。这个问题极其常见手动标注时一不留神就会引入。学习率过高。lr0设得太大比如0.1以上梯度更新步子太大loss直接震荡或发散。把学习率降到0.001试试通常能解决。图像与标注文件不匹配。比如某张图像的txt标注文件是从另一张图像复制过来的导致框的位置和图像内容完全对不上。模型想学也学不出来。还有一个容易忽略的因素标签类别数不匹配。YAML配置里写了nc: 1但标注文件里出现了class_id: 1也就是第二个类别训练时索引越界就会报错或者loss异常。5.3 界面推理速度慢的优化建议PyQt5界面如果检测一帧需要一两秒体验会非常差。优化方向降低推理分辨率。640分辨率要比1280快数倍。如果是实时摄像头预览可以用640如果是离线分析单张高清图片再用1280。使用FP16推理。ONNX Runtime支持半精度推理加载模型时设置providers参数session onnxruntime.InferenceSession( best.onnx, providers[CUDAExecutionProvider, CPUExecutionProvider] )如果显卡是NVIDIA且支持FP16可以进一步做TensorRT转换速度翻倍。控制视频处理帧率。视频检测不需要每一帧都做推理比如设置每5帧处理一次既不会太卡也能保证连续性。摄像头检测也可以用这个策略。图像读取与预处理用多线程。UI主线程负责绘制子线程负责读图和推理通过信号槽传递结果。不要把所有逻辑都堆在主线程里界面秒卡。5.4 边界检测框不准问题检测框和实际大豆边缘贴合不紧密也是常见问题。如果框普遍偏大检查标注时是否习惯性地把外边界也框进去了如果框普遍偏小同理标注时不要把“外圈模糊”的部分包含进去。这里有个标准框的边界应该正好卡住大豆可见部分的边缘不要留边距也不要裁剪进大豆内部。如果模型训练收敛后检测框始终存在系统性偏移比如总是偏左一两个像素可以使用测试集上预测框和真实标注框之间的平均偏移量来修正。不过对大多数场景来说这个偏移量很小不影响实际使用。6. 模型部署与系统工程化的补充建议如果这个系统是要交给非技术背景的人使用的除了UI界面之外还必须考虑几个“隐藏”的需求。打包发布。PyQt5项目可以用PyInstaller打包成独立的exeWindows或者可执行文件Linux这样用户不需要安装Python环境。打包时需要把模型文件、配置文件一并打包进去。我踩过的一个坑是PyInstaller打包OpenCV相关依赖时缺失一些dll导致运行时报错建议用--collect-all把OpenCV相关的库包含进来。日志记录。我建议在系统里保留一个日志文件记录每次检测的时间、图片路径、检测数量、是否有异常。这样后续出了问题方便回溯。不用很复杂简单用logging模块写文件就行。批量处理能力。实验室用户常有大批量图像需要分析光靠一张张选择图片效率太低。我会在体系里增加一个“批量检测”功能用户选择一个文件夹系统自动遍历所有图像把结果保存成CSV文件里面包含文件名、检测目标数量、平均置信度等字段。几点心得收尾回到开头那个问题为什么这个项目值得做。大豆检测只是一个很小的垂直场景但它很能说明问题目标检测模型在实际落地时模型结构本身带来的精度差异远不如数据质量、标注规范和推理部署细节的影响大。YOLOv10的确提供了更好的基础架构但真正决定系统好不好用的是数据集是不是覆盖了足够多的实际场景是标注框是不是统一规范是UI界面是不是让用户觉得好用、能在几分钟内上手。我自己操练这个项目时的最深体会是深度学习行业不缺模型DIY教程缺的是把模型盘活成型、让非技术人员也能用上的工程能力。这需要数据集、训练、部署、界面开发这几个环节都能串起来。YOLOv10给了你一个高性能的检测基础但能否把“能跑”变成“好用”才是真正考验一个开发者的地方。如果你正在做类似的项目记住多花时间和精力在数据采集与标注上其次是界面和部署体验模型训练本身的反而是最不花心思的部分。方向对路了效果通常不会差。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询