拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于YOLO与PyQt的蜜蜂目标检测系统:从模型训练到桌面应用开发

在农业智能化、生态监测和生物研究领域蜜蜂作为重要的授粉昆虫其种群数量、活动轨迹的自动化监测一直是个技术难点。传统的人工计数和观察方法效率低下且误差大。本文将围绕“蜜蜂目标检测”这一核心任务分享一套从模型选型、训练、评估到最终集成到桌面应用并实现数据持久化的完整实战方案。我们将使用 YOLO 系列模型涵盖 v5/v8/11/12/26 等多个版本进行检测利用 PyQt 构建用户友好的图形界面并通过 MySQL 数据库管理检测结果与元数据。无论你是计算机视觉的初学者希望了解如何训练自己的第一个目标检测模型还是有一定经验的开发者想学习如何将 AI 模型封装成可交付的桌面软件这篇文章都将提供从零到一的详细指导。我们将覆盖环境搭建、数据集处理、模型训练调优、PyQt 界面开发、数据库设计以及最终的集成部署确保每个环节的代码都可复现、可运行。1. 项目背景与核心技术选型1.1 为什么需要蜜蜂目标检测蜜蜂是生态系统健康的关键指示物种其种群动态直接影响农作物产量和生物多样性。对养蜂人而言实时掌握蜂群进出巢门的活动情况有助于判断蜂群健康状况、预测分蜂行为。在科研领域自动化、非侵入式的蜜蜂监测能产生大量客观数据用于行为学、生态学研究。手动视频分析耗时费力且难以进行大规模、长时间的连续监测。因此基于计算机视觉的自动目标检测技术成为理想的解决方案。它能够从摄像头拍摄的视频流或图像中实时、准确地识别并定位出蜜蜂个体进而统计数量、分析轨迹。1.2 技术栈详解YOLO、PyQt 与 MySQL1. YOLO (You Only Look Once) 系列模型YOLO 是一种单阶段one-stage目标检测算法以其速度快、精度高而闻名。它直接将目标检测视为一个回归问题在单个神经网络中同时预测边界框和类别概率。本项目涉及多个版本YOLOv5: 由 Ultralytics 维护生态完善文档清晰非常易于上手和训练自定义数据集是许多工业项目的首选。YOLOv8: Ultralytics 推出的新一代模型不仅支持目标检测还支持实例分割、姿态估计等任务。在精度和速度上通常有更好的平衡且 API 设计更现代。YOLOv11/YOLOv12/YOLOv26: 这些通常是社区或研究团队基于 YOLO 架构的改进版本注截至当前YOLOv11/12/26 并非 Ultralytics 官方正式版本可能是其他团队的迭代或特定改进型号。在项目中对比这些模型有助于我们理解不同改进思路如新的主干网络、注意力机制、损失函数等对蜜蜂这类小目标检测效果的影响。2. PyQtPyQt 是 Python 对 Qt 应用框架的绑定。Qt 是一个强大的跨平台 C 图形用户界面库。选择 PyQt 用于本项目的理由包括跨平台: 编写的应用程序可以在 Windows、macOS、Linux 上运行。功能强大: 提供丰富的控件按钮、表格、图像显示等和布局管理器能轻松构建复杂的桌面应用。与 Python 无缝集成: 方便我们将训练好的 YOLO 模型通常通过 Python 调用嵌入到图形界面中实现“模型加载-图像/视频输入-实时检测-结果展示”的完整闭环。3. MySQLMySQL 是一个流行的开源关系型数据库管理系统。在本项目中它的作用至关重要数据持久化: 存储每次检测任务的结果包括检测时间、图片/视频路径、检测到的蜜蜂数量、每个蜜蜂的边界框坐标和置信度等。历史查询与分析: 便于后期通过 SQL 语句进行数据汇总、趋势分析如每日蜜蜂活跃度变化。系统化管理: 可以管理用户信息、模型版本、摄像头配置等系统元数据。这三者构成了一个典型的 AI 应用系统YOLO 负责核心的智能感知AIPyQt 负责提供人机交互界面UIMySQL 负责数据的结构化存储与管理Data。2. 开发环境准备一个清晰、隔离的环境是项目成功的基石。强烈建议使用 Anaconda 或 Miniconda 来管理 Python 环境以避免包依赖冲突。2.1 创建并激活 Conda 环境打开终端Windows 下为 Anaconda Prompt 或 PowerShell执行以下命令# 创建一个名为 bee_detection 的 Python 3.9 环境3.8-3.11 皆可建议与 PyTorch 官方推荐版本对齐 conda create -n bee_detection python3.9 -y # 激活环境 conda activate bee_detection2.2 安装 PyTorch 与 CUDAYOLO 系列模型基于 PyTorch 框架。根据你的电脑是否具备 NVIDIA GPU 以及 CUDA 版本选择不同的安装命令。访问 PyTorch 官网 获取最准确的安装命令。有 GPU (CUDA 11.8) 的情况推荐训练和推理速度大幅提升:pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118仅 CPU 的情况:pip install torch torchvision torchaudio安装完成后可以在 Python 中验证import torch print(torch.__version__) # 输出 PyTorch 版本 print(torch.cuda.is_available()) # 输出 True 则表示 GPU 可用2.3 安装 YOLOv5 和 YOLOv8我们将同时安装 YOLOv5 和 YOLOv8 的官方库。# 安装 YOLOv5 pip install ultralytics # 注意ultralytics 包同样包含了 YOLOv8 # 或者克隆 YOLOv5 仓库更推荐便于查看源码和示例 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt cd .. # Ultralytics 库已经安装了 YOLOv8无需额外安装 # 但为了使用方便可以确认安装 pip install ultralytics对于 YOLOv11/12/26 等社区版本你需要找到对应的 GitHub 仓库并按照其README.md中的说明进行安装。通常步骤也是克隆仓库并安装依赖。2.4 安装 PyQt6 和 MySQL 连接器# 安装 PyQt6 这是 Qt6 的 Python 绑定 pip install PyQt6 # 安装 MySQL 客户端库和 Python 连接器 # 首先确保系统已安装 MySQL 客户端开发文件例如在 Ubuntu 上sudo apt-get install libmysqlclient-dev # 然后安装 mysqlclient (性能较好) 或 pymysql (纯Python) pip install mysqlclient # 或者 pip install pymysql2.5 安装 MySQL 数据库服务器你需要一个运行的 MySQL 服务。可以选择本地安装: 从 MySQL 官网 下载安装包按照向导安装。记住 root 密码。Docker 运行(推荐干净隔离):docker run --name mysql-bee -e MYSQL_ROOT_PASSWORDyourpassword -p 3306:3306 -d mysql:8.0使用云数据库服务。安装后使用命令行或 MySQL Workbench 等工具连接数据库并创建一个用于本项目的数据库CREATE DATABASE bee_detection_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE bee_detection_db;3. 蜜蜂数据集准备与标注没有数据再好的模型也无用武之地。对于蜜蜂检测我们需要收集大量包含蜜蜂的图片。3.1 数据收集数据来源可以包括公开数据集如 Kaggle 上的 “Bee Dataset” 或 “Honey Bee and Bumble Bee Images”。自行拍摄在蜂箱巢门、蜜源植物附近设置摄像头采集视频并抽帧。网络爬取注意版权和用途限制。数据应尽可能多样化不同光照条件白天、黄昏、不同背景蜂箱、花朵、天空、不同蜜蜂姿态飞行、爬行、静止、不同拍摄角度。3.2 数据标注我们需要用标注工具在每张图片上框出蜜蜂并赋予标签例如 “bee”。推荐使用LabelImg或Roboflow。使用 LabelImg 标注安装pip install labelImg然后运行labelImg。设置格式选择YOLO会生成.txt文件。标注打开图片目录用矩形框工具框出蜜蜂输入标签名bee。保存每标注一张会自动生成一个同名的.txt文件。其内容格式为class_id x_center y_center width height坐标是归一化后的0-1之间。一个bee_001.txt文件内容示例0 0.512345 0.634567 0.123456 0.098765这表示有一个目标类别 ID 为 0对应bee其边界框中心点位于图片 (51.23%, 63.46%) 的位置宽度和高度分别为图片宽高的 12.35% 和 9.88%。3.3 组织数据集目录按照 YOLO 要求的格式组织你的数据集bee_dataset/ ├── images/ │ ├── train/ │ │ ├── bee_001.jpg │ │ └── ... │ └── val/ │ ├── bee_101.jpg │ └── ... └── labels/ ├── train/ │ ├── bee_001.txt │ └── ... └── val/ ├── bee_101.txt └── ...还需要一个描述数据集信息的 YAML 文件bee_data.yaml# bee_data.yaml path: /absolute/path/to/bee_dataset # 数据集根目录 train: images/train # 训练集图片相对路径 val: images/val # 验证集图片相对路径 # 类别数量和名称 nc: 1 names: [bee] # 可选下载地址/说明将images和labels下的train、val文件夹对应好。4. 训练 YOLO 蜜蜂检测模型我们将以 YOLOv8 和 YOLOv5 为例演示训练过程。其他版本流程类似。4.1 使用 YOLOv8 训练YOLOv8 提供了极其简洁的 API。创建一个训练脚本train_yolov8.py# train_yolov8.py from ultralytics import YOLO def main(): # 加载一个预训练模型 (例如 yolov8n.pt, yolov8s.pt, yolov8m.pt, yolov8l.pt, yolov8x.pt) # ‘n’,‘s’,‘m’,‘l’,‘x’ 分别代表模型尺寸和复杂度递增 model YOLO(yolov8n.pt) # 这里以最小的 yolov8n 为例 # 训练模型 results model.train( datapath/to/your/bee_data.yaml, # 上一步创建的配置文件 epochs100, # 训练轮数 imgsz640, # 输入图片大小 batch16, # 批次大小根据GPU内存调整 device0, # 使用 GPU 0如果是CPU则设为 ‘cpu’ projectruns/detect, # 结果保存目录 namebee_yolov8n_train, # 本次训练运行名称 saveTrue, verboseTrue ) # 训练完成后最佳模型会自动保存在 ‘runs/detect/bee_yolov8n_train/weights/best.pt’ print(训练完成最佳模型已保存。) if __name__ __main__: main()运行此脚本即可开始训练。训练过程中Ultralytics 会实时输出损失曲线、精度指标mAP等并保存日志和模型权重。4.2 使用 YOLOv5 训练进入之前克隆的yolov5目录使用其提供的标准训练脚本cd yolov5 python train.py --img 640 --batch 16 --epochs 100 --data ../bee_data.yaml --weights yolov5s.pt --project ../runs/detect --name bee_yolov5s_train --device 0参数解释--img 640: 图像尺寸。--batch 16: 批次大小。--epochs 100: 训练轮数。--data: 数据集配置文件路径。--weights: 预训练权重yolov5s.pt是小型模型。--project和--name: 定义输出目录。--device 0: 使用 GPU 0。4.3 模型评估与验证训练结束后使用验证集评估模型性能YOLOv8:from ultralytics import YOLO model YOLO(runs/detect/bee_yolov8n_train/weights/best.pt) metrics model.val(datapath/to/bee_data.yaml, splitval) print(metrics.box.map) # 打印 mAP50-95YOLOv5:python val.py --weights ../runs/detect/bee_yolov5s_train/weights/best.pt --data ../bee_data.yaml --img 640 --device 0关键指标是mAP (mean Average Precision)特别是mAP0.5和mAP0.5:0.95。值越高说明模型检测蜜蜂的平均精度越好。可以尝试训练不同版本YOLOv5s, YOLOv8m等和调整超参数学习率、数据增强等对比这些指标选择最适合的模型。5. 使用 PyQt6 构建检测界面现在我们将训练好的模型集成到一个桌面应用中。创建一个主应用文件bee_detector_app.py。5.1 设计主窗口界面我们将设计一个包含以下区域的主窗口菜单栏/工具栏用于打开文件、摄像头、设置等。图像显示区域用于显示原始图片和检测结果。控制面板开始/停止检测、模型选择、置信度阈值调节。结果列表以表格形式展示当前图片中检测到的蜜蜂信息。状态栏显示检测状态、耗时等信息。# bee_detector_app.py import sys import cv2 from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFileDialog, QComboBox, QSlider, QTableWidget, QTableWidgetItem, QMessageBox, QStatusBar, QToolBar, QAction) from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QThread from PyQt6.QtGui import QImage, QPixmap, QAction from ultralytics import YOLO import numpy as np from datetime import datetime # 数据库模块稍后引入 class DetectionThread(QThread): 用于执行检测任务的线程避免界面卡顿 finished pyqtSignal(np.ndarray, list) # 信号传递检测后的图像和结果列表 def __init__(self, model, image, conf_threshold): super().__init__() self.model model self.image image self.conf_threshold conf_threshold def run(self): # 执行 YOLO 推理 results self.model(self.image, confself.conf_threshold, verboseFalse) # 获取带标注框的图像 annotated_frame results[0].plot() # 这个 plot 方法返回绘制了框的BGR图像 # 提取检测信息 detections [] for box in results[0].boxes: xyxy box.xyxy[0].cpu().numpy() # 边界框 [x1, y1, x2, y2] conf box.conf[0].cpu().numpy() # 置信度 cls int(box.cls[0].cpu().numpy()) # 类别ID detections.append({ bbox: xyxy.tolist(), confidence: float(conf), class_id: cls, class_name: self.model.names[cls] }) self.finished.emit(annotated_frame, detections) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.model None self.current_image None self.detections [] self.conf_threshold 0.25 self.init_ui() self.load_default_model() def init_ui(self): self.setWindowTitle(蜜蜂目标检测系统 - YOLOPyQtMySQL) self.setGeometry(100, 100, 1400, 800) # 创建中心部件和主布局 central_widget QWidget() self.setCentralWidget(central_widget) main_layout QHBoxLayout(central_widget) # 左侧图像显示区域 left_panel QVBoxLayout() self.image_label QLabel(图像将显示在这里) self.image_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.image_label.setMinimumSize(800, 600) self.image_label.setStyleSheet(border: 1px solid #ccc; background-color: #f0f0f0;) left_panel.addWidget(self.image_label) # 图像控制按钮 btn_layout QHBoxLayout() self.btn_open QPushButton(打开图片) self.btn_open.clicked.connect(self.open_image) self.btn_camera QPushButton(打开摄像头) self.btn_camera.clicked.connect(self.toggle_camera) self.btn_detect QPushButton(开始检测) self.btn_detect.clicked.connect(self.detect_image) self.btn_detect.setEnabled(False) btn_layout.addWidget(self.btn_open) btn_layout.addWidget(self.btn_camera) btn_layout.addWidget(self.btn_detect) btn_layout.addStretch() left_panel.addLayout(btn_layout) # 右侧控制与结果面板 right_panel QVBoxLayout() # 模型选择 model_layout QHBoxLayout() model_layout.addWidget(QLabel(选择模型:)) self.model_combo QComboBox() self.model_combo.addItems([YOLOv8n (蜜蜂), YOLOv5s (蜜蜂), YOLOv8m (蜜蜂)]) # 示例实际应加载可用模型 self.model_combo.currentTextChanged.connect(self.change_model) model_layout.addWidget(self.model_combo) right_panel.addLayout(model_layout) # 置信度阈值调节 conf_layout QHBoxLayout() conf_layout.addWidget(QLabel(f置信度阈值: {self.conf_threshold:.2f})) self.conf_slider QSlider(Qt.Orientation.Horizontal) self.conf_slider.setRange(1, 99) # 对应 0.01 到 0.99 self.conf_slider.setValue(int(self.conf_threshold * 100)) self.conf_slider.valueChanged.connect(self.update_conf_threshold) conf_layout.addWidget(self.conf_slider) right_panel.addLayout(conf_layout) # 检测结果表格 right_panel.addWidget(QLabel(检测结果:)) self.result_table QTableWidget() self.result_table.setColumnCount(5) self.result_table.setHorizontalHeaderLabels([ID, 类别, 置信度, X1, Y1, X2, Y2]) right_panel.addWidget(self.result_table) # 数据库操作按钮 db_btn_layout QHBoxLayout() self.btn_save_db QPushButton(保存到数据库) self.btn_save_db.clicked.connect(self.save_to_database) self.btn_save_db.setEnabled(False) self.btn_query QPushButton(查询历史) self.btn_query.clicked.connect(self.query_history) db_btn_layout.addWidget(self.btn_save_db) db_btn_layout.addWidget(self.btn_query) right_panel.addLayout(db_btn_layout) # 将左右面板加入主布局 main_layout.addLayout(left_panel, 70) # 左侧占70% main_layout.addLayout(right_panel, 30) # 右侧占30% # 状态栏 self.status_bar QStatusBar() self.setStatusBar(self.status_bar) self.status_bar.showMessage(就绪) # 初始化摄像头相关 self.cap None self.timer QTimer() self.timer.timeout.connect(self.update_camera_frame) self.is_camera_on False def load_default_model(self): 加载默认的 YOLO 模型 try: # 这里路径需要替换为你训练好的最佳模型路径 self.model YOLO(runs/detect/bee_yolov8n_train/weights/best.pt) self.status_bar.showMessage(默认模型加载成功) except Exception as e: QMessageBox.critical(self, 错误, f模型加载失败: {e}) self.model None def open_image(self): 打开图片文件 file_path, _ QFileDialog.getOpenFileName(self, 选择图片, , Image files (*.jpg *.jpeg *.png *.bmp)) if file_path: self.current_image cv2.imread(file_path) if self.current_image is not None: self.display_image(self.current_image) self.btn_detect.setEnabled(True) self.btn_save_db.setEnabled(False) self.result_table.setRowCount(0) # 清空旧结果 self.status_bar.showMessage(f已加载图片: {file_path}) self.current_image_path file_path else: QMessageBox.warning(self, 警告, 无法读取图片文件。) # 由于篇幅限制此处省略 display_image, toggle_camera, update_camera_frame, detect_image, # update_conf_threshold, change_model, update_result_table, save_to_database, query_history 等具体方法实现 # 它们将处理图像显示、摄像头开关、检测执行、UI更新和数据库交互。 if __name__ __main__: app QApplication(sys.argv) window MainWindow() window.show() sys.exit(app.exec())以上代码搭建了应用的主框架。你需要补充完整诸如display_image将 OpenCV 图像转换为 QPixmap 并显示、detect_image启动检测线程、update_result_table用检测结果填充表格等方法。5.2 实现检测与结果显示逻辑在MainWindow类中添加关键方法def display_image(self, cv_img): 将 OpenCV BGR 图像转换为 QPixmap 并在 QLabel 上显示 if cv_img is None: return # 转换颜色空间 BGR - RGB rgb_image cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) h, w, ch rgb_image.shape bytes_per_line ch * w qt_image QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format.Format_RGB888) pixmap QPixmap.fromImage(qt_image) # 缩放以适应 QLabel同时保持比例 scaled_pixmap pixmap.scaled(self.image_label.size(), Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation) self.image_label.setPixmap(scaled_pixmap) def detect_image(self): 对当前图片执行目标检测 if self.model is None or self.current_image is None: QMessageBox.warning(self, 警告, 请先加载模型和图片。) return self.btn_detect.setEnabled(False) self.status_bar.showMessage(检测中...) # 创建并启动检测线程 self.detection_thread DetectionThread(self.model, self.current_image, self.conf_threshold) self.detection_thread.finished.connect(self.on_detection_finished) self.detection_thread.start() def on_detection_finished(self, annotated_frame, detections): 检测线程完成后的槽函数 self.detections detections self.display_image(annotated_frame) self.update_result_table(detections) self.btn_detect.setEnabled(True) self.btn_save_db.setEnabled(True) # 有结果后允许保存 self.status_bar.showMessage(f检测完成共发现 {len(detections)} 只蜜蜂。) def update_result_table(self, detections): 更新结果表格 self.result_table.setRowCount(len(detections)) for row, det in enumerate(detections): self.result_table.setItem(row, 0, QTableWidgetItem(str(row1))) self.result_table.setItem(row, 1, QTableWidgetItem(det[class_name])) self.result_table.setItem(row, 2, QTableWidgetItem(f{det[confidence]:.4f})) bbox det[bbox] self.result_table.setItem(row, 3, QTableWidgetItem(f{bbox[0]:.1f})) self.result_table.setItem(row, 4, QTableWidgetItem(f{bbox[1]:.1f})) self.result_table.setItem(row, 5, QTableWidgetItem(f{bbox[2]:.1f})) self.result_table.setItem(row, 6, QTableWidgetItem(f{bbox[3]:.1f}))6. 集成 MySQL 数据库我们需要将检测结果时间、图片路径、蜜蜂数量、每个蜜蜂的详细信息保存到数据库并支持历史查询。6.1 设计数据库表结构在之前创建的bee_detection_db中执行以下 SQL-- 创建检测任务表 CREATE TABLE detection_task ( task_id INT AUTO_INCREMENT PRIMARY KEY, image_path VARCHAR(500) NOT NULL COMMENT 原始图片路径, detection_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 检测时间, bee_count INT DEFAULT 0 COMMENT 检测到的蜜蜂总数, model_used VARCHAR(100) COMMENT 使用的模型名称, conf_threshold FLOAT COMMENT 检测置信度阈值 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci; -- 创建检测结果明细表 CREATE TABLE detection_result ( result_id INT AUTO_INCREMENT PRIMARY KEY, task_id INT NOT NULL COMMENT 关联的任务ID, bee_index INT COMMENT 在当前图片中的蜜蜂序号, class_name VARCHAR(50) COMMENT 类别名称, confidence FLOAT COMMENT 置信度, bbox_x1 FLOAT COMMENT 边界框左上角x, bbox_y1 FLOAT COMMENT 边界框左上角y, bbox_x2 FLOAT COMMENT 边界框右下角x, bbox_y2 FLOAT COMMENT 边界框右下角y, FOREIGN KEY (task_id) REFERENCES detection_task(task_id) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci;6.2 实现数据库操作类创建一个database.py文件来封装所有数据库操作# database.py import pymysql from datetime import datetime from typing import List, Dict, Any class BeeDetectionDB: def __init__(self, hostlocalhost, userroot, passwordyourpassword, databasebee_detection_db): self.connection pymysql.connect( hosthost, useruser, passwordpassword, databasedatabase, charsetutf8mb4, cursorclasspymysql.cursors.DictCursor ) def save_detection_task(self, image_path: str, bee_count: int, model_used: str, conf_threshold: float, detections: List[Dict]): 保存一次完整的检测任务和结果明细 try: with self.connection.cursor() as cursor: # 插入任务主记录 sql_task INSERT INTO detection_task (image_path, bee_count, model_used, conf_threshold) VALUES (%s, %s, %s, %s) cursor.execute(sql_task, (image_path, bee_count, model_used, conf_threshold)) task_id cursor.lastrowid # 插入每条检测结果 sql_result INSERT INTO detection_result (task_id, bee_index, class_name, confidence, bbox_x1, bbox_y1, bbox_x2, bbox_y2) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) result_data [] for idx, det in enumerate(detections): result_data.append(( task_id, idx1, det[class_name], det[confidence], det[bbox][0], det[bbox][1], det[bbox][2], det[bbox][3] )) cursor.executemany(sql_result, result_data) self.connection.commit() return task_id except Exception as e: self.connection.rollback() print(f保存到数据库失败: {e}) return None def query_recent_tasks(self, limit50): 查询最近的检测任务 try: with self.connection.cursor() as cursor: sql SELECT task_id, image_path, detection_time, bee_count, model_used FROM detection_task ORDER BY detection_time DESC LIMIT %s cursor.execute(sql, (limit,)) return cursor.fetchall() except Exception as e: print(f查询任务失败: {e}) return [] def close(self): self.connection.close()6.3 在 PyQt 应用中调用数据库回到bee_detector_app.py补充数据库操作# 在文件开头导入 from database import BeeDetectionDB # 在 MainWindow 类的 __init__ 方法中初始化数据库连接 self.db BeeDetectionDB(hostlocalhost, userroot, passwordyourpassword, databasebee_detection_db) # 实现保存到数据库的方法 def save_to_database(self): if not self.detections or not hasattr(self, current_image_path): QMessageBox.warning(self, 警告, 没有可保存的检测结果。) return model_name self.model_combo.currentText() task_id self.db.save_detection_task( image_pathself.current_image_path, bee_countlen(self.detections), model_usedmodel_name, conf_thresholdself.conf_threshold, detectionsself.detections ) if task_id: QMessageBox.information(self, 成功, f检测结果已保存到数据库任务ID: {task_id}) self.btn_save_db.setEnabled(False) # 保存后禁用避免重复保存 else: QMessageBox.critical(self, 错误, 保存到数据库失败请检查数据库连接。) # 实现查询历史的方法可以打开一个新窗口或对话框显示 def query_history(self): from PyQt6.QtWidgets import QDialog, QVBoxLayout, QTableWidget, QTableWidgetItem, QPushButton dialog QDialog(self) dialog.setWindowTitle(历史检测记录) dialog.setGeometry(200, 200, 800, 400) layout QVBoxLayout(dialog) table QTableWidget() layout.addWidget(table) tasks self.db.query_recent_tasks() table.setRowCount(len(tasks)) table.setColumnCount(5) table.setHorizontalHeaderLabels([任务ID, 图片路径, 检测时间, 蜜蜂数量, 使用模型]) for row, task in enumerate(tasks): table.setItem(row, 0, QTableWidgetItem(str(task[task_id]))) table.setItem(row, 1, QTableWidgetItem(task[image_path])) table.setItem(row, 2, QTableWidgetItem(str(task[detection_time]))) table.setItem(row, 3, QTableWidgetItem(str(task[bee_count]))) table.setItem(row, 4, QTableWidgetItem(task[model_used])) dialog.exec()7. 项目运行、打包与部署7.1 运行应用程序确保所有依赖已安装数据库服务已启动且配置正确修改database.py中的连接参数。在终端激活bee_detection环境后运行python bee_detector_app.py如果一切正常图形界面将弹出。你可以通过“打开图片”加载蜜蜂图片点击“开始检测”进行推理结果会显示在图片和表格中最后可以“保存到数据库”。7.2 使用 PyInstaller 打包为可执行文件为了让没有 Python 环境的用户也能使用我们可以将应用打包成.exe(Windows) 或可执行文件 (macOS/Linux)。安装 PyInstaller:pip install pyinstaller创建打包规范文件bee_app.spec可选用于高级配置或直接使用命令行pyinstaller --onefile --windowed --name BeeDetector --add-data runs/detect/bee_yolov8n_train/weights/best.pt;. --hidden-import ultralytics --collect-all ultralytics bee_detector_app.py--onefile: 打包成单个可执行文件。--windowed: 不显示控制台窗口仅GUI。--name: 指定输出程序名称。--add-data: 将模型文件等资源打包进去。源路径;目标路径Windows用;Linux/macOS用:。--hidden-import和--collect-all: 确保 PyInstaller 能正确找到 Ultralytics 等动态导入的模块。打包命令执行后在dist目录下会生成可执行文件。注意首次运行可能需要将模型文件放在可执行文件同级目录下具体取决于--add-data的配置。7.3 部署注意事项模型路径: 在打包或部署时确保代码中加载模型的路径是相对的或可通过配置文件指定避免硬编码绝对路径。数据库连接: 生产环境应将数据库连接信息主机、用户名、密码放在配置文件如config.ini或环境变量中不要写在代码里。性能: 在树莓派或边缘设备上部署时可能需要使用更轻量的模型如 YOLOv5n, YOLOv8n或进行模型量化、剪枝。摄像头集成: 代码中已预留摄像头支持框架需要完善toggle_camera和update_camera_frame方法实现实时视频流检测。8. 常见问题与解决方案在开发和使用过程中你可能会遇到以下问题问题现象可能原因解决方案ImportError: libGL.so.1(Linux)OpenCV 的 GUI 依赖缺失。安装系统库sudo apt-get install libgl1-mesa-glxRuntimeError: CUDA out of memoryGPU 显存不足。1. 减小batch_size。2. 使用更小的模型如yolov8n。3. 减小推理图片尺寸imgsz。4. 在代码中使用model.to(‘cpu’)切换到 CPU 模式慢。PyQt 界面卡死或无响应在主线程执行耗时操作如模型推理。使用QThread将检测任务放到工作线程中如本文示例所示。YOLO 检测不到蜜蜂或精度很低1. 数据集质量差或数量少。2. 标注不准确。3. 训练轮数不足或过拟合。4. 蜜蜂目标太小。1. 增加数据集规模和多样性。2. 检查并修正标注。3. 调整训练超参数使用早停early stopping。4. 尝试专门针对小目标优化的模型或改进如添加注意力机制、使用更小的检测头网格。MySQL 连接失败1. 数据库服务未启动。2. 用户名/密码错误。3. 防火墙阻止了端口 3306。4. 未授予远程连接权限。1. 检查 MySQL 服务状态。2. 确认连接参数。3. 检查防火墙设置。4. 对于远程连接需在 MySQL 中创建用户并授权GRANT ALL ON bee_detection_db.* TO ‘username’‘%’ IDENTIFIED BY ‘password’;打包后的 exe 文件运行时找不到模型PyInstaller 未将模型文件打包进去或路径不对。1. 使用--add-data正确指定模型文件。2. 在代码中使用sys._MEIPASS来获取打包后的临时资源路径。例如model_path os.path.join(getattr(sys, ‘_MEIPASS’, os.path.abspath(“.”)), “best.pt”)实时摄像头检测延迟高1. 模型太大推理速度慢。2. 图像预处理/后处理耗时。3. UI 刷新过于频繁。1. 换用更轻量模型或进行模型量化。2. 优化代码使用 NumPy 向量化操作。3. 降低摄像头帧率或检测频率如每3帧检测一次。9. 最佳实践与进阶优化建议模型管理建立一个models/目录存放不同版本YOLOv5s, v8m, v8x等和不同训练阶段的模型权重。在应用中通过配置文件或数据库来管理模型路径和元信息实现动态切换模型。配置化将数据库连接信息、模型默认路径、置信度阈值默认值、界面样式等写入config.yaml或config.ini文件使应用更易于维护和部署。日志记录使用 Python 的logging模块记录应用运行日志、错误信息和用户操作便于后期排查问题。异常处理与用户体验对所有可能失败的操作文件读取、模型加载、数据库连接、网络请求进行try-except捕获并给用户友好的提示而不是抛出晦涩的异常。数据增强与模型优化在训练阶段使用 Mosaic、MixUp、随机仿射变换等数据增强技术提升模型鲁棒性。对于蜜蜂这类小目标可以尝试在 YOLO 的 Neck 部分添加针对小目标的检测层或者使用专门优化小目标的模型如 YOLO-Fine。数据库优化对于海量检测数据考虑对detection_time字段建立索引加速历史查询。定期归档旧数据或者将检测结果图片的路径改为相对路径并将图片本身存储于对象存储如 MinIO或文件服务器数据库中只存 URL。功能扩展视频处理扩展应用支持加载视频文件并进行逐帧检测与结果保存。批量处理添加批量图片检测功能并生成汇总报告。数据导出支持将检测结果导出为 CSV、Excel 或 JSON 格式。模型再训练在界面中集成“困难样本挖掘”功能将误检、漏检的样本收集起来便于后续迭代训练模型。通过以上步骤我们完成了一个完整的“蜜蜂目标检测系统”的构建。这个项目不仅是一个简单的模型应用更是一个涵盖了 AI 模型训练、桌面应用开发、数据库设计集成的综合实践案例。你可以将此框架作为模板轻松替换数据集和模型应用于其他领域的目标检测任务如工业质检、安防监控、野生动物监测等。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门