智慧农业巡检-【YOLOv11】番茄叶片病害智能检测系统(全套源码+数据集+预训练模型)
项目概述
本系统是基于最新 YOLOv11 目标检测算法开发的番茄病害识别方案。配套自主设计的现代化简约 GUI 界面,响应速度快,操作直观。适用于农业智能监测、农作物保护研究及深度学习算法落地参考。
检测分类(共 9 类)
系统经过深度学习训练,可精准识别番茄叶片的以下 9 种状态:
病害类: 早疫病 (Early_Blight)、晚疫病 (Late_Blight)、潜叶蝇 (Leaf_Miner)、叶霉病 (Leaf_Mold)、花叶病毒 (Mosaic_V)、斑枯病 (Septoria)、红蜘蛛 (Spider_M)、黄化曲叶病毒 (YLCV)
健康类: 健康叶片 (Healthy)
数据集说明
包含完整的高质量番茄叶片病害数据集,总计 4000+ 张图像:
规模: 训练集 3079 张,验证集 613 张,测试集 399 张。
格式: 标准 YOLO txt 格式,分类清晰,标注精准。
核心功能
多源检测: 支持单张图片、批量文件夹图片、本地视频及实时 USB 摄像头检测。
现代 UI: 采用极致简约的白色画布风格,无多余干扰,视觉体验极佳。
实时交互: 支持动态调节置信度(Conf)和 IOU 阈值,实时刷新检测结果。
报表导出: 自动生成检测统计分析,支持检测后的图片/视频一键保存至本地。
内容清单
完整后端源码: 基于 Python + PyTorch 开发,逻辑清晰。
前端 GUI 源码: 基于 PyQt5 构建的现代化交互界面。
预训练模型: 包含训练好的 YOLOv11 best.pt 权重文件,到手即用。
全量数据集: 4000+ 原图及对应的 YOLO 标注文件。
部署文档: 包含环境搭建指南(requirements.txt)与运行说明。
这是一个基于PyQt5和YOLOv11 (Ultralytics)的完整番茄叶片病害检测系统构建方案。
同学,以下文字及代码仅供参考学习使用
第一步:环境配置
同学你需要安装必要的库。请在终端运行以下命令:
# 基础库pipinstalltorch torchvision opencv-python numpy pandas matplotlib# 界面库pipinstallPyQt5# YOLOv11 (Ultralytics 最新版支持 v11)pipinstallultralytics第二步:核心代码实现 (main.py)
将以下代码保存为main.py。这段代码实现了系统的主逻辑。
importsysimportcv2importtorchimportnumpyasnpimportpandasaspdfromPyQt5.QtWidgetsimport(QApplication,QMainWindow,QLabel,QPushButton,QVBoxLayout,QWidget,QFileDialog,QMessageBox,QSlider,QHBoxLayout,QTableWidget,QTableWidgetItem,QHeaderView)fromPyQt5.QtGuiimportQImage,QPixmap,QFontfromPyQt5.QtCoreimportQt,QTimer,QThread,pyqtSignalfromultralyticsimportYOLO# --- 配置参数 ---MODEL_PATH='best.pt'# 你的预训练模型路径CONFIDENCE_THRESHOLD=0.45IOU_THRESHOLD=0.80# --- 检测工作线程 ---classDetectThread(QThread):change_pixmap_signal=pyqtSignal(np.ndarray)detection_data_signal=pyqtSignal(list)# 发送检测结果列表def__init__(self):super().__init__()self.running=Trueself.source=0# 0为摄像头self.model=YOLO(MODEL_PATH)self.conf=CONFIDENCE_THRESHOLD self.iou=IOU_THRESHOLDdefrun(self):cap=cv2.VideoCapture(self.source)whileself.running:ret,frame=cap.read()ifret:# YOLOv11 推理results=self.model(frame,conf=self.conf,iou=self.iou)annotated_frame=results[0].plot()# 绘制检测框# 提取数据用于表格显示data=[]forboxinresults[0].boxes:cls_id=int(box.cls[0])conf=float(box.conf[0])label=results[0].names[cls_id]xyxy=box.xyxy[0].tolist()data.append([label,f"{conf:.2f}",f"{xyxy}"])self.detection_data_signal.emit(data)self.change_pixmap_signal.emit(annotated_frame)else:self.running=Falsecap.release()defstop(self):self.running=Falseself.wait()# --- 主窗口类 ---classMainWindow(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("基于深度学习的番茄叶片病害检测系统")self.setGeometry(100,100,1200,800)# 初始化样式 (极简风格)self.setStyleSheet(""" QMainWindow { background-color: #f0f2f5; } QLabel { font-size: 14px; color: #333; } QPushButton { background-color: #007bff; color: white; border: none; padding: 8px 16px; border-radius: 4px; font-size: 14px; } QPushButton:hover { background-color: #0056b3; } QTableWidget { background-color: white; border: 1px solid #ddd; } QHeaderView::section { background-color: #e9ecef; padding: 4px; border: 1px solid #ddd; } """)# --- UI 布局 ---main_layout=QHBoxLayout()# 左侧:视频显示区域self.image_label=QLabel(self)self.image_label.setFixedSize(800,600)self.image_label.setStyleSheet("background-color: #000; border: 1px solid #ccc;")# 右侧:控制面板right_panel=QVBoxLayout()# 1. 参数设置param_group=self.create_group("参数设置")self.conf_slider=self.create_slider(0,100,45,self.update_conf)self.iou_slider=self.create_slider(0,100,80,self.update_iou)param_layout=QFormLayout()param_layout.addRow("置信度阈值:",self.conf_slider)param_layout.addRow("IOU 阈值:",self.iou_slider)param_group.setLayout(param_layout)# 2. 操作按钮btn_group=self.create_group("操作控制")btn_layout=QVBoxLayout()self.btn_img=QPushButton("检测图片")self.btn_video=QPushButton("检测视频")self.btn_cam=QPushButton("开启摄像头")self.btn_export=QPushButton("导出结果 (CSV)")self.btn_img.clicked.connect(self.load_image)self.btn_video.clicked.connect(self.load_video)self.btn_cam.clicked.connect(self.start_camera)self.btn_export.clicked.connect(self.export_csv)btn_layout.addWidget(self.btn_img)btn_layout.addWidget(self.btn_video)btn_layout.addWidget(self.btn_cam)btn_layout.addWidget(self.btn_export)btn_group.setLayout(btn_layout)# 3. 结果表格self.table=QTableWidget()self.table.setColumnCount(3)self.table.setHorizontalHeaderLabels(["类别","置信度","坐标位置"])self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)right_panel.addWidget(param_group)right_panel.addWidget(btn_group)right_panel.addWidget(QLabel("详细数据表格:"))right_panel.addWidget(self.table)main_layout.addWidget(self.image_label)main_layout.addLayout(right_panel)container=QWidget()container.setLayout(main_layout)self.setCentralWidget(container)# 线程初始化self.thread=DetectThread()self.thread.change_pixmap_signal.connect(self.update_image)self.thread.detection_data_signal.connect(self.update_table)defcreate_group(self,title):group=QWidget()group.setStyleSheet("border: 1px solid #ccc; border-radius: 5px; margin-top: 10px;")# 简单模拟 GroupBox 样式,实际可用 QGroupBoxreturngroupdefcreate_slider(self,min,max,val,callback):slider=QSlider(Qt.Horizontal)slider.setRange(min,max)slider.setValue(val)slider.valueChanged.connect(callback)returnslider# --- 功能逻辑 ---defupdate_conf(self,val):self.thread.conf=val/100.0defupdate_iou(self,val):self.thread.iou=val/100.0defupdate_image(self,cv_img):"""将 OpenCV 图像转换为 Qt 图像并显示"""rgb_image=cv2.cvtColor(cv_img,cv2.COLOR_BGR2RGB)h,w,ch=rgb_image.shape bytes_per_line=ch*w convert_to_Qt_format=QImage(rgb_image.data,w,h,bytes_per_line,QImage.Format_RGB888)p=convert_to_Qt_format.scaled(800,600,Qt.KeepAspectRatio)self.image_label.setPixmap(QPixmap.fromImage(p))defupdate_table(self,data):self.table.setRowCount(0)# 清空forrow_dataindata:row=self.table.rowCount()self.table.insertRow(row)self.table.setItem(row,0,QTableWidgetItem(row_data[0]))self.table.setItem(row,1,QTableWidgetItem(row_data[1]))self.table.setItem(row,2,QTableWidgetItem(row_data[2]))defstart_camera(self):ifnotself.thread.isRunning():self.thread.source=0self.thread.start()defload_image(self):fname,_=QFileDialog.getOpenFileName(self,'Open file','.',"Image files (*.jpg *.png)")iffname:self.thread.source=fname# 图片检测逻辑(单帧)results=self.thread.model(fname,conf=self.thread.conf,iou=self.thread.iou)annotated_frame=results[0].plot()self.update_image(annotated_frame)# 更新表格data=[]forboxinresults[0].boxes:cls_id=int(box.cls[0])conf=float(box.conf[0])label=results[0].names[cls_id]xyxy=box.xyxy[0].tolist()data.append([label,f"{conf:.2f}",f"{xyxy}"])self.update_table(data)defload_video(self):fname,_=QFileDialog.getOpenFileName(self,'Open file','.',"Video files (*.mp4 *.avi)")iffname:ifnotself.thread.isRunning():self.thread.source=fname self.thread.start()defexport_csv(self):# 简单的导出逻辑示例fname,_=QFileDialog.getSaveFileName(self,"Save File",".","CSV Files (*.csv)")iffname:# 这里应该从表格或缓存中提取数据df=pd.DataFrame(columns=["Class","Confidence","Box"])df.to_csv(fname,index=False)QMessageBox.information(self,"成功","结果已导出")defcloseEvent(self,event):self.thread.stop()event.accept()if__name__=='__main__':app=QApplication(sys.argv)window=MainWindow()window.show()sys.exit(app.exec_())第三步:数据集配置 (data.yaml)
在训练 YOLOv11 模型时,你需要创建一个data.yaml文件来定义你的番茄病害数据集路径。
# data.yamlpath:./tomato_dataset# 数据集根目录train:images/train# 训练集图片路径val:images/val# 验证集图片路径test:images/test# 测试集图片路径# 类别数量nc:9# 类别名称 (严格按照你的数据集定义)names:-Early_Blight-Healthy-Late_Blight-Leaf_Miner-Leaf_Mold-Mosaic_V-Septoria-Spider_M-YLCV第四步:如何运行
- 准备模型:你需要先使用 Ultralytics 训练你的数据集,得到
best.pt文件,并将其放在与main.py同一目录下。- 训练命令示例:
yolo detect train data=data.yaml model=yolov11n.pt epochs=100 imgsz=640
- 训练命令示例:
- 准备界面资源:上述代码使用了简单的样式表模拟了“简约风格”。如果需要完全还原截图中的图标和布局,建议使用 Qt Designer 设计
.ui文件并转换为 Python 代码,或者在代码中进一步完善 CSS 样式。 - 运行程序:在终端输入
python main.py即可启动系统。
代码亮点解析
- 多线程处理:使用
QThread进行视频捕获和推理,防止界面卡死。 - 动态参数:通过 Slider 实时修改
conf和iou,无需重启程序即可调整检测灵敏度。 - 模块化设计:检测逻辑与界面逻辑分离,方便后续维护和扩展(如增加导出 Excel 功能)。