ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于YOLOv8与PyQt5的水下垃圾生物检测识别系统实现

基于YOLOv8与PyQt5的水下垃圾生物检测识别系统实现 水底环境的视觉检测一直是个痛点光照不均匀、水体浑浊、目标尺度变化大很多在陆地上表现不错的检测模型放到水下数据上就直接失灵。这次我们来看一个基于 YOLOv8 PyQt5 的桌面端检测识别系统专门面向水底海底场景同时覆盖垃圾和生物两类目标。它的核心不复杂就是用 YOLOv8 做检测器用 PyQt5 搭一个本地 GUI再配合数据集训练和后处理逻辑形成一套能实际使用的探测识别工具。这个项目的价值在于把“模型训练”和“桌面应用”串成了一条完整链路。YOLOv8 负责目标检测核心能力PyQt5 负责界面交互摄像头或图片输入进去能在窗口里直接看到检测框和类别标签。对于水下机器人、海洋环保监测、渔业资源调研这类场景这套架构是可以直接改造成产品原型的。本文会从环境准备、数据集整理、模型训练、GUI 搭建、接口封装、性能观察和常见问题几个方面展开带你把这套系统完整跑通。1. 核心能力速览能力项说明项目类型深度学习目标检测 桌面端 GUI 应用检测算法YOLOv8来自 Ultralytics支持 n/s/m/l/x 多种规格界面框架PyQt5支持实时画面显示、检测结果标注、按钮交互输入方式单张图片、视频文件、摄像头实时画面、批量图片目录输出内容检测框、类别标签、置信度、检测计数、结果保存显存需求随模型规格变化YOLOv8n 占用较低YOLOv8x 明显更高需按实际环境测试是否支持 CPU支持但推理速度会比 GPU 慢很多是否支持批量任务通过遍历输入目录可实现GUI 中可增加批量处理按钮是否提供 API项目本身以 PyQt5 桌面应用为主接口能力需自行封装启动方式Python 脚本启动可打包为 exe适合场景水下垃圾清理、海底生物调查、海洋环保监测、教学演示与算法验证从实际工程角度看这个项目的门槛不高。YOLOv8 的推理接口已经封装得比较成熟PyQt5 也是相对成熟的桌面开发框架两者结合的核心工作量其实集中在两处一是水下数据集的采集与标注质量二是 GUI 的业务逻辑设计比如检测结果统计、批量任务、模型切换这些功能。2. 适用场景与使用边界这类水底垃圾生物检测系统最典型的场景包括水下机器人搭载摄像头对海底垃圾分布进行巡查记录。海洋环保机构对特定海域的垃圾类型做抽样统计比如塑料、渔网、玻璃瓶。渔业或科研单位对海底生物种类和数量进行观测。高校项目或毕业设计中作为深度学习目标检测的完整落地演示。它不适合什么场景如果要求极高的实时性比如水下机器人的实时避障单靠 YOLOv8 在嵌入式设备上跑可能压力较大需要配合 TensorRT 加速或部署更轻量的模型。如果检测目标严重遮挡、水体极端浑浊纯视觉方案也会有明显误差需要融合声呐等其他传感器数据。使用边界方面要重点提一下合法性。水下图像数据的采集如果涉及特定海域、特定保护区或他人设备拍摄的数据必须确认数据来源合法。使用真实水下场景的人脸、船只、特定设施图像时应避免敏感区域和未授权数据。对于模型输出的检测结果不能直接作为官方统计或执法依据需要人工复核。3. 环境准备与前置条件3.1 操作系统与运行环境推荐使用 Windows 10/11 或 Ubuntu 20.04/22.04。项目本身以 Python 开发为主跨平台能力一般没有问题。Windows 下需要注意 PyQt5 和 CUDA 环境的版本匹配问题。3.2 Python 与依赖库建议使用 Python 3.8 到 3.11 之间的版本更稳妥的选择是 3.9 或 3.10。Ultralytics 对 Python 版本有明确要求过高或过低都可能导致依赖冲突。核心依赖包括ultralytics torch torchvision PyQt5 opencv-python numpy pillow安装命令参考pip install ultralytics torch torchvision pip install PyQt5 opencv-python numpy pillow如果本机有 NVIDIA 显卡建议安装对应版本的 CUDA 版 PyTorch。具体安装命令需要到 PyTorch 官网根据 CUDA 版本生成这里不写死。3.3 GPU 与显存要求YOLOv8 各规格模型对显存的需求差异较大YOLOv8n模型最小CPU 也能跑GPU 上速度很快显存占用低。YOLOv8s / YOLOv8m适合大多数场景8G 显存基本够用具体需实测。YOLOv8l / YOLOv8x精度高但显存占用明显增加推理速度下降。关于显存占用不给出固定数值因为输入分辨率、批大小、是否开启半精度都会直接影响结果。建议用小分辨率、小批大小起步逐步往上加。3.4 数据集要求水下目标检测数据集需要包含标注文件。YOLOv8 默认使用 YOLO 格式的 txt 标注文件每行格式为class_id x_center y_center width height其中 x_center、y_center、width、height 都是归一化后的数值取值范围 0 到 1。数据集的目录结构建议如下datasets/ |-- underwater/ |-- images/ |-- train/ |-- val/ |-- labels/ |-- train/ |-- val/图片和标注文件需要保持同名。比如001.jpg对应001.txt。4. 安装部署与启动方式4.1 创建虚拟环境为了避免依赖冲突强烈建议使用虚拟环境。python -m venv yolo_envWindows 激活yolo_env\Scripts\activateLinux 激活source yolo_env/bin/activate4.2 安装依赖激活环境后安装依赖pip install --upgrade pip pip install ultralytics PyQt5 opencv-python numpy pillow如果训练需要 GPU确保 PyTorch 安装的是 CUDA 版本。可以在 Python 中验证import torch print(torch.cuda.is_available())输出为 True 说明 CUDA 可用。4.3 验证 YOLOv8 推理先跑一个最简单的推理确认环境没问题from ultralytics import YOLO model YOLO(yolov8n.pt) results model.predict(sourcetest.jpg, saveTrue)第一次运行会自动下载 yolov8n.pt 权重文件网络不稳定时可以手动下载放到项目目录。4.4 启动 PyQt5 界面将检测逻辑封装到 PyQt5 界面中下面给出一个最小可运行的示例框架import sys import cv2 from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QFileDialog, QVBoxLayout, QWidget from PyQt5.QtGui import QImage, QPixmap from ultralytics import YOLO class DetectorWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(水底垃圾生物检测系统) self.setGeometry(100, 100, 1000, 700) self.model YOLO(yolov8n.pt) self.image_label QLabel(请选择图片或视频) self.open_image_btn QPushButton(打开图片) self.open_image_btn.clicked.connect(self.open_image) layout QVBoxLayout() layout.addWidget(self.image_label) layout.addWidget(self.open_image_btn) container QWidget() container.setLayout(layout) self.setCentralWidget(container) def open_image(self): file_path, _ QFileDialog.getOpenFileName(self, 选择图片, , 图片文件 (*.jpg *.png *.bmp)) if not file_path: return results self.model.predict(sourcefile_path, conf0.25) annotated_frame results[0].plot() height, width, channel annotated_frame.shape bytes_per_line 3 * width q_img QImage(annotated_frame.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped() self.image_label.setPixmap(QPixmap.fromImage(q_img).scaled(self.image_label.size(), aspectRatioMode1)) if __name__ __main__: app QApplication(sys.argv) window DetectorWindow() window.show() sys.exit(app.exec_())这个示例中点击按钮选择图片后YOLOv8 完成推理结果绘制在原始帧上再通过 QImage 转换为 PyQt5 可以显示的格式。这是整个系统的核心数据流。5. 功能测试与效果验证5.1 图片检测测试测试目的验证单张图片的检测流程是否正常包括模型加载、推理、标注和显示。操作步骤准备一张包含水下目标或普通目标的测试图片。点击“打开图片”按钮选择图片。观察检测结果是否显示在界面中。预期结果图片上出现检测框和类别标签置信度显示在标签中。判断成功标准检测框位置基本准确类别标签正确推理时间在可接受范围内。常见失败原因模型文件不存在或路径错误检查项目目录下是否有 yolov8n.pt。图片路径包含中文OpenCV 读取可能失败建议改用英文路径。5.2 摄像头实时检测测试目的验证摄像头实时画面的处理能力判断推理速度是否满足实时展示需求。操作步骤在 GUI 中添加“摄像头检测”按钮。点击后打开本机摄像头逐帧读取视频流。每帧调用 YOLOv8 推理结果实时显示。代码示例import cv2 from PyQt5.QtCore import QTimer # 在窗口类中新增属性 self.capture None self.timer QTimer() self.timer.timeout.connect(self.update_frame) def start_camera(self): self.capture cv2.VideoCapture(0) self.timer.start(30) # 每 30ms 读取一帧 def update_frame(self): ret, frame self.capture.read() if not ret: return results self.model.predict(sourceframe, conf0.25, verboseFalse) annotated_frame results[0].plot() # 转换为 QImage 并显示注意摄像头检测对推理速度要求较高。如果帧率太低可以将输入帧等比缩小或者使用批次推理的简化方式。5.3 视频文件检测测试目的验证视频文件的批量帧处理能力以及输出结果是否能够保存。操作步骤用 cv2.VideoCapture 打开视频文件。逐帧处理并显示。可选将处理后的帧写入新的视频文件。视频写入示例fourcc cv2.VideoWriter_fourcc(*mp4v) out cv2.VideoWriter(output.mp4, fourcc, 20.0, (width, height))注意视频写入的分辨率必须和输入帧保持一致否则保存失败。5.4 模型切换测试YOLOv8 可以分为检测、实例分割等不同类型接口很统一。如果水下场景需要像素级分割结果可以加载分割模型model YOLO(yolov8n-seg.pt)检测还是分割取决于数据集标注方式。如果项目目标是识别垃圾轮廓和生物形态实例分割效果通常更好但对显存的要求也更高。6. 接口 API 与批量任务6.1 为什么需要接口PyQt5 桌面应用本身是面向人机交互的。如果要把检测能力开放给其他模块比如水下机器人的控制程序、数据管理系统或 Web 后端就需要把检测逻辑封装成一个独立的接口服务。6.2 Flask API 封装示例可以使用 Flask 将 YOLOv8 检测封装为 HTTP 接口from flask import Flask, request, jsonify import cv2 import numpy as np from ultralytics import YOLO app Flask(__name__) model YOLO(yolov8n.pt) app.route(/detect, methods[POST]) def detect(): file request.files.get(image) if file is None: return jsonify({error: no image}), 400 img_bytes np.frombuffer(file.read(), np.uint8) img cv2.imdecode(img_bytes, cv2.IMREAD_COLOR) results model.predict(sourceimg, conf0.25) detections [] for box in results[0].boxes: detections.append({ class: results[0].names[int(box.cls)], confidence: float(box.conf), x1: float(box.xyxy[0][0]), y1: float(box.xyxy[0][1]), x2: float(box.xyxy[0][2]), y2: float(box.xyxy[0][3]), }) return jsonify({detections: detections}) if __name__ __main__: app.run(host127.0.0.1, port5000)启动接口服务后可以用 curl 测试curl -X POST -F imagetest.jpg http://127.0.0.1:5000/detect6.3 批量任务设计批量检测的核心思路是遍历目录中的所有图片逐一处理并保存结果。需要考虑两个问题第一单张失败不能中断全部任务要加 try-except。第二批量处理耗时长最好把进度显示出来。批量检测脚本示例import os import cv2 from ultralytics import YOLO model YOLO(yolov8n.pt) input_dir ./underwater_test output_dir ./underwater_result os.makedirs(output_dir, exist_okTrue) total len(os.listdir(input_dir)) for idx, filename in enumerate(os.listdir(input_dir)): if not filename.lower().endswith((.jpg, .png, .jpeg)): continue img_path os.path.join(input_dir, filename) try: results model.predict(sourceimg_path, conf0.25) annotated results[0].plot() output_path os.path.join(output_dir, filename) cv2.imwrite(output_path, annotated) print(f[{idx 1}/{total}] {filename} 完成) except Exception as e: print(f[{idx 1}/{total}] {filename} 失败: {e})实际项目中批量任务还可以增加队列管理、失败重试和日志记录。7. 资源占用与性能观察7.1 显存占用观察方法在推理过程中可以用 NVIDIA 官方的 nvidia-smi 工具查看显存占用。nvidia-smi -l 1参数 -l 1 表示每秒刷新一次。也可以通过 Python 查看import torch print(torch.cuda.memory_allocated() / 1024**2, MB)更准确的方式是同时运行检测程序然后在另一个终端中持续采样 nvidia-smi记录峰值显存。7.2 CPU 推理与 GPU 推理差异YOLOv8n 在 CPU 上可以运行但速度较慢。一张 640x640 的图片CPU 推理可能需要几百毫秒甚至更久具体取决于 CPU 性能。GPU 推理可以明显提速但前提是 PyTorch 安装正确、CUDA 可用。摄像头实时检测场景中如果 CPU 推理帧率过低最直接的优化方式是把输入帧缩小到 640x640 以下或者改用 YOLOv8n half 精度。7.3 推理参数对性能的影响YOLOv8 的 predict 方法有几个参数直接影响性能conf置信度阈值。阈值越高检测框越少计算量略有变化。imgsz输入分辨率。分辨率越高计算量越大小目标检测效果越好。device指定 GPU 或 CPU。half是否开启半精度推理GPU 上可以加速。示例results model.predict(sourceframe, conf0.3, imgsz640, device0, halfTrue)7.4 降低显存占用的方法如果显存不足优先考虑以下手段降低输入分辨率从 640 降到 480 或 416。使用更小的模型从 YOLOv8m 降到 YOLOv8s 或 YOLOv8n。关闭批量推理逐张处理。在 PyTorch 中开启显存清理import torch torch.cuda.empty_cache()7.5 端口与进程残留PyQt5 应用和 Flask 接口服务如果启动异常可能会有残留进程占用端口或 GPU 显存。Windows 下查看端口占用netstat -ano | findstr 5000找到对应 PID 后结束进程taskkill /PID 12345 /F如果 GPU 显存被占满但没有看到明显进程用任务管理器查看 Python 进程并结束或者重启机器。8. 常见问题与排查方法问题现象可能原因排查方式解决方案PyQt5 界面中文乱码字体或编码问题检查代码文件编码和系统字体在代码开头加 UTF-8 声明或调整字体设置打开图片后界面无显示图片路径不存在或格式不支持查看控制台是否有异常使用英文路径确认图片格式为 jpg、png点击按钮无响应信号与槽未正确连接检查 connect 是否写对确认按钮对象和槽函数存在模型加载报错权重文件缺失或版本不匹配查看错误信息中的文件路径重新下载对应权重文件推理速度很慢使用了 CPU 推理或模型较大查看 torch.cuda.is_available()安装 CUDA 版 PyTorch 或换小模型摄像头画面卡顿推理时间超过帧间隔打印每帧耗时降低分辨率或使用小模型批量任务中途崩溃单张图片引发异常加 try-except 打印错误跳过异常文件记录失败日志打包 exe 后界面无法打开PyQt5 依赖未完整打包检查打包日志使用 PyInstaller 收集 PyQt5 插件CUDA 不可用PyTorch 版本与显卡驱动不匹配运行 torch.cuda.is_available()重新安装对应 CUDA 版本的 PyTorch视频检测输出文件为空视频宽度高度未正确设置打印 frame.shape从输入帧读取宽高用实际值初始化 VideoWriterPyInstaller 打包 PyQt5 项目时常见的问题是缺少 Qt 平台插件。Windows 上可以尝试pyinstaller --windowed --onefile --collect-all PyQt5 main.py打包后如果启动提示缺少平台插件把 PyQt5 的 plugins 目录放到可执行文件同级的 PyQt5 目录下。9. 最佳实践与使用建议9.1 数据集层面的建议水下数据集的获取成本高需要做好规划。优先保证目标类别的均衡性垃圾和生物都要有足够的样本量。如果某些类别样本过少可以尝试数据增强包括旋转、翻转、亮度调整、对比度调整、加入水下蓝色滤镜模拟效果。标注质量直接影响模型效果。标注时要把遮挡严重的图像剔除或单独处理避免漏标和错标。对于小目标建议使用高分辨率图像训练或者使用 YOLOv8 的小目标检测头改进策略。9.2 训练层面的建议第一次训练时先用默认参数跑 50 轮确认loss能下降再调参。不要一上来就追求 mAP要先跑通全流程。训练命令参考yolo detect train dataunderwater.yaml modelyolov8n.pt epochs100 imgsz640 batch16underwater.yaml 需要配置数据集路径和类别名称path: ./datasets/underwater train: images/train val: images/val nc: 4 names: [plastic, fishing_net, glass_bottle, fish]实际类别名称需要按自己的标注方案修改。9.3 推理层面的建议推理环境要和训练环境尽量一致。如果训练时用了 640 分辨率推理时使用 640 分辨率效果通常最好。批量检测任务要设计幂等逻辑已经处理过的图片可以跳过避免重复计算。9.4 GUI 设计层面的建议PyQt5 界面不建议把所有逻辑都堆在一个文件里。建议按功能拆分模型管理模块负责模型加载、切换、参数设置。数据管理模块负责图片、视频、摄像头的输入控制。结果展示模块负责画面显示、检测统计、结果保存。批量任务模块负责批量处理、进度展示、日志记录。单独用 QThread 做批量推理或摄像头处理避免界面卡死。PyQt5 界面线程不能直接做耗时操作否则窗口会无响应。QThread 简单示例class DetectThread(QThread): update_signal pyqtSignal(object) def run(self): # 耗时推理操作 self.update_signal.emit(result)主界面中定义一个槽函数接收信号并更新界面。9.5 部署层面的建议如果系统要交付给非技术用户需要打包为 exe。打包前注意模型文件放在外部目录方便用户替换。配置文件使用 yaml 或 json方便修改类别名和阈值。首次启动时做依赖检查缺少 CUDA 时自动退回到 CPU 推理模式。10. 总结与下一步这个项目最值得尝试的点是它把目标检测和桌面交互结合得非常自然YOLOv8 提供了完整的训练和推理链路PyQt5 则解决了结果展示和人工操作的入口问题。整套架构不仅适合水下垃圾和生物检测也完全可以迁移到工业质检、安防监控、农业巡检等场景只需要替换数据集并修改类别配置。如果第一次动手建议先把 YOLOv8n 跑通确认训练、推理、GUI 显示这条链路是通的再考虑更换大模型、接入摄像头或封装接口服务。最容易踩的坑集中在三个方面CUDA 环境装错导致 GPU 不可用、水下数据集标注质量差导致模型效果差、PyQt5 界面线程未处理导致卡顿。后续的扩展方向可以考虑把 YOLOv8 替换为 YOLOv8-seg实现像素级垃圾区域分割。加入跟踪算法比如 ByteTrack 或 DeepSORT实现水下生物数量统计。结合水声传感器数据多模态融合提升检测鲁棒性。将模型转换为 TensorRT 格式部署到 Jetson 等嵌入式设备上。这套系统的核心价值不复杂它把深度学习模型从 notebook 里搬到了可交互的桌面工具里让实际使用的人可以直接看到检测效果并做出决策。沿着这个方向继续往下做能延伸出的工程空间还是很大的。
返回列表