智慧农业检测-基于YOLOv8深度学习的苹果成熟度检测系统
基于深度学习YOLOv8+PyQt5的苹果成熟度检测系统(完整源码源文件+已标注的数据集+训练好的模型)
包含登录页面+yolov5和yolov11训练结果可执行替换
数据集分布:4种分类,4513张图片 训练集3610验证集903
识别分类:‘高度成熟’, ‘中度成熟’, ‘低度成熟’, ‘坏苹果’
Python + PyQt5可视化界面
可对图片,视频,摄像头进行识别
这是一个非常完整且实用的计算机视觉项目。基于你提供的项目结构和截图,我为你整理了构建这个基于 YOLOv8 的苹果成熟度检测系统所需的核心代码。
作为参考 几个关键模块:环境配置、数据集配置、训练代码以及PyQt5 界面主程序。
1. 项目目录结构
项目文件夹结构如下:
AppleDetection/ ├── datasets/ # 存放数据集 │ └── apple_data/ # 你的苹果数据集文件夹 │ ├── images/ │ ├── labels/ │ └── data.yaml # 数据集配置文件 ├── runs/ # 训练结果保存目录 ├── UI/ # 界面资源(图标等) ├── utils/ # 工具类 │ ├── config.py # 配置文件 │ └── ... ├── weights/ # 存放模型权重 │ └── best.pt # 训练好的模型 ├── main.py # 主程序(界面+逻辑) ├── train.py # 训练脚本 └── requirements.txt # 依赖库2. 环境依赖 (requirements.txt)
首先,你需要安装必要的 Python 库。
torch>=1.8.0 torchvision>=0.9.0 ultralytics>=8.0.0 # 包含YOLOv8/v11 PyQt5>=5.15.0 opencv-python>=4.5.0 numpy>=1.19.0 pandas>=1.2.0 matplotlib>=3.4.03. 数据集配置 (datasets/apple_data/data.yaml)
你需要创建一个 yaml 文件来告诉模型你的类别是什么。
path:../datasets/apple_data# 数据集根路径train:images/train# 训练集图片路径val:images/val# 验证集图片路径test:images/test# 测试集图片路径# 类别数量和名称 (根据你的描述)nc:4names:['高度成熟','中度成熟','低度成熟','坏苹果']4. 训练代码 (train.py)
使用 YOLOv8 进行训练非常简单,运行此脚本即可得到best.pt。
fromultralyticsimportYOLOdeftrain_model():# 1. 加载预训练模型 (推荐从 yolov8n.pt 开始,速度快且效果好)# 如果你想用 v11,只需将 'yolov8n.pt' 改为 'yolov11n.pt'model=YOLO('yolov8n.pt')# 2. 开始训练results=model.train(data='datasets/apple_data/data.yaml',# 数据集配置文件路径epochs=100,# 训练轮数imgsz=640,# 输入图像大小batch=16,# 批大小,根据显存调整name='apple_train_v8',# 保存的文件夹名称device=0iftorch.cuda.is_available()else'cpu'# 自动选择 GPU 或 CPU)if__name__=='__main__':train_model()5. 主程序代码 (main.py)
这是系统的核心,包含了 PyQt5 界面设计、视频流处理、YOLO 推理逻辑以及截图中的数据展示功能。
importsysimportcv2importtorchimportnumpyasnpimportpandasaspdfromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QLabel,QPushButton,QVBoxLayout,QHBoxLayout,QWidget,QFileDialog,QTableWidget,QTableWidgetItem,QMessageBox,QSlider,QSpinBox)fromPyQt5.QtGuiimportQImage,QPixmap,QFontfromPyQt5.QtCoreimportQt,QTimerfromultralyticsimportYOLO# --- 全局配置 ---MODEL_PATH='weights/best.pt'# 你的模型路径CONFIDENCE_THRESHOLD=0.45IOU_THRESHOLD=0.5classAppleDetectionSystem(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("基于深度学习的苹果成熟度检测系统")self.setGeometry(100,100,1200,800)# 1. 加载模型self.device='cuda'iftorch.cuda.is_available()else'cpu'self.model=YOLO(MODEL_PATH).to(self.device)# 2. 初始化变量self.timer=QTimer()self.timer.timeout.connect(self.update_frame)self.cap=Noneself.current_image_path=""self.results_data=[]# 用于存储表格数据# 3. 构建UIself.init_ui()definit_ui(self):# 主布局main_widget=QWidget()main_layout=QHBoxLayout(main_widget)self.setCentralWidget(main_widget)# --- 左侧:视频/图像显示区域 ---self.image_label=QLabel(self)self.image_label.setFixedSize(800,600)self.image_label.setStyleSheet("background-color: #000000; border: 1px solid #ccc;")self.image_label.setAlignment(Qt.AlignCenter)# --- 右侧:控制面板 ---right_layout=QVBoxLayout()# 参数设置param_group=self.create_group("检测参数设置")param_layout=QVBoxLayout()self.conf_spin=QSpinBox()self.conf_spin.setRange(0,100)self.conf_spin.setValue(45)self.conf_spin.valueChanged.connect(self.update_params)param_layout.addWidget(QLabel("置信度阈值:"))param_layout.addWidget(self.conf_spin)self.iou_spin=QSpinBox()self.iou_spin.setRange(0,100)self.iou_spin.setValue(50)self.iou_spin.valueChanged.connect(self.update_params)param_layout.addWidget(QLabel("IOU 阈值:"))param_layout.addWidget(self.iou_spin)param_group.setLayout(param_layout)# 检测结果信息info_group=self.create_group("检测结果")info_layout=QVBoxLayout()self.info_label=QLabel("等待检测...")info_layout.addWidget(self.info_label)info_group.setLayout(info_layout)# 操作按钮btn_layout=QHBoxLayout()self.btn_img=QPushButton("打开图片")self.btn_img.clicked.connect(self.open_image)self.btn_video=QPushButton("打开视频")self.btn_video.clicked.connect(self.open_video)self.btn_cam=QPushButton("打开摄像头")self.btn_cam.clicked.connect(self.open_camera)self.btn_save=QPushButton("保存结果")self.btn_save.clicked.connect(self.save_results)btn_layout.addWidget(self.btn_img)btn_layout.addWidget(self.btn_video)btn_layout.addWidget(self.btn_cam)btn_layout.addWidget(self.btn_save)# 底部表格self.table=QTableWidget()self.table.setColumnCount(5)self.table.setHorizontalHeaderLabels(["序号","文件路径","类别","置信度","坐标位置"])self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)# 组装右侧right_layout.addWidget(param_group)right_layout.addWidget(info_group)right_layout.addLayout(btn_layout)right_layout.addWidget(QLabel("检测结果列表:"))right_layout.addWidget(self.table)main_layout.addWidget(self.image_label)main_layout.addLayout(right_layout)defcreate_group(self,title):group=QWidget()group.setTitle(title)# 注意:QWidget没有setTitle,实际需用QGroupBox# 这里为了简化代码,直接返回QWidget,实际开发请用 QGroupBoxfromPyQt5.QtWidgetsimportQGroupBox box=QGroupBox(title)box.setLayout(QVBoxLayout())returnbox# --- 核心逻辑 ---defupdate_params(self):# 动态更新参数globalCONFIDENCE_THRESHOLD,IOU_THRESHOLD CONFIDENCE_THRESHOLD=self.conf_spin.value()/100.0IOU_THRESHOLD=self.iou_spin.value()/100.0defopen_image(self):path,_=QFileDialog.getOpenFileName(self,"选择图片","","Image Files (*.png *.jpg *.bmp)")ifpath:self.current_image_path=path self.process_image(path)defopen_video(self):path,_=QFileDialog.getOpenFileName(self,"选择视频","","Video Files (*.mp4 *.avi)")ifpath:self.cap=cv2.VideoCapture(path)self.timer.start(30)defopen_camera(self):self.cap=cv2.VideoCapture(0)self.timer.start(30)defprocess_image(self,img_path):# 读取图片img=cv2.imread(img_path)img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)# YOLO 推理results=self.model(img_rgb,conf=CONFIDENCE_THRESHOLD,iou=IOU_THRESHOLD)result=results[0]# 绘制结果annotated_img=result.plot()# 自带绘制框和标签# 解析数据更新UIself.update_results_table(img_path,result)self.display_image(annotated_img)defupdate_frame(self):ifself.cap:ret,frame=self.cap.read()ifret:# 推理results=self.model(frame,conf=CONFIDENCE_THRESHOLD,iou=IOU_THRESHOLD)result=results[0]annotated_frame=result.plot()self.display_image(annotated_frame)# 如果是单张图片模式,更新表格(视频流通常只展示不记录表格以免卡顿,或者做抽样记录)# self.update_results_table("Camera", result)else:self.timer.stop()self.cap.release()defupdate_results_table(self,source,result):self.table.setRowCount(0)# 清空boxes=result.boxes self.info_label.setText(f"检测到目标数:{len(boxes)}")fori,boxinenumerate(boxes):cls_id=int(box.cls[0])conf=box.conf[0]xyxy=box.xyxy[0].cpu().numpy().astype(int)label=result.names[cls_id]self.table.insertRow(i)self.table.setItem(i,0,QTableWidgetItem(str(i+1)))self.table.setItem(i,1,QTableWidgetItem(source))self.table.setItem(i,2,QTableWidgetItem(label))self.table.setItem(i,3,QTableWidgetItem(f"{conf:.2f}"))self.table.setItem(i,4,QTableWidgetItem(str(xyxy)))defdisplay_image(self,img):# OpenCV (BGR) -> Qt (RGB)iflen(img.shape)==3:h,w,c=img.shape q_img=QImage(img.data,w,h,w*c,QImage.Format_RGB888)else:h,w=img.shape q_img=QImage(img.data,w,h,w,QImage.Format_Grayscale8)pixmap=QPixmap.fromImage(q_img)# 自适应Label大小self.image_label.setPixmap(pixmap.scaled(self.image_label.size(),Qt.KeepAspectRatio))defsave_results(self):# 简单的导出逻辑data=[]forrowinrange(self.table.rowCount()):row_data=[]forcolinrange(self.table.columnCount()):item=self.table.item(row,col)row_data.append(item.text()ifitemelse"")data.append(row_data)df=pd.DataFrame(data,columns=["序号","文件路径","类别","置信度","坐标"])path,_=QFileDialog.getSaveFileName(self,"保存结果","","Excel Files (*.xlsx)")ifpath:df.to_excel(path,index=False)QMessageBox.information(self,"成功","结果已保存!")if__name__=='__main__':app=QApplication(sys.argv)window=AppleDetectionSystem()window.show()sys.exit(app.exec_())6. 如何运行
- 准备数据:图片按照
images/train,images/val等结构放好,并生成data.yaml。 - 训练模型:运行
python train.py。训练完成后,将runs/detect/apple_train_v8/weights/best.pt复制到项目根目录下的weights文件夹。 - 运行系统:运行
python main.py。 - 操作:点击“打开图片”或“打开摄像头”