基于深度学习YOLOv10的水果分类检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)
一、项目介绍摘要本项目基于YOLOv10深度学习框架开发了一套高精度水果多目标分类检测系统能够同时识别六种常见水果苹果(Apple)、香蕉(Banana)、芒果(Mango)、橙子(Orange)、菠萝(Pineapple)和西瓜(Watermelon)。系统通过对水果图像进行实时分析可准确识别水果种类并定位其位置为智能零售、自动分拣、农业收获等场景提供高效解决方案。项目构建了包含1007张高质量标注图像的数据集其中训练集768张验证集129张测试集110张。系统特别优化了重叠水果、部分遮挡和不同成熟度等复杂场景的识别能力显著提升了水果检测的准确率和鲁棒性。项目意义水果自动检测技术在现代农业和零售领域具有重要应用价值本项目的实施将带来以下显著效益提升分拣效率传统人工分拣效率低而本系统配合自动化设备可将效率提升同时降低分拣错误率。降低人力成本水果分拣是劳动密集型工作本系统可减少人工需求。标准化质量管控系统可客观评估水果大小、形状等特征确保分拣标准一致性提升产品品质和市场竞争力。收获辅助决策通过田间实时检测可精准评估不同区域水果成熟度优化收获时间和路线减少采收损耗。零售智能化升级应用于无人超市、自动售货机等场景实现水果自动识别和结算提升消费体验。数据驱动种植长期检测数据可分析品种表现、生长状况等为种植规划提供数据支持。减少食物浪费精准的成熟度判断可优化供应链管理可降低运输和存储损耗。目录一、项目介绍摘要项目意义二、项目功能展示系统功能图片检测视频检测摄像头实时检测三、数据集介绍数据集概述数据集特点数据集配置文件数据集制作流程四、项目环境配置创建虚拟环境pycharm中配置anaconda安装所需要库五、模型训练训练代码训练结果六、核心代码七、项目源码视频下方简介内基于深度学习YOLOv10的水果分类检测系统YOLOv10YOLO数据集UI界面Python项目源码模型_哔哩哔哩_bilibili基于深度学习YOLOv10的水果分类检测系统YOLOv10YOLO数据集UI界面Python项目源码模型二、项目功能展示系统功能✅图片检测可对图片进行检测返回检测框及类别信息。✅视频检测支持视频文件输入检测视频中每一帧的情况。✅摄像头实时检测连接USB 摄像头实现实时监测。✅参数实时调节置信度和IoU阈值图片检测该功能允许用户通过单张图片进行目标检测。输入一张图片后YOLO模型会实时分析图像识别出其中的目标并在图像中框出检测到的目标输出带有目标框的图像。视频检测视频检测功能允许用户将视频文件作为输入。YOLO模型将逐帧分析视频并在每一帧中标记出检测到的目标。最终结果可以是带有目标框的视频文件或实时展示适用于视频监控和分析等场景。摄像头实时检测该功能支持通过连接摄像头进行实时目标检测。YOLO模型能够在摄像头拍摄的实时视频流中进行目标检测实时识别并显示检测结果。此功能非常适用于安防监控、无人驾驶、智能交通等应用提供即时反馈。核心特点高精度基于YOLO模型提供精确的目标检测能力适用于不同类型的图像和视频。实时性特别优化的算法使得实时目标检测成为可能无论是在视频还是摄像头实时检测中响应速度都非常快。批量处理支持高效的批量图像和视频处理适合大规模数据分析。三、数据集介绍数据集概述本项目构建了专业的水果多目标检测数据集共包含1007张精心标注的图像按照约7.5:1.5:1的比例划分为训练集(768张)、验证集(129张)和测试集(110张)。数据集涵盖六类常见水果苹果(Apple)包含红富士、嘎啦等多个品种不同颜色和大小香蕉(Banana)包含不同成熟度(青色到带斑点)的样本芒果(Mango)涵盖台农、凯特等多个品种橙子(Orange)包括脐橙、血橙等类型菠萝(Pineapple)包含完整菠萝和切开的样本西瓜(Watermelon)包含整个西瓜和切块的样本数据集特点多场景覆盖数据集包含超市货架、果园环境、分拣流水线、家庭场景等多种背景确保模型泛化能力。多角度采集每种水果都包含顶部、侧面、底部等多角度图像全面覆盖各种观察视角。成熟度梯度特别关注香蕉等颜色变化明显的水果采集了从未成熟到过熟的全阶段样本。遮挡处理包含部分遮挡样本(如水果重叠、枝叶遮挡等)增强模型鲁棒性。光照变化采集了不同光照条件(强光、弱光、逆光等)下的样本提高光照不变性。特殊状态包含切块、剥皮、腐烂等特殊状态样本扩展应用场景。精细标注采用高精度标注对密集排列水果的边界进行严格区分。数据集配置文件数据集采用YOLO格式进行组织配置文件内容如下# YOLOv10水果分类检测数据集配置文件 path: ../datasets/fruit_detection train: images/train # 768张 val: images/val # 129张 test: images/test # 110张 # 检测类别 nc: 6 names: [Apple, Banana, Mango, Orange, Pineapple, Watermelon] # 训练参数 img_size: 640 # 输入图像尺寸 batch_size: 32 # 批次大小 workers: 6 # 数据加载线程数 hsv_h: 0.015 # 图像色调增强幅度 hsv_s: 0.7 # 图像饱和度增强幅度 hsv_v: 0.4 # 图像亮度增强幅度 # 水果特定参数 maturity_levels: 5 # 成熟度分级数 occlusion_aug: True # 启用遮挡增强数据集制作流程数据采集阶段使用中高端数码相机进行原始图像采集在6个不同场景(果园、超市、仓库等)分别采集样本对每种水果确保覆盖不同品种、大小和成熟度采用三脚架固定拍摄和手持动态拍摄相结合的方式数据标注规范制定详细的《水果标注标准手册》统一各类水果的标注边界对重叠水果采用可见部分标注原则对切块水果根据果肉特征进行分类标注对带包装水果要求同时标注包装和实际水果区域标注质量控制实行初标-复核-仲裁三级质量管控流程使用CVAT标注工具进行多人协作标注对模糊样本进行专家会商确定定期进行标注一致性测试数据增强策略几何增强随机旋转、缩放、裁剪色彩增强模拟不同白平衡、饱和度、对比度条件遮挡增强随机添加模拟枝叶遮挡和水果重叠背景替换将水果抠图后随机组合到新背景中数据集划分原则确保同一批水果不会出现在不同子集平衡各类水果在不同子集中的数量分布验证集和测试集包含更多困难样本保留极端样本作为隐藏测试集持续优化机制建立错误样本回收机制将误检样本加入训练集每季度更新数据集补充新品种和新场景开发自动化工具监控数据集的类别平衡性建立数据版本控制系统追踪数据集演变四、项目环境配置创建虚拟环境首先新建一个Anaconda环境每个项目用不同的环境这样项目中所用的依赖包互不干扰。终端输入conda create -n yolov10 python3.9激活虚拟环境conda activate yolov10安装cpu版本pytorchpip install torch torchvision torchaudiopycharm中配置anaconda安装所需要库pip install -r requirements.txt五、模型训练训练代码from ultralytics import YOLOv10 model_path yolov10s.pt data_path datasets/data.yaml if __name__ __main__: model YOLOv10(model_path) results model.train(datadata_path, epochs500, batch64, device0, workers0, projectruns/detect, nameexp, )根据实际情况更换模型 yolov10n.yaml (nano)轻量化模型适合嵌入式设备速度快但精度略低。 yolov10s.yaml (small)小模型适合实时任务。 yolov10m.yaml (medium)中等大小模型兼顾速度和精度。 yolov10b.yaml (base)基本版模型适合大部分应用场景。 yolov10l.yaml (large)大型模型适合对精度要求高的任务。--batch 64每批次64张图像。--epochs 500训练500轮。--datasets/data.yaml数据集配置文件。--weights yolov10s.pt初始化模型权重yolov10s.pt是预训练的轻量级YOLO模型。训练结果六、核心代码import sys import cv2 import numpy as np from PyQt5.QtWidgets import QApplication, QMessageBox, QFileDialog from PyQt5.QtCore import QThread, pyqtSignal from ultralytics import YOLOv10 from UiMain import UiMainWindow import time import os class DetectionThread(QThread): frame_received pyqtSignal(np.ndarray, np.ndarray, list) # 原始帧, 检测帧, 检测结果 finished_signal pyqtSignal() # 线程完成信号 def __init__(self, model, source, conf, iou, parentNone): super().__init__(parent) self.model model self.source source self.conf conf self.iou iou self.running True def run(self): try: if isinstance(self.source, int) or self.source.endswith((.mp4, .avi, .mov)): # 视频或摄像头 cap cv2.VideoCapture(self.source) while self.running and cap.isOpened(): ret, frame cap.read() if not ret: break # 保存原始帧 original_frame frame.copy() # 检测 results self.model(frame, confself.conf, iouself.iou) annotated_frame results[0].plot() # 提取检测结果 detections [] for result in results: for box in result.boxes: class_id int(box.cls) class_name self.model.names[class_id] confidence float(box.conf) x, y, w, h box.xywh[0].tolist() detections.append((class_name, confidence, x, y)) # 发送信号 self.frame_received.emit( cv2.cvtColor(original_frame, cv2.COLOR_BGR2RGB), cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB), detections ) # 控制帧率 time.sleep(0.03) # 约30fps cap.release() else: # 图片 frame cv2.imread(self.source) if frame is not None: original_frame frame.copy() results self.model(frame, confself.conf, iouself.iou) annotated_frame results[0].plot() # 提取检测结果 detections [] for result in results: for box in result.boxes: class_id int(box.cls) class_name self.model.names[class_id] confidence float(box.conf) x, y, w, h box.xywh[0].tolist() detections.append((class_name, confidence, x, y)) self.frame_received.emit( cv2.cvtColor(original_frame, cv2.COLOR_BGR2RGB), cv2.cvtColor(annotated_frame, cv2.COLOR_BGR2RGB), detections ) except Exception as e: print(fDetection error: {e}) finally: self.finished_signal.emit() def stop(self): self.running False class MainWindow(UiMainWindow): def __init__(self): super().__init__() # 初始化模型 self.model None self.detection_thread None self.current_image None self.current_result None self.video_writer None self.is_camera_running False self.is_video_running False self.last_detection_result None # 新增保存最后一次检测结果 # 连接按钮信号 self.image_btn.clicked.connect(self.detect_image) self.video_btn.clicked.connect(self.detect_video) self.camera_btn.clicked.connect(self.detect_camera) self.stop_btn.clicked.connect(self.stop_detection) self.save_btn.clicked.connect(self.save_result) # 初始化模型 self.load_model() def load_model(self): try: model_name self.model_combo.currentText() self.model YOLOv10(f{model_name}.pt) # 自动下载或加载本地模型 self.update_status(f模型 {model_name} 加载成功) except Exception as e: QMessageBox.critical(self, 错误, f模型加载失败: {str(e)}) self.update_status(模型加载失败) def detect_image(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, 警告, 请先停止当前检测任务) return file_path, _ QFileDialog.getOpenFileName( self, 选择图片, , 图片文件 (*.jpg *.jpeg *.png *.bmp)) if file_path: self.clear_results() self.current_image cv2.imread(file_path) self.current_image cv2.cvtColor(self.current_image, cv2.COLOR_BGR2RGB) self.display_image(self.original_image_label, self.current_image) # 创建检测线程 conf self.confidence_spinbox.value() iou self.iou_spinbox.value() self.detection_thread DetectionThread(self.model, file_path, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status(f正在检测图片: {os.path.basename(file_path)}) def detect_video(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, 警告, 请先停止当前检测任务) return file_path, _ QFileDialog.getOpenFileName( self, 选择视频, , 视频文件 (*.mp4 *.avi *.mov)) if file_path: self.clear_results() self.is_video_running True # 初始化视频写入器 cap cv2.VideoCapture(file_path) frame_width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps cap.get(cv2.CAP_PROP_FPS) cap.release() # 创建保存路径 save_dir results os.makedirs(save_dir, exist_okTrue) timestamp time.strftime(%Y%m%d_%H%M%S) save_path os.path.join(save_dir, fresult_{timestamp}.mp4) fourcc cv2.VideoWriter_fourcc(*mp4v) self.video_writer cv2.VideoWriter(save_path, fourcc, fps, (frame_width, frame_height)) # 创建检测线程 conf self.confidence_spinbox.value() iou self.iou_spinbox.value() self.detection_thread DetectionThread(self.model, file_path, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status(f正在检测视频: {os.path.basename(file_path)}) def detect_camera(self): if self.detection_thread and self.detection_thread.isRunning(): QMessageBox.warning(self, 警告, 请先停止当前检测任务) return self.clear_results() self.is_camera_running True # 创建检测线程 (默认使用摄像头0) conf self.confidence_spinbox.value() iou self.iou_spinbox.value() self.detection_thread DetectionThread(self.model, 0, conf, iou) self.detection_thread.frame_received.connect(self.on_frame_received) self.detection_thread.finished_signal.connect(self.on_detection_finished) self.detection_thread.start() self.update_status(正在从摄像头检测...) def stop_detection(self): if self.detection_thread and self.detection_thread.isRunning(): self.detection_thread.stop() self.detection_thread.quit() self.detection_thread.wait() if self.video_writer: self.video_writer.release() self.video_writer None self.is_camera_running False self.is_video_running False self.update_status(检测已停止) def on_frame_received(self, original_frame, result_frame, detections): # 更新原始图像和结果图像 self.display_image(self.original_image_label, original_frame) self.display_image(self.result_image_label, result_frame) # 保存当前结果帧用于后续保存 self.last_detection_result result_frame # 新增保存检测结果 # 更新表格 self.clear_results() for class_name, confidence, x, y in detections: self.add_detection_result(class_name, confidence, x, y) # 保存视频帧 if self.video_writer: self.video_writer.write(cv2.cvtColor(result_frame, cv2.COLOR_RGB2BGR)) def on_detection_finished(self): if self.video_writer: self.video_writer.release() self.video_writer None self.update_status(视频检测完成结果已保存) elif self.is_camera_running: self.update_status(摄像头检测已停止) else: self.update_status(图片检测完成) def save_result(self): if not hasattr(self, last_detection_result) or self.last_detection_result is None: QMessageBox.warning(self, 警告, 没有可保存的检测结果) return save_dir results os.makedirs(save_dir, exist_okTrue) timestamp time.strftime(%Y%m%d_%H%M%S) if self.is_camera_running or self.is_video_running: # 保存当前帧为图片 save_path os.path.join(save_dir, fsnapshot_{timestamp}.jpg) cv2.imwrite(save_path, cv2.cvtColor(self.last_detection_result, cv2.COLOR_RGB2BGR)) self.update_status(f截图已保存: {save_path}) else: # 保存图片检测结果 save_path os.path.join(save_dir, fresult_{timestamp}.jpg) cv2.imwrite(save_path, cv2.cvtColor(self.last_detection_result, cv2.COLOR_RGB2BGR)) self.update_status(f检测结果已保存: {save_path}) def closeEvent(self, event): self.stop_detection() event.accept() if __name__ __main__: app QApplication(sys.argv) # 设置应用程序样式 app.setStyle(Fusion) # 创建并显示主窗口 window MainWindow() window.show() sys.exit(app.exec_())七、项目源码视频下方简介内完整全部资源文件包括测试图片、视频py文件训练数据集、训练代码、界面代码等这里已打包上传至博主的面包多平台见可参考博客与视频已将所有涉及的文件同时打包到里面点击即可运行完整文件截图如下基于深度学习YOLOv10的水果分类检测系统YOLOv10YOLO数据集UI界面Python项目源码模型_哔哩哔哩_bilibili基于深度学习YOLOv10的水果分类检测系统YOLOv10YOLO数据集UI界面Python项目源码模型

相关新闻

MiniCPM4-0.5B-QAT-Int4-GPTQ-format 小显存llm

MiniCPM4-0.5B-QAT-Int4-GPTQ-format 小显存llm

2026/7/6 12:27:49 阅读更多 →
强烈安利9个AI论文软件,专科生轻松搞定毕业论文!

强烈安利9个AI论文软件,专科生轻松搞定毕业论文!

2026/7/3 20:53:32 阅读更多 →
计算机Java毕设实战-基于springboot的农企商品产品信息管理平台设计与开发【完整源码+LW+部署说明+演示视频,全bao一条龙等】

计算机Java毕设实战-基于springboot的农企商品产品信息管理平台设计与开发【完整源码+LW+部署说明+演示视频,全bao一条龙等】

2026/7/7 5:29:19 阅读更多 →

最新新闻

Web安全必修课:从原理到实战,全面掌握XSS漏洞防御与修复

Web安全必修课:从原理到实战,全面掌握XSS漏洞防御与修复

1. 项目概述:为什么XSS漏洞是每个Web开发者的必修课如果你是一名Web开发者,或者正在管理一个网站,那么“XSS漏洞”这个词对你来说,绝对不应该陌生。它就像潜伏在代码里的幽灵,平时不声不响,一旦被利用&…

2026/7/7 8:56:25 阅读更多 →
Windows 10终极指南:PL-2303旧版芯片驱动完整安装解决方案

Windows 10终极指南:PL-2303旧版芯片驱动完整安装解决方案

Windows 10终极指南:PL-2303旧版芯片驱动完整安装解决方案 【免费下载链接】pl2303-win10 Windows 10 driver for end-of-life PL-2303 chipsets. 项目地址: https://gitcode.com/gh_mirrors/pl/pl2303-win10 还在为Windows 10系统无法正常使用PL-2303串口设…

2026/7/7 8:54:24 阅读更多 →
Token 与时间双维度 ROI:生成质量不是唯一考核指标

Token 与时间双维度 ROI:生成质量不是唯一考核指标

Token 与时间双维度 ROI:生成质量不是唯一考核指标 一、老板问"花这么多钱值不值",你该怎么算 AI 项目的预算审核越来越严格。上季度花了 8 万元在 API 调用上。财务问:这笔钱带来了什么业务价值?传统回答是"提升了…

2026/7/7 8:54:24 阅读更多 →
Java十大排序算法知识点总结

Java十大排序算法知识点总结

一、排序算法概述排序算法是计算机科学中最基础、最重要的算法之一,它负责将一组数据按照特定顺序(升序或降序)重新排列。在Java编程中,掌握各种排序算法的原理、实现和适用场景,对于提升编程能力和解决实际问题至关重…

2026/7/7 8:52:24 阅读更多 →
零壹教育:我们学Python,学的究竟是什么?

零壹教育:我们学Python,学的究竟是什么?

零壹教育:在很多人看来,学Python就是学编程。这个等式,其实把Python的价值大大低估了。Python真正提供的,是一套结构化思考问题的训练路径。当面对一个模糊、复杂的任务时,Python迫使你去拆解环节、定义中间状态、理顺…

2026/7/7 8:52:24 阅读更多 →
Kuikly 是什么?和KMP有什么关系?

Kuikly 是什么?和KMP有什么关系?

Kuikly 是腾讯开源的 Kotlin Multiplatform 跨端框架。 它处理的不是单纯的业务逻辑复用,而是把 UI、布局、事件、Bridge 和部分业务逻辑都放到 KMP 工程里,再分别编译到 Android、iOS、鸿蒙、Web、小程序和 macOS。它解决什么问题 Android 开发看跨平台…

2026/7/7 8:50:23 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻