资讯动态

YOLOv8水果识别系统实战:从数据标注到界面部署

发布时间:2026/8/31 15:28:16 来源:尧图企业网站定制
简介本资源是一个基于YOLOv8算法实现的端到端水果图像识别系统面向人工智能初学者、计算机视觉实践者及农业智能化应用开发者解决水果种类自动识别与分类的实际问题适用于农产品分拣、智能仓储、教学实验等场景。压缩包共497个文件含184个Python源码如main.py主程序、Fruit_Detection.py检测模块、Fruit_Detection.ui图形界面、30个YAML配置文件含BASC.yaml等模型参数定义、254个pyc编译文件以及PNG/UI/Shell等辅助资源整体仅2.57MB轻量易部署。目前已有72人学习下载。用户可直接运行GUI界面进行实时检测完整获得从数据加载、YOLOv8模型调用、后处理BASC.py、可视化background.png/shexiangtou.png等UI素材到基线测试Baseline.py的全流程代码结构特别适合理解工业级轻量识别系统的模块划分与集成逻辑。 我们直接用 YOLOv8 做的水果识别系统从数据准备到训练调参再到界面封装整套流程已经跑通这里把完整经验分享出来包括踩过的坑和最终可复用的细节希望能帮到正在做类似项目的朋友。这个项目本身不算复杂核心就三件事目标检测模型选型、数据集构建、训练与部署。但如果想把识别效果做好、系统做得完整可交付里面还是有不少细节值得深挖。我这次基于 YOLOv8 实现了一套水果图像识别系统能够在图片、视频流和摄像头实时画面中识别常见水果类别并输出带标注框的结果同时配套了简单的 GUI 操作界面。整个过程从环境配置、数据标注、模型训练到界面封装完整走了一遍这里把每个环节的关键操作和心得记录下来。1. 项目整体设计与方案选型1.1 为什么选 YOLOv8 而不是其他目标检测模型我最初考虑过几个方案Faster R-CNN、SSD、EfficientDet以及 YOLOv5 和 YOLOv8。Faster R-CNN 精度确实高但推理速度太慢对后续要做实时摄像头识别来说不够友好。SSD 速度快但小目标检测能力一般水果这种目标虽然不算特别小但在画面中相互遮挡的情况很常见SSD 的表现不太稳定。EfficientDet 结构复杂部署和训练都不够轻量。YOLOv8 相比 YOLOv5 有几个明显优势C2f 模块替换了原来的 C3 模块梯度流动更充分检测头改成了解耦头结构分类和回归分支分开收敛速度更快Anchor-Free 的方式省去了锚框聚类这一步骤训练时少了一个调参维度。实际跑下来在同样的数据集上YOLOv8 的 mAP 比 YOLOv5 高 2 到 4 个百分点训练时间也没有明显增加。选择 YOLOv8 还考虑到它的生态完整度。Ultralytics 官方仓库提供了从数据标注格式转换、训练、验证到导出的完整工具链自带的数据增强策略也比较成熟使用成本低非常契合做一个系统级项目。1.2 系统整体架构设计这套水果识别系统从功能上划分成四个模块数据层、训练层、推理层、展示层。数据层负责图像采集和标注格式统一训练层基于 YOLOv8 完成模型训练和评估推理层封装模型加载与预测逻辑展示层提供可视化界面和结果输出。展示层我用了 PyQt5 来写主要考虑到 Python 生态下的兼容性最省心。界面分成三块区域左侧是功能按钮区支持选择图片、打开摄像头、开始识别中间是大面积的结果显示区实时展示带标注框的画面右侧是识别信息区显示当前帧中每个目标的类别、置信度以及整帧推理耗时。如果是做毕业论文或者实训项目这种架构足够支撑起整套系统的功能演示而且代码量可控后期扩展也比较方便。设计系统的时候有一个教训推理模块一定要和界面模块解耦。我一开始把模型推理逻辑直接写在 PyQt5 的信号槽函数里结果摄像头识别时界面频繁卡顿。后来把推理放到独立线程通过信号把结果传给主界面才彻底解决卡顿问题。1.3 水果类别的定义与识别范围我这次做的是 6 类水果识别苹果、香蕉、橙子、葡萄、西瓜、草莓。选择这 6 类有几个考虑一是常见后续找数据和实际测试都方便二是形态差异足够大类别间不容易混淆适合作为目标检测项目的入门选择三是这 6 类水果有代表性的遮挡场景比如一串葡萄、堆叠的苹果对模型泛化能力有一定挑战。如果是想挑战更高难度可以加入形态相似的水果比如青苹果和梨、橙子和橘子这就对数据量和标注质量提出了更高要求。2. 环境配置与数据集构建2.1 环境配置的详细步骤与避坑先说硬件。我跑训练的机器配置是 i5-12400F GTX 1660 Ti 6GB 32GB 内存。1660 Ti 跑 YOLOv8 说实话不算宽裕6GB 显存限制很大模型规模稍微大一点就容易爆显存。实测下YOLOv8s 用 640 输入尺寸、batch size 8 可以稳定训练YOLOv8m 就只能降到 batch size 4。如果显存小于 6GB建议直接选 YOLOv8n 或者 YOLOv8s输入尺寸可以配合 480。软件环境我用了 Python 3.9 PyTorch 2.0.1 CUDA 11.8 ultralytics 8.0.x。这里特别注意版本匹配PyTorch 的 CUDA 版本和显卡驱动需要对应。安装 PyTorch 时直接用官方命令就行注意不要用 pip 默认源安装 CPU 版本否则训练速度会慢到怀疑人生。# CUDA 11.8 对应安装命令 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 安装 ultralytics pip install ultralytics安装完 ultralytics 后建议验证一下是否正常python -c from ultralytics import YOLO; print(YOLO.__module__)能正常输出版本路径就说明环境没问题。另外强烈建议用虚拟环境管理项目依赖我见过太多人把环境搞乱了重新装系统得不偿失。2.2 数据集获取与标注实操数据来源我试过两个方向公开数据集和自己标注。公开数据集方面网上有很多水果检测数据集可以直接下载但质量参差不齐且标注格式各不相同需要统一转换。自己标注虽然费时间但数据和需求的匹配度更高。如果你选择公开数据集建议去 Kaggle 或者 Roboflow Universe 找。Roboflow Universe 上的水果检测数据可以直接导出 YOLO 格式连转换都省了。但注意检查数据质量有的数据集里面混入了不适合的图片需要肉眼筛查一遍。自己标注我用的是 LabelImg。流程是准备图片 → LabelImg 标注 → 导出 YOLO 格式 txt 文件 → 划分训练集和验证集。图片收集时注意多样性不同光照、不同角度、不同背景下同一种水果都要有。我实际收集了大约 3000 张图片6 类水果平均每类 500 张其中约 80% 用于训练20% 用于验证。标注的时候几个要点要注意。首先是边界框要贴合目标边缘不要留太多背景但也不能切掉水果本体。其次是对于遮挡目标如果遮挡面积小于 30%仍然标注完整的边界框遮挡超过一半就放弃标注。最后是一张图里多个目标每个都要单独标注不能漏标。标注是最耗体力也最关键的环节。我第一版模型识别效果差排查了一圈发现是标注框太随意有的框只包住水果的一半。重新标注后mAP 直接从 0.72 提升到了 0.85。2.3 数据增强与数据集划分策略YOLOv8 内置了丰富的数据增强策略包括马赛克增强、随机翻转、色彩抖动、随机缩放等。这些增强策略在训练时自动生效不需要手动做。需要手动处理的是数据集文件的组织方式。YOLO 格式的数据集目录结构如下dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yaml其中 data.yaml 是数据集配置文件里面指定了类别数和类别名称train: dataset/images/train val: dataset/images/val nc: 6 names: [apple, banana, orange, grape, watermelon, strawberry]标注文件是每个图片对应一个同名 txt 文件每行格式是类别id x_center y_center width height坐标都是归一化后的比例值。LabelImg 导出 YOLO 格式时已经处理好这些不需要手动计算。3. 模型训练与调优实战3.1 训练参数选择与完整命令YOLOv8 的训练入口很简单用 Ultralytics 提供的接口一条命令就能跑起来。关键是需要理解几个重要的参数from ultralytics import YOLO model YOLO(yolov8s.pt) results model.train( datadataset/data.yaml, epochs100, imgsz640, batch8, lr00.01, optimizerSGD, device0, workers4, patience20, projectruns/train, namefruit_yolov8s )这里的参数选择逻辑说一下。epochs 设 100配合早停机制patience20意思是 20 个 epoch 内验证集指标没有提升就提前停止防止过拟合。imgsz 用 640这是速度与精度的平衡点。batch 设 8 是 1660 Ti 6GB 显存的极限。优化器用 SGD 而不是 Adam因为 YOLO 系列的默认推荐就是 SGD配合线性学习率衰减策略效果最好。学习率从 0.01 起步训练过程中由余弦退火策略逐步降低。训练过程中终端会实时打印每个 epoch 的 loss 值和指标情况Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 49/100 5.8G 1.021 0.871 1.045 5 640 50/100 5.9G 0.952 0.802 0.998 9 640等训练的 loss 曲线从快速下降到缓慢下降直至基本持平说明模型已经收敛。3.2 损失函数曲线怎么看训练完成后runs/train/xxx/ 目录下会生成 results.png这是判断训练状态最直接的依据。图中包含 box_loss、cls_loss、dfl_loss 三条损失曲线以及 precision、recall、mAP50、mAP50-95 四条指标曲线。看曲线有几个经验training loss 持续下降但 validation loss 不降反升说明过拟合了需要增加数据量或增大正则化强度。mAP50 和 mAP50-95 两条曲线的差距通常在 10 到 20 个百分点之间如果差距过大说明模型在精确定位方面表现不好需要检查标注框质量。如果在训练最后阶段指标还在上升趋势中没有完全平稳可以增加训练轮次继续训练。我这次训练的模型最终结果是 mAP50 约 0.91mAP50-95 约 0.78precision 约 0.93recall 约 0.88。在 6 类水果识别任务中算是比较好的水平了。其中葡萄和草莓的 AP 稍低主要是这两个类别在数据集中存在大量密集目标和部分遮挡的情况。3.3 模型精度提升的改进尝试如果你觉得 baseline 精度不够有几个改进方向可以尝试。第一是更换更大的预训练权重从 yolov8n 换到 yolov8s 或者 yolov8m在相同数据下通常有 2 到 5 个百分点的提升。第二是调整输入尺寸从 640 提高到 960对于小目标有明显帮助但推理速度会下降约 40%。第三是引入注意力机制模块比如在 C2f 模块中加入 SE 或 ECA 注意力可以小幅提升精度代价是参数量和推理时间的略微增加。我在实验过程中尝试过给 YOLOv8s 加 ECA 注意力模块mAP50 提升了约 1.2 个百分点但推理耗时增加了约 8%。如果项目对实时性要求不是极端苛刻这个改动是值得的。实现方式就是在 ultralytics 的模块定义中增加 ECA 类然后在 C2f 模块中替换原来的 Bottleneck。但这里提醒一句如果是初学者先跑通完整流程再考虑改进。不要一上来就折腾网络结构很容易陷入调参泥潭。baseline 跑通以后再做改进对比实验才有意义。3.4 显存不足的应对策略GTX 1660 Ti 只有 6GB 显存训练过程中我遇到过几次 CUDA out of memory。解决方案优先级从高到低排列降低 batch size 是最直接有效的从 8 降到 4 通常就能解决。减小输入尺寸也有帮助从 640 降到 480显存占用会下降约一半。严重的话可以开启梯度累积YOLOv8 中通过 batch 参数配合 device 参数实现比如 batch16、设备显存不够时可以用 accumulate 参数来实现等效大 batch 的效果。另外注意 workers 参数不要设置太高Windows 系统下 workers 大于 2 容易出现 DataLoader worker 崩溃的问题这是 PyTorch 在 Windows 平台的老毛病了。4. 系统界面与推理部署4.1 GUI 界面核心实现识别系统做出来不是光在命令行里跑那样没法给用户用。我的界面用 PyQt5 实现核心代码分为两个部分界面构建和推理逻辑。推理部分封装成一个类class FruitDetector: def __init__(self, weights_path): self.model YOLO(weights_path) def predict(self, img): results self.model.predict(img, conf0.5, iou0.45, verboseFalse) return results[0] def detect_image(self, img): result self.predict(img) boxes result.boxes class_names result.names output [] for i in range(len(boxes)): cls_id int(boxes.cls[i]) conf float(boxes.conf[i]) xyxy boxes.xyxy[i].tolist() output.append({ class: class_names[cls_id], confidence: conf, bbox: xyxy }) return outputconf 参数控制置信度阈值低于这个值的检测结果会被过滤掉。iou 参数控制 NMS 的 IoU 阈值值越小越严格的去重。根据我的实测水果识别场景下 conf 设为 0.5、iou 设为 0.45 效果比较理想目标重叠少时可以适当降低 iou。摄像头实时识别时用 OpenCV 读取视频流每帧传入检测器然后把绘制了边界框和标签的帧显示到界面上。为了避免界面卡死检测器运行在单独的 QThread 中用信号把结果传回主线程刷新界面。4.2 模型导出与部署方式训练好的模型有几种部署形态。我实际用到的有三种PyTorch 权重文件.pt、ONNX 格式.onnx、TensorRT 引擎.engine。PyTorch 格式最省事直接加载就能用适合快速开发和验证。ONNX 格式适合跨平台部署可以脱离 PyTorch 环境运行速度也有所提升。TensorRT 格式是 NVIDIA GPU 上最快的推理方式适合对延迟要求苛刻的场景但导出时与显卡型号绑定换机器需要重新生成。导出 ONNX 的命令很简单model.export(formatonnx, imgsz640, opset12)导出后可以用 onnxruntime 进行推理import onnxruntime as ort sess ort.InferenceSession(best.onnx) input_name sess.get_inputs()[0].name outputs sess.run(None, {input_name: img_array})我在实际项目中将 ONNX 模型用 onnxruntime 推理单帧检测耗时在 25ms 左右1660 Ti 显卡比 PyTorch 原生推理快了接近一倍。如果是纯 CPU 推理耗时大约 150ms 到 300ms具体取决于 CPU 性能和输入尺寸。4.3 嵌入式设备部署的考虑热搜里有不少人问 YOLOv8 训练好的模型怎么部署到嵌入式设备。嵌入式部署的目标通常分两类一类是树莓派这种带 Linux 系统的开发板另一类是 STM32 这种裸机 MCU。树莓派部署相对简单安装好 PyTorch 或者 onnxruntime 后把模型和推理脚本放进去就能运行。实测树莓派 4B 上用 YOLOv8n 推理一张 640 分辨率的图片耗时大约 800ms做到准实时。优化方向是把模型量化成 FP16 或者 INT8可以再提速 1 到 2 倍。STM32 这类 MCU 上跑 YOLOv8 就很吃力了因为 YOLOv8 的参数量和计算量对 MCU 来说过于庞大。通常的做法是先蒸馏或者剪枝得到一个很小的模型再量化成 INT8最后用 CMSIS-NN 或 TensorFlow Lite Micro 框架部署。我自己尝试过这条路最终 YOLOv8n 的 INT8 量化权重大概 5MB在 STM32F407 上推理一张 320 分辨率的图需要几秒钟只能算实验性探索。如果真的要在嵌入式上做水果识别建议考虑更轻量的方案比如 SSD-MobileNet 或者自定义轻量 CNN。5. 常见问题与排查技巧实录5.1 环境相关的典型报错与解决方式报错一ultralytics 模块不存在。大概率是环境没装好。确认当前环境是否有 ultralytics 包确认当前解释器是否为项目所在虚拟环境。这两点检查完基本能解决 90% 的问题。报错二CUDA error: out of memory。这是显存溢出。解决方案按上面讲过的顺序试降低 batch、降低 imgsz、更换更小的模型。报错三DataLoader worker (pid) is killed by signal。Windows 下很常见。把 workers 设为 0 或者 1再把 multiprocessing 的 start method 改为 spawn 方式基本能解决。报错四NVIDIA GeForce GTX 1660 Ti 与 CUDA 版本不兼容。注意显卡驱动需要支持对应的 CUDA 版本。GTX 16 系列属于 Turing 架构对 CUDA 11.x 支持良好但用 CUDA 12.x 也没问题只需要选择对应的 PyTorch 版本。5.2 训练效果不理想的排查路径模型训练完后如果效果不好我通常按以下顺序排查标注文件是否正确可视化标注框确认 category id 和 bbox 坐标是否对准了目标→ 数据集划分是否合理确认训练集和验证集的目标类别分布相似→ 超参数是否合适学习率、batch、epochs 是否合理→ 模型结构是否有问题先跑通 baseline 再改结构→ 数据是否充足类别不均衡时增加图片数量或应用更强的数据增强。有个很隐蔽的问题是训练集和验证集数据泄露。比如同一个视频里抽帧出来的图片有的进了训练集有的进了验证集模型会在验证集上表现得虚高。建议在划分数据前先按图片相似性去重或者保证来自同一场景的图片只出现在一个集合中。5.3 推理阶段性能优化的经验推理性能优化有几种思路。模型层面优先考虑裁剪输入尺寸、采用更小的模型版本、导出成 ONNX 或 TensorRT。推理框架层面可以用半精度推理在 GPU 上开启 fp16 模式批量推理时充分利用 batch 维度开启 TensorRT 时用动态 shape 提高吞吐量。代码层面注意图片预处理方式比如用 cv2 的 efficient resize 方法替换 PIL 的 resize整体提速明显。视频流推理的优化点在于不要对每一帧都做全流程预处理和推理可以结合实际场景降采样处理比如每两帧取一帧推理或者动态调节推理分辨率在保证识别率的前提下大幅降低 CPU 占用。6. 项目经验总结与后续扩展方向整个项目做下来我最大的体会是目标检测项目最大的坑往往不在模型训练而在数据。数据量的多少、标注质量的高低直接决定模型效果的上限。要想效果好花在数据上的时间至少要占整个项目周期的一半以上这是绕不开的。另一个体会是项目工程化能力很重要。同一个模型有没有好的界面、有没有好的推理封装、有没有合理的错误处理直接决定了项目能不能交付。很多初学者训练完模型就以为项目结束了但真正的交付是从模型训练完成后才开始的。如果继续往下做有几个方向值得探索。第一是扩展更多类别比如加入蔬菜、干果品类让系统覆盖更广的使用场景。第二是引入轻量化网络结构比如在 YOLOv8n 基础上做剪枝量化提升推理速度。第三是做一个移动端 App 版本把模型转换到 NCNN 或 MNN 框架。第四是结合采摘机器人等应用场景把识别结果转化为机械臂的采摘坐标形成完整的落地闭环。最后分享一个小经验训练最终的 best.pt 权重一定要单独备份我用网盘存了三份因为训练成本真的不低一次失败可能就要重训十几个小时。另外训练、验证、推理三个阶段的代码分别放在不同文件里日志和权重分开保存这样项目后期维护能省心很多。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价