尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

基于YOLOv8和PyQt5的锂电池表面缺陷检测系统实战解析

发布时间:2026/9/26 14:09:45

资讯中心
01
ARTICLE

基于YOLOv8和PyQt5的锂电池表面缺陷检测系统实战解析

基于YOLOv8和PyQt5的锂电池表面缺陷检测系统实战解析
简介一套面向本科毕业设计的锂电池表面缺陷检测完整工程方案融合YOLOv8目标检测算法与PyQt5自适应界面覆盖模型权重、训练脚本、GUI交互及多格式结果输出。针对锂电池表面常见的划痕、裂纹、鼓包与杂质等缺陷提供实时识别与可视化检测适合机器视觉、深度学习方向的毕设选题与横向项目参考。压缩包共含89个文件整体约76MB以Python源码.py、编译缓存.pyc、PyTorch权重.pt及UI描述.ui/.qrc为主辅以图片、视频、XML标注和TTF字体等素材可支撑数据准备、模型训练、界面调试与结果验证全流程。目前已有266人学习下载包内特意提供程序运行说明、预训练模型、测试图像与检测结果录屏便于快速复现和二次开发也方便替换自有数据完成迁移训练增强毕设项目完整度与答辩说服力。1. 锂电池表面缺陷检测为什么我把毕业设计押在 YOLOv8 和 PyQt5 上如果你的毕业设计题目叫「基于深度学习的锂电池表面缺陷检测」大概率会遇到三个尴尬数据集只有几百张、实验室机器跑不动大模型、导师要求必须有个能点开看的界面。我当初选型时直接锁定了 YOLOv8 加 PyQt5 这套组合原因是它把训练成本、检测精度和界面开发三者压到了一个本科生能承受的范围。YOLOv8 的 n/s 系列模型在 GTX 1660 Ti 这种级别的显卡上就能完成训练PyQt5 则负责把检测结果、实时视频流和缺陷标注做成一个自适应窗口不用写一行 Web 代码。这套方案做出来的系统既能跑离线图片检测也能接摄像头做实时检测还能把每个缺陷的位置和类别导出成报告。适合的读者很明确正在做基于 YOLOv8 的毕业设计、需要交付一个可演示系统、又不想被界面开发拖死的人。2. 从缺陷样本到 YOLOv8 训练集标注、格式转换与数据增强2.1 先搞清锂电池表面缺陷到底要检测什么锂电池表面的缺陷类别通常集中在极片划痕、凹坑、脏污、气泡、露箔这几类。其中划痕和凹坑是出现频率最高的两类也是检测模型最容易混淆的两个类别。划痕是线状的低灰度区域凹坑则是椭圆形的暗斑两者在灰度图上很接近但在形态上差异明显。标注时如果只框出不规则的外接矩形模型很难区分这两类建议对细长划痕使用旋转框标注工具对凹坑和脏污使用普通矩形框。我一般会在标注前先按缺陷类别把图片分到不同文件夹这样 Labelme 打开时能直接看到类别清单避免边标边想类别名导致标注质量下降。数据集的规模不需要追求几千张。锂电池表面缺陷的形态相对固定背景是电池极片或外壳干扰物少300 到 500 张图片、每张包含 1 到 3 个缺陷就已经足够训练出一个能用于演示的模型。关键是要保证每类缺陷的数量均衡如果划痕有 800 个框而凹坑只有 50 个框训练出来的模型会对凹坑极不敏感。我通常要求每类缺陷的标注框数量不低于 200 个不够就通过数据增强补。2.2 Labelme 标注完怎么转成 YOLOv8 能用的格式YOLOv8 需要的标签格式是 txt 文件每行一个目标内容是「类别id x_center y_center width height」坐标全部归一化到 0 到 1 之间。Labelme 保存的是 JSON 格式里面记录的是多边形顶点坐标所以必须写转换脚本。转换的逻辑不复杂读取 JSON 文件中的 shapes 字段把每个多边形的顶点坐标转换成外接矩形的左上角和右下角坐标再除以图片宽度和高度做归一化。但这里有个关键点Labelme 的 JSON 里图片路径可能是绝对路径转换后的图片和标签文件必须放到同一级目录下否则 YOLOv8 训练时会报图片不存在的错误。下面是我常用的转换脚本基于 labelme 的 shapely 库计算外接矩形import json import os from shapely.geometry import Polygon def labelme_to_yolo(json_path, output_dir, class_names): with open(json_path, r, encodingutf-8) as f: data json.load(f) image_path data[imagePath] img_width data[imageWidth] img_height data[imageHeight] txt_name os.path.splitext(os.path.basename(json_path))[0] .txt txt_path os.path.join(output_dir, txt_name) with open(txt_path, w) as f: for shape in data[shapes]: label shape[label] if label not in class_names: continue class_id class_names.index(label) points shape[points] polygon Polygon(points) minx, miny, maxx, maxy polygon.bounds x_center (minx maxx) / 2 / img_width y_center (miny maxy) / 2 / img_height box_width (maxx - minx) / img_width box_height (maxy - miny) / img_height # 过滤掉太小的目标避免噪声 if box_width 0.005 or box_height 0.005: continue f.write(f{class_id} {x_center:.6f} {y_center:.6f} {box_width:.6f} {box_height:.6f}\n) class_names [scratch, pit, dirty, bubble] # 用法遍历标注目录下所有 json 文件脚本中过滤掉宽高小于图片尺寸 0.5% 的目标这类目标通常是标注时手抖产生的极小的框对训练没有帮助反而会增加噪声。归一化坐标保留 6 位小数精度完全够用。转换完成后建议抽查几个 txt 文件手动比对原始图片中缺陷的位置和坐标是否吻合这一步不要省。2.3 数据增强怎么做才能不破坏缺陷特征YOLOv8 训练时自带 mosaic 增强但只靠内置增强是不够的。锂电池表面缺陷有方向性比如划痕往往是沿着极片轧制方向分布的水平翻转和垂直翻转会改变缺陷的语义方向可能导致模型学到错误的方向特征。我一般只在训练时开启水平翻转关闭垂直翻转。旋转增强可以开小角度正负 15 度以内太大的角度会让划痕的线性特征失真。光照增强对锂电池表面缺陷检测非常有用。实际产线上拍摄环境的光照不稳定偏亮或偏暗都会影响缺陷的可见度。可以用 OpenCV 做随机的亮度对比度调整import cv2 import numpy as np def adjust_lighting(image): # 随机调整亮度和对比度模拟产线光照波动 alpha np.random.uniform(0.8, 1.2) # 对比度系数 beta np.random.uniform(-30, 30) # 亮度偏移 adjusted cv2.convertScaleAbs(image, alphaalpha, betabeta) return adjusted # 在训练前对每张图做预处理注意标签不变只改像素这个增强操作不影响目标位置和类别所以标签文件不需要改动。另外一个容易忽略的坑是图像分辨率。锂电池表面缺陷很多是小目标比如凹坑直径只有十几个像素如果原始图片是 4000x3000 的大图直接 resize 到 640x640 会让小目标几乎消失。建议先对原图按缺陷尺寸做裁剪或分块而不是直接统一缩放。如果图片里缺陷区域占比很小可以采用滑窗裁剪把图片切成若干块再对每块做标注和训练这样模型能学到更多细节。3. 训练 YOLOv8 检测模型参数调优与损失曲线判读3.1 用 GPU 还是 CPU 训练怎么选参数训练环境的选择直接影响毕业设计进度。标题场景下的数据集通常不大几百张图片在 GTX 1660 Ti 上用 YOLOv8s 训练 100 个 epoch大约需要两到三个小时。如果是纯 CPU 环境同样配置可能要跑十几个小时不建议在 CPU 上训练超过 100 个 epoch。如果只有 CPU换 YOLOv8n 并减小输入尺寸到 480同时开启缓存数据到内存能显著加快训练。至于 Ubuntu 20.04 搭建 YOLOv8 CPU 环境核心是装好 PyTorch 的 CPU 版本然后 pip install ultralytics 即可不需要额外配置 CUDA。训练命令我一般写成脚本而不是一行命令方便调整参数后重新执行yolo train \ modelyolov8s.pt \ datali_battery.yaml \ epochs100 \ imgsz640 \ batch16 \ optimizerSGD \ lr00.01 \ lrf0.01 \ mosaic0.8 \ close_mosaic10 \ patience15 \ project./runs \ namebattery_defect_v1 \ device0参数说明model 使用 yolov8s.pt 预训练权重COCO 上预训练过的模型对边缘、纹理等基础特征有更好的提取能力迁移到缺陷检测上收敛更快。data 指向数据集配置文件里面写了 train 和 val 的图片路径以及类别名。mosaic 默认是 1.0对缺陷检测建议降到 0.8因为 mosaic 拼接的四张图会让小目标的上下文信息错乱。close_mosaic10 表示最后 10 个 epoch 关闭 mosaic 增强让模型在真实分布上微调这是 YOLOv8 官方推荐的做法。patience 是早停参数15 个 epoch 内验证集 mAP 没有提升就自动停止省时间。3.2 loss 曲线和 mAP 怎么判断模型真的收敛了训练结束后先去 runs/battery_defect_v1 目录看 results.csv 文件这里面记录了每个 epoch 的 box_loss、cls_loss、dfl_loss 和 mAP50、mAP50-95。判断模型是否有效的标准不是 loss 归零而是验证集上的 mAP50 是否达到 0.85 以上。锂电池表面缺陷背景简单、类别少mAP50 如果低于 0.8基本可以判断是标注质量或数据量出了问题。画损失函数曲线图时不要只看训练集 loss要把训练集和验证集的 loss 画在同一张图上。如果训练 loss 持续下降但验证 loss 先降后升说明过拟合了需要增加数据增强或减少 epoch。如果两个 loss 都在高位震荡不下降先检查数据集的标签文件是否为空这是最常犯的错误。转换脚本跑完没有检查 txt 文件内容导致训练时模型没有正样本loss 一直不降。3.3 换更小的模型还是加大输入尺寸先动哪个当检测效果不好时优先调整输入尺寸而不是更换模型。把 imgsz 从 640 提升到 960小目标检测能力会明显提升但显存占用也会翻倍。GTX 1660 Ti 的 6GB 显存跑 960 输入时需要把 batch 降到 8 甚至 4。如果提升输入尺寸后显存不够再考虑从 YOLOv8s 换成 YOLOv8n参数量从 11M 降到 3.2M训练速度翻倍精度损失在简单背景场景下通常不超过 3 个点。还有一个容易被忽略的参数是 anchor 相关配置YOLOv8 是 anchor-free 结构不需要手动调 anchor但如果检测目标全是小目标可以增大输入尺寸让特征图上的目标像素占比更大。4. PyQt5 自适应界面怎么搭从图片检测到摄像头实时流4.1 界面布局用 QGridLayout 还是 QHBoxLayoutPyQt5 界面设计的核心诉求是自适应。用户拖动窗口大小时图片显示区、控制按钮区、检测结果列表都要跟着等比缩放不能出现按钮被挤掉或图片显示不全的问题。我一般用 QSplitter 做左右分栏左侧是控制面板右侧是检测结果区再在右侧内部用 QGridLayout 放图片显示控件和结果表格。QSplitter 允许用户手动拖动分隔条调整左右比例比固定布局更实用。控制面板的宽度用 setMaximumWidth 限制在 280 像素防止用户把面板拖太窄导致按钮文字显示不全。图片显示区用 QLabel 加 setScaledContents(True)图片会自动铺满整个 Label。但直接缩放会导致图片变形正确做法是保持图片宽高比def update_image(self, cv_img): # 将 OpenCV 的 BGR 图像转为 RGB 并显示在 QLabel 中 rgb_img cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) h, w, ch rgb_img.shape bytes_per_line ch * w qt_img QImage(rgb_img.data, w, h, bytes_per_line, QImage.Format_RGB888) label self.image_label # 计算 QLabel 的可用尺寸保持图片宽高比缩放 label_width label.width() label_height label.height() scaled_width label_width scaled_height int(label_width * h / w) if scaled_height label_height: scaled_height label_height scaled_width int(label_height * w / h) pixmap QPixmap.fromImage(qt_img).scaled( scaled_width, scaled_height, Qt.KeepAspectRatio, Qt.SmoothTransformation ) label.setPixmap(pixmap)这段代码的关键是拿 QLabel 当前尺寸动态计算缩放后的宽高然后用 Qt.KeepAspectRatio 保持比例。QLabel 在窗口 resize 事件中会自动触发更新所以要在 resizeEvent 里重新调用 update_image否则窗口拉大后图片不会跟着变大。如果图片不更新可以检查是否忘了在 resizeEvent 中调用超类方法 QLabel.resizeEvent(event)这是 PyQt5 继承中常见的翻车点。4.2 检测线程和 UI 线程为什么要分开PyQt5 的槽函数运行在主线程如果直接在槽函数里跑 YOLOv8 推理模型推理期间界面会卡死按钮点不了、窗口拖不动体验极差。正确做法是用 QThread 开一个工作线程专门跑检测主线程只管显示结果。线程之间传数据用信号槽机制工作线程发结果信号主线程负责更新界面import sys import cv2 from PyQt5.QtCore import QThread, pyqtSignal from ultralytics import YOLO class DetectThread(QThread): result_ready pyqtSignal(object, object) # 原图, 标注结果 def __init__(self, model_path): super().__init__() self.model YOLO(model_path) self.running True def run(self): cap cv2.VideoCapture(0) while self.running: ret, frame cap.read() if not ret: continue # 推理时直接让 YOLOv8 绘制标注框 results self.model(frame)[0] annotated results.plot() self.result_ready.emit(frame, annotated) cap.release() def stop(self): self.running False self.wait()这里的注意点是 YOLO 模型初始化要在 run 方法里做而不是在init里做。因为 QThread 的信号槽机制要求模型实例必须存在于工作线程的上下文如果在主线程初始化再传给子线程使用部分版本的 ultralytics 会报跨线程调用错误。实测中这个错误不是必现的但一旦出现很难排查建议直接按上面的写法把模型加载放在 run 里。4.3 自适应界面的显示控件选 QLabel 还是 QGraphicsView小尺寸界面用 QLabel 足够但如果你打算在检测结果上做缩放查看、框选区域重新检测这类交互QLabel 就不够用了。QGraphicsView 配合 QGraphicsScene 可以支持鼠标缩放和平移适合做缺陷的细节查看。缺点是代码量多一倍需要在 scene 上手动绘制标注框和文字。毕业设计答辩场景下QLabel 加 QGridLayout 的组合已经能满足演示需求。实时检测时把摄像头画面缩放到 640 分辨率再送进模型推理速度能达到 30 帧以上界面显示完全流畅。如果要同时显示原图和标注图用 QTabWidget 放两个标签页一页显示原始图像一页显示检测结果比并排显示更节省空间。5. 检测系统联调避坑数据集处理、模型导出与界面卡顿排查5.1 数据集路径写错导致的训练崩溃现象yolo train 命令启动后马上报错提示 no labels found in train set。原因data.yaml 里 train 字段的路径写的是相对路径但当前工作目录并不在项目根目录下。解决data.yaml 里统一用绝对路径或者把 train 和 val 字段写成相对于 data.yaml 文件所在目录的路径。ultralytics 在加载数据时会以当前执行命令的目录为基准解析相对路径这导致同一份配置在 Linux 和 Windows 下表现不一致。我自己的习惯是直接写死绝对路径反正数据集路径固定。5.2 模型推理速度慢不是因为模型大而是因为预处理现象用 YOLOv8s 做实时检测FPS 只有 8 到 10GPU 利用率不高。原因输入图像是摄像头读出的原始分辨率的帧1920x1080 的图像直接送进模型预处理耗时比推理耗时还长。解决先统一缩放到 640 再推理。还有一个容易被忽略的问题是没有开启 half 精度推理在 GPU 上用 model(fp16) 或导出 FP16 engine 能提高一倍速度。如果仍然卡顿检查是否在子线程里做了高分辨率图像的绘制操作QImage 转换大图本身也耗时。5.3 Labelme 安装了但 PyQt5 启动报错现象pip install labelme 成功后运行报错提示无法加载 PyQt5 的 QtWidgets 模块。原因labelme 依赖的 PyQt5 版本与机器上已有的 PyQt5 冲突常见于先装了 labelme 再装 PyQt5版本被覆盖。解决直接用 pip install pyqt55.15.4 指定版本重装一次labelme 运行的是它内部虚拟环境还是系统环境要确认清楚。如果是在 Anaconda 里用的 labelme不要同时给 base 环境装 PyQt5单独建一个标注用的虚拟环境最省事。5.4 自适应窗口缩放时图片区域出现黑边现象窗口拉大后 QLabel 显示区域变大很多图片周围出现大片黑边。原因QLabel 设置了 stylesheet 的 background-color缩放后图片没有重新计算尺寸。解决在 resizeEvent 里重新调用 update_image 方法并且把 QLabel 的 sizePolicy 设置为 Expanding让它能随窗口变化自动调整。如果黑边仍然存在检查 update_image 里拿到的 label_width 和 label_height 是否是像素值PyQt5 在 HiDPI 屏幕上可能返回逻辑尺寸需要乘以 devicePixelRatio。5.5 训练完的模型在 PyQt5 里加载特别慢现象程序启动后要卡两三秒才会出现主界面。原因YOLOv8 模型初始化时要加载权重并做预热推理。解决启动时先显示一个极简的加载窗口子线程里加载模型加载完成后再弹主界面。或者更简单的做法第一次推理前显示「模型加载中」的状态提示避免用户以为程序崩溃。实测中 YOLOv8s 的 pt 文件约 20MB加载耗时主要花在 CUDA 初始化上在 GPU 环境首次加载需要一到两秒这是正常现象不用优化。6. 把模型部署到界面后的进阶验证用视频抽帧测试漏检率和单类精度模型训练完、界面跑通后立刻用批量图片测试远远不够。我会准备一段 30 秒的测试视频从里面均匀抽帧逐帧跑检测统计漏检率。锂电池缺陷检测最怕的不是精度不够而是漏检一个凹坑没被框出来整个系统的可信度就崩了。抽帧测试的目的就是找出模型在哪些角度、哪些光照条件下会漏检。实操方法是写一个简单的脚本按固定间隔抽帧后预测并保存标注结果import cv2 from ultralytics import YOLO model YOLO(runs/battery_defect_v1/weights/best.pt) cap cv2.VideoCapture(test_video.mp4) total_frames int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) interval max(1, total_frames // 100) # 最多抽100帧 frame_idx 0 saved_count 0 while True: ret, frame cap.read() if not ret: break if frame_idx % interval 0: results model(frame, conf0.25, iou0.45)[0] annotated results.plot() cv2.imwrite(feval_frames/frame_{frame_idx:06d}.jpg, annotated) saved_count 1 frame_idx 1 print(fevaluated {saved_count} frames)跑完后把抽帧结果拼成一张大图或者按目录翻看重点找两类问题一是漏检即缺陷区域没有框二是类别混淆即划痕被标成了凹坑。找到问题后回到数据层面补样本把检错的帧裁剪出来重新标注并加入训练集。这个闭环迭代才是工程落地的核心模型不是一次训练完就结束的。至于 PyQt5 界面上的最终交付我会在界面里加一个置信度滑条最低设在 0.2最高设在 0.7拖动后立即重新检测当前帧。这样答辩时可以现场演示不同置信度下的检测效果比固定参数有说服力。界面的自适应部分千万别过度设计只要保证窗口缩放不崩、图片不拉伸变形、检测结果显示清晰就能满足验收的演示需求。最后说一个习惯我每次训练完都会把 best.pt 单独复制一份在名字里注明训练日期和 mAP 值防止后续改数据集重新训练把之前的权重覆盖了。这个后悔药在赶毕业设计时特别有用你永远不知道下一次训练会不会直接翻车。希望这篇文章能帮你在毕业设计的这条路上少踩几个数据标注和界面开发的坑。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。