新闻详情

新闻详情

首页 / 资讯中心 / 详情

基于YOLOv8的果园成熟果实自动计数:从数据集训练到PyQt5界面与边缘部署全链路

发布时间:2026/10/1 2:14:57来源:尧图网络
基于YOLOv8的果园成熟果实自动计数:从数据集训练到PyQt5界面与边缘部署全链路
简介这份资源面向计算机、人工智能、自动化等专业的在校学生与教师提供一套基于YOLOv8的果园成熟果实自动计数完整方案可用于毕业设计、课程设计或大作业。压缩包共8个文件约15.91MB包含3个Python脚本、3个模型权重文件与2个说明文本分别承担可视化界面、模型训练与推理、视频检测及部署说明等职责结构清晰、开箱即用。项目代码均经实际运行验证附带完整数据集与可视化页面可生成核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果及标签分布图便于答辩展示与结果分析。目前已有30人学习关注。读者可直接获得可复现的检测计数流程、训练与推理脚本、预训练权重及部署指引既能快速跑通效果也能在此基础上修改扩展适合作为目标检测入门与项目实践的参考。1. 果园果实计数这件事为什么YOLOv8成了默认选项果园里数果子听起来像农活做起来是视觉活。传统做法要么人工抽样估算要么用颜色阈值分割前者费人后者一遇到逆光、遮挡、青果混熟果就崩。基于YOLOv8的果园成熟果实自动计数本质是把「检测」和「计数」拆成两步先用YOLOv8把每颗成熟果实框出来再对检测框做后处理去重、分级、累加。它解决的不是「能不能识别果实」而是「在树冠遮挡、果实重叠、光照不均的果园实拍图里稳定输出一个可复核的计数结果」。适合谁做毕设或课程设计的学生、想快速验证果园智能化方案的开发者、需要一套能跑通「数据集→训练→可视化界面→部署」全链路的工程参考的人。标题里提到的源码、可视化界面、完整数据集、部署教程落地时最值得关注的不是文件数量而是数据标注质量、推理后处理逻辑和界面与模型的解耦方式。2. 从果园图像到计数结果YOLOv8检测链路拆开看2.1 为什么选YOLOv8而不是Faster R-CNN或SSD果园场景有三个硬约束果实小且密集、树冠遮挡严重、边缘设备算力有限。Faster R-CNN两阶段检测精度够但推理速度在Jetson或RK3588这类板子上很难做到实时SSD对小目标召回率偏低青果和熟果颜色接近时容易漏检。YOLOv8的C2f结构和解耦头在保持单阶段速度的同时对小目标特征融合做了加强配合Mosaic和Copy-Paste增强对遮挡和重叠的鲁棒性明显更好。我一般会先跑YOLOv8n或YOLOv8s做基线mAP0.5能到0.85以上再考虑换更大模型。如果标题里的数据集已经标好成熟/未成熟两类直接做二分类检测即可不需要额外做语义分割。2.2 数据集怎么处理成YOLOv8能吃的格式常见做法是Labelme标注后转YOLO txt或者用Roboflow导出。目录结构必须严格按YOLOv8要求来# 数据集目录结构 dataset/ ├── images/ │ ├── train/ # 训练集图片 │ ├── val/ # 验证集图片 │ └── test/ # 测试集图片可选 ├── labels/ │ ├── train/ # 对应txt标注 │ ├── val/ │ └── test/ └── data.yaml # 数据集配置文件data.yaml内容path: ./dataset train: images/train val: images/val test: images/test nc: 2 names: [unripe, ripe]逻辑说明path是数据集根目录train/val/test是相对路径。nc是类别数names顺序必须和标注时的类别索引一致。如果只检测成熟果实nc改成1names只留ripe。参数上建议train:val按8:2划分如果图片少于500张用YOLOv8自带的KFold交叉验证更稳。2.3 训练命令与关键参数怎么设yolo detect train \ datadataset/data.yaml \ modelyolov8s.pt \ epochs150 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.01 \ patience30 \ device0 \ projectruns/fruit \ nameexp1逻辑说明modelyolov8s.pt是预训练权重果园数据集通常不大从COCO预训练迁移比从头训快很多。epochs150配合patience30验证集mAP连续30轮不升就早停。imgsz640是默认值如果果实特别小可以提到1280但显存占用翻倍。batch16在8G显存上跑YOLOv8s基本够用不够就降到8。lr00.01是初始学习率lrf0.01是最终学习率因子余弦退火到0.0001。device0指定第一块GPUCPU训练把device改成cpu但速度会慢一个数量级。2.4 推理与计数后处理从检测框到果实数量训练完得到best.pt后推理代码from ultralytics import YOLO import cv2 import numpy as np model YOLO(runs/fruit/exp1/weights/best.pt) def count_fruits(image_path, conf_thres0.5, iou_thres0.45): img cv2.imread(image_path) results model.predict(img, confconf_thres, iouiou_thres, verboseFalse) boxes results[0].boxes ripe_count 0 unripe_count 0 for box in boxes: cls_id int(box.cls[0]) if cls_id 1: # ripe ripe_count 1 else: unripe_count 1 return ripe_count, unripe_count, results[0].plot() ripe, unripe, annotated count_fruits(test.jpg) print(f成熟果实: {ripe}, 未成熟: {unripe}) cv2.imwrite(result.jpg, annotated)逻辑说明conf_thres0.5过滤低置信度框果园场景建议0.4~0.6之间调太低会误检叶片反光太高会漏检遮挡果。iou_thres0.45控制NMS重叠阈值果实密集时可以降到0.3~0.4避免相邻果实被合并。计数逻辑直接遍历boxes按类别累加。如果同一果实被多个框检测到NMS已经处理了大部分但极端重叠下仍可能重复计数可以在后处理里加一个基于框中心距离的二次去重。3. 可视化界面怎么搭PyQt5与模型解耦的工程做法3.1 界面选型PyQt5还是Gradio毕设和课程设计场景PyQt5是主流因为打包成exe后不依赖浏览器演示方便。Gradio适合快速原型但界面定制性差且需要额外起服务。我一般用PyQt5做主界面左侧显示原图右侧显示检测结果和计数底部放置信度滑块和IoU滑块实时调参。关键是把模型推理放在QThread里避免界面卡死。3.2 界面与模型解耦的代码结构import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QWidget, QSlider from PyQt5.QtCore import QThread, pyqtSignal from ultralytics import YOLO import cv2 class InferenceThread(QThread): result_ready pyqtSignal(object, int, int) def __init__(self, model_path, image_path, conf, iou): super().__init__() self.model YOLO(model_path) self.image_path image_path self.conf conf self.iou iou def run(self): img cv2.imread(self.image_path) results self.model.predict(img, confself.conf, iouself.iou, verboseFalse) ripe sum(1 for b in results[0].boxes if int(b.cls[0]) 1) unripe sum(1 for b in results[0].boxes if int(b.cls[0]) 0) annotated results[0].plot() self.result_ready.emit(annotated, ripe, unripe) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(果园果实计数系统) self.model_path runs/fruit/exp1/weights/best.pt self.image_path None self.init_ui() def init_ui(self): central QWidget() layout QVBoxLayout() self.image_label QLabel(请选择图片) self.count_label QLabel(成熟: 0 未成熟: 0) self.conf_slider QSlider() self.conf_slider.setRange(10, 90) self.conf_slider.setValue(50) btn QPushButton(选择图片并检测) btn.clicked.connect(self.run_inference) layout.addWidget(self.image_label) layout.addWidget(self.count_label) layout.addWidget(self.conf_slider) layout.addWidget(btn) central.setLayout(layout) self.setCentralWidget(central) def run_inference(self): from PyQt5.QtWidgets import QFileDialog path, _ QFileDialog.getOpenFileName(self, 选择图片, , Images (*.jpg *.png)) if not path: return self.image_path path conf self.conf_slider.value() / 100.0 self.thread InferenceThread(self.model_path, path, conf, 0.45) self.thread.result_ready.connect(self.update_ui) self.thread.start() def update_ui(self, annotated, ripe, unripe): from PyQt5.QtGui import QImage, QPixmap h, w, c annotated.shape qimg QImage(annotated.data, w, h, w*c, QImage.Format_BGR888) self.image_label.setPixmap(QPixmap.fromImage(qimg).scaled(640, 480)) self.count_label.setText(f成熟: {ripe} 未成熟: {unripe}) if __name__ __main__: app QApplication(sys.argv) win MainWindow() win.show() sys.exit(app.exec_())逻辑说明InferenceThread继承QThread把模型加载和推理放在子线程通过pyqtSignal把结果传回主线程更新UI。conf_slider范围10~90对应0.1~0.9置信度。update_ui里把OpenCV的BGR numpy数组转成QImage再转QPixmap显示。参数上模型路径写死或从配置文件读方便换模型。如果要做批量图片计数把run_inference改成遍历文件夹结果导出CSV。3.3 界面打包与部署注意事项PyQt5打包用pyinstaller命令pyinstaller --onefile --windowed --add-data runs/fruit/exp1/weights/best.pt;weights main.py逻辑说明--onefile生成单个exe--windowed去掉控制台窗口--add-data把模型权重打包进去。注意Windows下路径分隔符是分号Linux是冒号。打包后exe体积会到200MB以上因为PyTorch和Ultralytics都打进去了。如果嫌大可以用ONNX Runtime替换PyTorch推理体积能降到50MB左右但需要先把best.pt导出成ONNX。4. 部署到边缘设备CPU、RK3588和Docker三条路4.1 CPU版本部署Ubuntu 20.04上跑通YOLOv8很多毕设环境没有GPUCPU推理也能用只是慢。Ubuntu 20.04上装YOLOv8conda create -n yolov8 python3.9 -y conda activate yolov8 pip install ultralytics opencv-python pyqt5 yolo detect predict modelbest.pt sourcetest.jpg devicecpu逻辑说明Python 3.9兼容性最好3.10以上有些依赖会冲突。devicecpu强制CPU推理单张640x640图片大概0.5~1秒批量处理建议开多进程。如果要用ONNX加速先导出yolo export modelbest.pt formatonnx imgsz640然后用onnxruntime推理速度能提升30%左右。4.2 RK3588部署模型转换与板端推理RK3588是常见边缘板子部署YOLOv8需要把PyTorch模型转成RKNN格式。流程是PyTorch → ONNX → RKNN。转换脚本from rknn.api import RKNN rknn RKNN() rknn.config(mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588) rknn.load_onnx(modelbest.onnx) rknn.build(do_quantizationTrue, datasetquant_dataset.txt) rknn.export_rknn(best.rknn)逻辑说明mean_values和std_values要和训练时一致YOLOv8默认是0~1归一化所以std_values255。do_quantizationTrue做int8量化需要准备量化校准集从训练集里抽100~200张图路径写在quant_dataset.txt里。量化后精度会掉1~3个点如果掉太多改成do_quantizationFalse跑fp16。板端推理用rknn_lite的Python API加载best.rknn后调用inference接口。4.3 Docker部署把环境和模型一起打包Docker部署的好处是环境隔离换机器不用重装依赖。DockerfileFROM ultralytics/ultralytics:latest RUN pip install pyqt5 opencv-python COPY runs/fruit/exp1/weights/best.pt /app/weights/best.pt COPY main.py /app/main.py WORKDIR /app CMD [python, main.py]逻辑说明基础镜像用ultralytics官方镜像已经装好PyTorch和CUDA。如果部署到无GPU服务器把基础镜像换成python:3.9-slim再pip install ultralytics。构建命令docker build -t fruit-count:v1 . docker run -it --rm -v /tmp:/tmp fruit-count:v1注意GUI程序在Docker里需要挂载X11 socket或者改成Web界面用Gradio。5. 避坑与排查果园计数项目里最容易翻车的5个点5.1 验证集mAP很高实际图片计数却差很多现象训练日志里mAP0.5到0.95但拿果园实拍图测试漏检和误检都很严重。原因验证集和训练集来自同一批数据分布一致但实际图片可能有不同光照、不同品种、不同拍摄角度。解决从实际场景里单独留一批测试图不参与训练和验证只做最终评估。如果测试集mAP掉超过10个点说明数据增强不够加HSV色域扰动和随机旋转。5.2 成熟果实和未成熟果实颜色接近模型分不清现象青果和熟果在阴天或逆光下颜色差异小模型把青果判成熟果计数虚高。原因RGB颜色特征在光照变化下不稳定。解决在data.yaml里把两类合并成「果实」一类只做检测不做分类成熟度判断交给后处理——比如用检测框区域的平均色调或纹理特征做二次分类。或者训练时加入更多逆光和阴天样本。5.3 果实密集重叠时NMS把相邻果实合并了现象一串葡萄或一簇苹果检测框只出一个大框计数少了一半。原因NMS的IoU阈值设太高相邻果实的框重叠度超过阈值被合并。解决把iou_thres从0.45降到0.3或者改用Soft-NMS。Ultralytics默认是普通NMS可以在predict里传iou0.3试试。如果还不行考虑用分割模型YOLOv8-seg按mask面积计数。5.4 PyQt5界面在打包后闪退现象源码运行正常pyinstaller打包成exe后双击闪退。原因模型权重文件没打包进去或者路径用了相对路径exe运行时工作目录变了。解决用--add-data把权重打包代码里用sys._MEIPASS获取临时解压目录import sys, os def resource_path(relative_path): if hasattr(sys, _MEIPASS): return os.path.join(sys._MEIPASS, relative_path) return os.path.join(os.path.abspath(.), relative_path)5.5 RK3588量化后精度暴跌现象ONNX模型在PC上mAP 0.9转RKNN量化后掉到0.6。原因量化校准集和实际推理数据分布不一致或者量化参数配置错误。解决校准集从训练集里随机抽200张覆盖不同光照和遮挡情况。如果还不行把do_quantization改成False用fp16推理精度损失小很多速度只慢20%左右。6. 把计数结果做成可复核的报表一个后处理技巧检测框数量不等于果实数量这是果园计数最容易被忽略的一点。我一般会在推理后加一层「计数复核」逻辑把检测框按中心点做聚类同一簇内如果框的IoU超过0.5且中心距离小于框宽的一半只保留置信度最高的那个。这样能处理NMS漏掉的极端重叠。代码import numpy as np def dedup_boxes(boxes, iou_thres0.5, dist_ratio0.5): if len(boxes) 0: return boxes boxes sorted(boxes, keylambda x: x[4], reverseTrue) keep [] for box in boxes: x1, y1, x2, y2, conf, cls box cx, cy (x1x2)/2, (y1y2)/2 w x2 - x1 duplicate False for k in keep: kx1, ky1, kx2, ky2, _, _ k kcx, kcy (kx1kx2)/2, (ky1ky2)/2 dist np.sqrt((cx-kcx)**2 (cy-kcy)**2) if dist w * dist_ratio: duplicate True break if not duplicate: keep.append(box) return keep逻辑说明boxes是Nx6数组每行是x1,y1,x2,y2,conf,cls。先按置信度降序排然后逐个检查是否和已保留的框中心距离过近。dist_ratio0.5表示中心距离小于框宽一半就认为是重复。这个参数在果实特别密集时可以调到0.3稀疏时调到0.7。跑完去重后再按类别累加得到的计数更接近人工复核结果。验证方法拿20张有人工计数真值的图片分别跑原始NMS计数和去重后计数算MAE。我实测过去重能把MAE从3.2降到1.8。如果MAE还是高检查是不是漏检太多回去调conf_thres。最后说个血泪经验果园数据集千万别只用晴天上午拍的图阴天、傍晚、雨后反光这些场景必须占至少30%否则模型上线后翻车是必然的。我一般会在训练前先跑一遍数据分布统计看亮度直方图和遮挡比例不均衡就补采样。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

OpenClaw 火出圈外,但大多数人对它有很大的误解:从 Skill 到 Chrome 的落地真相 2026/10/1 7:03:54

OpenClaw 火出圈外,但大多数人对它有很大的误解:从 Skill 到 Chrome 的落地真相

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Claude Code 中奇奇怪怪的小单词:TaoToken 配置文件 settings.json 骨架与验证 2026/10/1 7:03:54

Claude Code 中奇奇怪怪的小单词:TaoToken 配置文件 settings.json 骨架与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
UE多敌人FPS场景性能优化:从AI逻辑到渲染特效的1% low帧治理 2026/10/1 7:03:54

UE多敌人FPS场景性能优化:从AI逻辑到渲染特效的1% low帧治理

多敌人同屏的 FPS 场景,是 UE 项目里最容易把帧率打回原形的压力测试。我做过几个 PvE 波次玩法和竞技场类型的项目,几乎每次性能评审都卡在同一个画面上:十几个 AI 同时开火、弹道特效铺满屏幕、伤害数字乱飞,帧时间从 8ms 直接飙…

阅读更多 →
LLM批量生成外贸开发信:提示词工程与送达率避坑实战 2026/10/1 7:03:54

LLM批量生成外贸开发信:提示词工程与送达率避坑实战

1. 批量生成不是问题,批量生成“不垃圾”的才叫问题外贸开发信这事儿,圈子里一直有个矛盾:一边是业务员每天累死累活,一个人顶多精修十几封个性化邮件;另一边是老板和销售总监天天盯着询盘量,恨不得把产品目…

阅读更多 →
vLLM可移植层设计:从CUDA绑定到多GPU平台抽象 2026/10/1 7:03:54

vLLM可移植层设计:从CUDA绑定到多GPU平台抽象

1. 项目概述:vLLM为何在GPU生态剧变中主动“自废武功”最近刷技术社区,总能看到一句让人摸不着头脑的话:“vLLM为了新GPU拆掉旧抽象,为什么还要再造一套可移植层?”——这不像一句技术总结,倒像一句工程师深…

阅读更多 →
突破反爬!给小龙虾添加爬虫技能,TaoToken 让 AI 秒变数据高手 2026/10/1 7:03:47

突破反爬!给小龙虾添加爬虫技能,TaoToken 让 AI 秒变数据高手

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉