简介这份资源是面向高校计算机、人工智能相关专业毕业设计参考的常见皮肤病辅助检测系统完整工程包适合具备一定深度学习与Python基础、需要完成目标检测类毕设的学生及自学者。项目以YOLOv8作为核心检测算法对皮肤病图像中的病变区域进行识别与分类并借助PyQt5搭建可自适应不同屏幕尺寸与分辨率的操作界面涵盖图像采集、本地图片选择、检测结果查看等交互流程同时提供训练脚本、模型权重与配置模块便于二次开发与功能扩展。压缩包共85个文件约34.32MB包含20个py源码文件、26个pyc编译文件、15张png界面素材、3个pt模型权重以及ui、xml、qrc等界面与资源描述文件目录结构清晰覆盖训练、推理、界面与工具模块。目前已有183人学习下载可作为毕设选题落地、算法调试与界面集成的实用参考。1. 从一份毕设包说起yolov8pyqt5 皮肤病检测系统能跑出什么如果你正在找一份能直接跑起来的 YOLOv8 目标检测毕设参考又恰好需要一套 PyQt5 自适应界面这个压缩包值得先解压看一眼。它不是那种只丢几个.py文件让你自己拼的“半成品”而是把训练脚本、推理脚本、UI 文件、QSS 样式、预训练权重、测试图片和视频都塞进了一个目录里。皮肤病辅助检测这个场景本身不算新但把 YOLOv8 的检测能力和 PyQt5 的界面响应串成一条完整链路对刚接触目标检测部署的人来说省掉的是大量“找文件、对路径、调接口”的碎片时间。你拿到手后最直接的验证方式就是跑MainProgram_pifubing.py看它能不能加载best.pt并对test-file里的图片出框。适合谁适合需要快速理解“检测模型怎么被界面调用”的毕设选手也适合想拿一套现成 UI 壳子套自己模型的开发者。但别急着把它当成生产级系统它的定位是参考实现不是医疗器械软件。2. 拆开压缩包yolov8 推理链路与 pyqt5 界面骨架怎么对上2.1 模型加载与推理入口从best.pt到detect_tools.py这个项目里真正干检测活的是detect_tools.py它把 YOLOv8 的推理封装成了几个函数供界面层调用。你打开models目录能看到best.pt这是已经训练好的皮肤病检测权重。常见做法是直接用 Ultralytics 的YOLO类加载然后调predict或track。但这份代码没有直接裸写而是包了一层方便界面传参。下面是我根据项目结构还原出的典型调用方式你对照detect_tools.py里的实际函数名改一下就能用# detect_tools.py 中常见的推理封装逻辑 from ultralytics import YOLO import cv2 import numpy as np class DetectTools: def __init__(self, model_pathmodels/best.pt): # 加载 YOLOv8 模型首次加载会编译计算图稍慢 self.model YOLO(model_path) # 皮肤病检测通常置信度不用设太高0.25 是常见起点 self.conf_threshold 0.25 # IoU 阈值控制重叠框合并0.45 对密集小病灶比较友好 self.iou_threshold 0.45 def detect_image(self, img_path): # 读取图片注意 OpenCV 默认 BGRYOLO 内部会处理 img cv2.imread(img_path) if img is None: raise FileNotFoundError(f图片读取失败: {img_path}) # 执行推理verboseFalse 避免控制台刷屏 results self.model.predict( sourceimg, confself.conf_threshold, iouself.iou_threshold, verboseFalse ) # results[0].boxes 里存了框、类别、置信度 boxes results[0].boxes # 把结果转成界面能用的列表格式 detections [] for box in boxes: x1, y1, x2, y2 box.xyxy[0].tolist() cls_id int(box.cls[0]) conf float(box.conf[0]) detections.append({ bbox: [x1, y1, x2, y2], class_id: cls_id, confidence: conf }) return detections, results[0].plot() # plot() 返回画好框的 numpy 图这段代码的关键参数有三个conf决定多低的置信度才保留框皮肤病图像里有些病灶边界模糊设太高会漏检设太低会误报0.25 是平衡点iou控制非极大值抑制的合并力度如果同一块皮损被重复框选就调低这个值verbose建议关掉不然控制台输出会干扰 PyQt5 的事件循环。results[0].plot()返回的是画好框的 BGR 图可以直接转成 QImage 显示在界面上。如果你要换成自己的模型只需要改model_path但类别数变了的话界面上的类别标签映射也要跟着改通常在Config.py里。2.2 PyQt5 自适应界面win自适应.py和 QSS 怎么配合界面部分的核心文件是win自适应.py和MainProgram_pifubing.py前者负责窗口缩放时控件跟着变后者是主业务逻辑。项目里还带了style.css和QssLoader.py说明样式是外挂的不是硬编码在 Python 里。这种做法的好处是改颜色、改圆角不用动业务代码。自适应这块常见做法是用QHBoxLayout和QVBoxLayout嵌套再配合QSpacerItem做弹性占位而不是手动算坐标。下面是一个能抄的骨架# win自适应.py 中典型的自适应窗口初始化 from PyQt5.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton from PyQt5.QtCore import Qt from QssLoader import QssLoader # 项目自带的样式加载器 class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(皮肤病辅助检测系统) # 设置最小尺寸防止缩太小控件重叠 self.setMinimumSize(1024, 768) # 加载 QSS 样式style.css 里定义了按钮、标签的外观 self.setStyleSheet(QssLoader.load_qss(style.css)) central QWidget() self.setCentralWidget(central) # 主布局用水平分割左边显示图片右边放控制按钮 main_layout QHBoxLayout(central) # 左侧图片显示区用 QLabel 承载 QPixmap self.image_label QLabel(请上传皮肤病图片) self.image_label.setAlignment(Qt.AlignCenter) self.image_label.setMinimumSize(640, 480) # 设置伸缩因子窗口拉大时图片区优先扩展 main_layout.addWidget(self.image_label, stretch3) # 右侧按钮区垂直排列 btn_layout QVBoxLayout() self.btn_load QPushButton(选择图片) self.btn_detect QPushButton(开始检测) self.btn_camera QPushButton(摄像头检测) btn_layout.addWidget(self.btn_load) btn_layout.addWidget(self.btn_detect) btn_layout.addWidget(self.btn_camera) btn_layout.addStretch() # 底部留白按钮靠上 main_layout.addLayout(btn_layout, stretch1)这里stretch参数是自适应的关键左边给 3、右边给 1窗口拉宽时图片区会分到更多空间。QssLoader是项目里现成的它读style.css并返回字符串你只要保证路径对就行。style.css里通常定义了QPushButton的background-color、border-radius、hover状态改起来比在 Python 里写setStyleSheet清爽。注意UiMain_pifubing.py和UiMain_pifubing.ui是 Qt Designer 生成的如果你要改布局建议直接改.ui文件再用pyuic5转成.py不要手改生成文件否则下次转换就覆盖了。2.3 图片、视频、摄像头三路输入怎么统一到同一个检测函数项目里有imgTest.py、VideoTest.py、CameraTest.py分别对应图片、视频文件、摄像头。这三个入口最后都调detect_tools.py里的检测函数只是数据源不同。图片是单帧视频是逐帧循环摄像头是持续取流。常见做法是把检测逻辑抽成一个process_frame(frame)然后三个入口各自负责取帧和显示。下面是一个统一调用的示例# 统一帧处理逻辑imgTest/VideoTest/CameraTest 都调它 import cv2 from detect_tools import DetectTools detector DetectTools(models/best.pt) def process_frame(frame): # frame 是 BGR numpy 数组 results detector.model.predict( sourceframe, conf0.25, iou0.45, verboseFalse ) # 拿到画好框的图 annotated results[0].plot() return annotated # 图片测试 img cv2.imread(test-file/test1.jpg) out process_frame(img) cv2.imwrite(save_data/result_test1.jpg, out) # 视频测试 cap cv2.VideoCapture(vedios/demo.mp4) while cap.isOpened(): ret, frame cap.read() if not ret: break out process_frame(frame) cv2.imshow(Video, out) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()摄像头那块把VideoCapture的参数改成0就行。注意视频和摄像头模式下如果每帧都调predict帧率会掉得厉害常见优化是隔帧检测或者把模型转成 TensorRT但这份毕设包没带 TensorRT 部分属于可以自己加分的扩展点。save_data目录用来存检测结果test-file里放了测试图片vedios里放了测试视频跑之前确认这些目录存在否则会报路径错误。3. 环境配置与依赖安装requirements.txt 里没写全的坑3.1 从 requirements.txt 到实际能跑的 Python 版本项目里带了requirements.txt和installPackages.py但根据__pycache__里的.cpython-39、.cpython-38、.cpython-310后缀这份代码至少在 Python 3.8、3.9、3.10 下都跑过。我一般会选 Python 3.9因为 PyQt5 和 Ultralytics 在 3.9 下兼容性最稳。requirements.txt里通常列了ultralytics、pyqt5、opencv-python、numpy这些但版本号可能没锁死。直接pip install -r requirements.txt有时会拉到最后不兼容的版本尤其是ultralytics更新快API 偶尔变。稳妥做法是先建虚拟环境再按下面顺序装# 创建虚拟环境Python 3.9 兼容性最好 python -m venv venv_pifu # Windows 激活 venv_pifu\Scripts\activate # Linux/Mac 激活 source venv_pifu/bin/activate # 先装 PyQt5指定 5.15 系列避免 Qt6 的兼容问题 pip install PyQt55.15.9 # 装 OpenCV用 opencv-python 而不是 opencv-contrib减少体积 pip install opencv-python4.8.1.78 # 装 Ultralytics如果 requirements 里没锁版本建议锁一个稳定版 pip install ultralytics8.0.200 # 最后装项目 requirements 里剩下的 pip install -r requirements.txtinstallPackages.py里可能写了自动安装逻辑但我不建议直接跑它因为它可能用os.system(pip install ...)批量装出错时不好定位。手动一条条装哪条报错就单独处理。如果ultralytics装完导入报No module named ultralytics检查是不是虚拟环境没激活或者 pip 指向了系统 Python。3.2 权重文件与字体资源的放置位置models/best.pt是检测权重Font/platech.ttf是界面用的字体。这两个文件如果路径不对程序启动就会报错。Config.py里通常定义了MODEL_PATH和FONT_PATH你打开确认一下是不是相对路径。如果是相对路径那运行目录必须是项目根目录不能在子目录里执行python MainProgram_pifubing.py。常见做法是在入口文件开头加一句os.chdir(os.path.dirname(os.path.abspath(__file__)))把工作目录切到脚本所在目录这样不管从哪执行都能找到文件。字体加载用QFontDatabase.addApplicationFont如果platech.ttf加载失败界面会回退到默认字体不影响功能但样式会变。ui_sources.qrc和ui_sources_rc.py是 Qt 资源文件里面可能打包了图标如果图标显示不出来检查ui_sources_rc.py有没有被正确导入。3.3 用test.py做最小化验证项目根目录有个test.py我猜它是用来做快速验证的可能只跑一张图看模型能不能出结果。在你调界面之前先跑test.py确认模型和依赖没问题。如果test.py能出框说明 YOLOv8 和权重是好的问题就缩小到 PyQt5 界面层。如果test.py就报错那先解决环境问题别急着调 UI。常见错误是cv2.imshow在无显示器的服务器上报错那种情况把显示部分注释掉只保存结果图就行。4. 避坑与排查跑不起来时先看这五条4.1 现象启动报ModuleNotFoundError: No module named PyQt5但 pip 显示已安装原因通常是虚拟环境没激活或者 PyQt5 装到了系统 Python 而脚本用的是另一个解释器。PyCharm 里尤其常见项目解释器和你终端里的python不是同一个。解决在 PyCharm 的Settings Project Python Interpreter里确认解释器路径然后在那个解释器下重新pip install PyQt5。命令行里用which python和pip -V核对路径是否一致。4.2 现象界面能打开但点“开始检测”没反应控制台也不报错原因多半是信号槽没连上或者检测函数在子线程里抛了异常被吞了。PyQt5 里如果槽函数执行时间长界面会卡死但不会报错。解决在MainProgram_pifubing.py里找到按钮的clicked.connect确认连到了正确的槽函数。然后在槽函数第一行加print(检测开始)看有没有输出。如果没输出说明信号没连上如果有输出但没结果把检测函数用try...except包起来把异常打印出来。4.3 现象检测结果框画出来了但类别标签全是错的原因通常是best.pt的类别索引和界面里写的类别名对不上。YOLOv8 的results[0].names里存了类别名但界面可能硬编码了一个列表。解决打开Config.py或detect_tools.py找到类别名列表和results[0].names打印出来对比。如果模型是 7 类界面写了 5 类那索引就错位了。直接改成从results[0].names动态取别硬编码。4.4 现象视频检测时界面卡死窗口无响应原因是在主线程里逐帧跑predictYOLOv8 单帧推理在 CPU 上可能几百毫秒视频帧率一高就堵死事件循环。解决把检测放到QThread里通过信号把结果发回主线程显示。或者简单点隔帧检测每两帧处理一次。如果只是演示把视频分辨率降下来也能缓解。项目里precess_bar.py可能是个进度条组件可以配合线程用。4.5 现象best.pt加载报UnpicklingError或版本不匹配原因是权重是用更高版本 Ultralytics 训练的你本地装的版本太低。解决先pip show ultralytics看版本然后升级到和训练时一致的版本。如果不知道训练版本就升到最新稳定版再试。如果还不行用torch.load手动加载看报什么错但一般直接升级 Ultralytics 就能解决。注意升级后 API 可能有细微变化比如predict的参数名对照官方文档改一下。5. 进阶技巧把检测结果导出成结构化数据并做置信度过滤跑通界面只是第一步真正做毕设答辩时老师常问“检测结果能不能量化”。这份代码默认只画框不存数据。我一般会加一个导出功能把每张图的检测结果存成 JSON 或 CSV包含文件名、类别、置信度、边界框坐标。这样后续做统计图表、算准确率都有依据。下面是一个可以直接嵌到detect_tools.py里的导出函数import json import os from datetime import datetime def export_detections(detections, img_path, save_dirsave_data/json): # 确保输出目录存在 os.makedirs(save_dir, exist_okTrue) # 用图片名加时间戳做文件名避免覆盖 base_name os.path.splitext(os.path.basename(img_path))[0] timestamp datetime.now().strftime(%Y%m%d_%H%M%S) out_path os.path.join(save_dir, f{base_name}_{timestamp}.json) # 组装结构化数据 record { image: img_path, detect_time: timestamp, num_objects: len(detections), objects: [] } for det in detections: # 置信度低于 0.3 的单独标记方便后续过滤 record[objects].append({ class_id: det[class_id], confidence: round(det[confidence], 4), bbox_xyxy: [round(v, 2) for v in det[bbox]], low_confidence: det[confidence] 0.3 }) with open(out_path, w, encodingutf-8) as f: json.dump(record, f, ensure_asciiFalse, indent2) return out_path这个函数的关键在于low_confidence字段它把置信度低于 0.3 的框标出来但不过滤掉。为什么不过滤因为皮肤病检测里低置信度的框可能是早期病灶直接扔掉会漏检。答辩时你可以展示“系统保留低置信度结果供医生复核”这比一刀切过滤更合理。round保留四位小数是为了 JSON 可读性坐标保留两位小数够用了。导出目录save_data/json和项目原有的save_data不冲突你可以在界面加个“导出结果”按钮调这个函数。另一个技巧是批量测试。test-file里如果有多张图写个循环跑完所有图统计每类的平均置信度和检出数量输出一个汇总表。这个表可以直接放进毕设论文的“实验结果”章节。我习惯在test.py里加这段import os import cv2 from detect_tools import DetectTools, export_detections detector DetectTools(models/best.pt) test_dir test-file summary {} for fname in os.listdir(test_dir): if not fname.lower().endswith((.jpg, .png, .jpeg)): continue fpath os.path.join(test_dir, fname) detections, annotated detector.detect_image(fpath) export_detections(detections, fpath) # 统计每类数量 for det in detections: cls det[class_id] summary[cls] summary.get(cls, 0) 1 # 保存画框图 cv2.imwrite(fsave_data/{fname}, annotated) print(类别检出统计:, summary)跑完这个你手里就有每类的检出次数和每张图的 JSON 明细。答辩时被问到“系统对哪类皮肤病检出率高”直接翻 JSON 算一下就行。从那以后我每次拿到检测类毕设都先跑一遍批量测试出统计表再调界面这样心里有底。希望帮到你。本文还有配套的精品资源点击获取