YOLOv8+PySide6金属表面缺陷检测系统实战

发布时间:2026/9/3 3:57:24
YOLOv8+PySide6金属表面缺陷检测系统实战 说到工业金属表面缺陷检测很多团队第一反应是上传统机器视觉方案打光、工业相机、固定阈值分割、形态学处理。这套玩法在小批量、单一材质、固定光照的场景下确实能用但换一条产线、换一种金属纹理、光照稍微偏一点算法参数就要重新调一轮。更头疼的是划痕、氧化斑、凹坑、麻点这类缺陷本身形态变化大传统特征工程很难用一个通用规则全部覆盖。最近在做金属表面缺陷检测项目时我把 YOLOv8 和 PySide6 组合起来搭了一套从数据集标注、模型训练到桌面端推理的完整流程。这套方案的好处是检测模型用 YOLO 系算法训练和部署链路成熟界面用 PySide6 开发能做到本地离线运行、批量导入图片、实时查看检测结果。本文就把这套流程完整拆开从环境准备、数据集制作、模型训练、界面开发到常见问题排查全部过一遍。1. 背景与核心概念1.1 工业金属表面缺陷检测为什么难金属零部件的表面质量直接影响产品性能和寿命。比如汽车齿轮表面如果存在细小裂纹装配后可能直接导致疲劳断裂轴承滚珠有麻点运行噪音和磨损都会超标精密模具表面划伤会直接复刻到压铸件上。因此金属表面缺陷检测是工业质检环节的核心任务之一。但金属表面检测有几个天然难点缺陷种类杂划痕、凹坑、麻点、氧化斑、边缘破损、焊渣飞溅形态差异大。纹理干扰强金属加工纹路、拉丝纹理、反光区域很容易被误判为缺陷。缺陷尺寸小细小划痕可能只有几十个像素宽对检测网络的分辨率要求很高。样本不均衡良品数量远大于缺陷品正负样本比例可能到几百比一。实时性要求产线节拍快单张图片检测耗时必须控制在几十毫秒到几百毫秒级别。传统视觉方案需要针对每种缺陷单独设计滤波器和特征算子开发周期长泛化能力弱。而基于深度学习的检测模型可以通过数据驱动自动学习缺陷特征迁移到新产线时只需要重新标注和训练省掉大量人工调参工作。1.2 YOLOv5 和 YOLOv8 选哪个YOLO 系列是目前工业目标检测落地最广的算法之一。YOLOv5 虽然官方仓库不是 Ultralytics 最初命名的那家公司但社区生态非常完善网上资料多TensorRT 部署和模型导出工具链成熟。YOLOv8 则是 Ultralytics 官方在 YOLOv5 基础上更新的大版本核心改进包括网络结构换成 C2f 模块梯度流动更丰富。Head 部分采用 Anchor-Free 解耦头分类和回归分支分离。内置支持分类、检测、分割、姿态估计等多个任务。训练时引入更多数据增强策略。模型导出支持 ONNX、TensorRT、OpenVINO 等格式。实际项目里如果现有系统基于 YOLOv5 且已经完成 TensorRT 加速继续用 YOLOv5 没毛病如果是新项目建议直接用 YOLOv8训练代码更简洁ultralytics 库统一管理后续维护更省心。本文主要基于 YOLOv8 演示但整体流程对 YOLOv5 同样适用。1.3 PySide6 在桌面端的作用PySide6 是 Qt 6 的 Python 绑定可以用来开发跨平台桌面应用。在缺陷检测系统里PySide6 承担的角色是可视化交互层加载模型、导入待检测图片、显示检测结果、统计缺陷数量、保存检测报告。选 PySide6 而不是 PyQt 或 Tkinter主要看重几点界面组件丰富支持表格、画布、拖拽、文件对话框。QThread 信号槽机制适合做模型推理这种耗时任务不会卡死界面。相比 PyQtPySide6 使用 LGPL 协议商业应用限制更少。与 OpenCV、NumPy 配合方便图像数据可以直接转为 QImage 显示。2. 系统整体方案设计2.1 检测流程整个系统分为两部分离线训练阶段和在线推理阶段。离线训练阶段采集金属表面图片 - 标注缺陷目标框 - 划分训练集/验证集 - 配置模型 yaml - 训练 YOLOv8 - 评估指标 - 导出模型在线推理阶段PySide6 界面启动 - 加载模型权重 - 用户导入图片/选择目录 - 模型推理 - 在图片上绘制检测框和标签 - 界面展示结果 - 统计缺陷数量 - 保存检测结果图片或报告2.2 模块划分metal_defect_system/ ├── datasets/ │ ├── metal_defect/ │ │ ├── images/ │ │ │ ├── train/ │ │ │ └── val/ │ │ └── labels/ │ │ ├── train/ │ │ └── val/ │ └── metal_defect.yaml ├── model/ │ ├── yolov8n.pt │ └── best.pt ├── app/ │ ├── main.py │ ├── detector.py │ ├── main_window.py │ └── ui/ └── runs/ └── detect/datasets数据集和类别配置文件。model模型权重和训练输出。appPySide6 桌面应用代码。runsultralytics 默认的训练输出目录。2.3 技术选型说明模块推荐选型说明检测算法YOLOv8n / YOLOv8s工件表面缺陷尺寸小建议输入分辨率 640 或 1280训练框架ultralytics统一 API训练、验证、导出一条龙推理后端CPU 或 CUDAGPU 优先GTX 1660 Ti 级别即可流畅跑界面框架PySide6跨平台桌面应用支持线程分离图像处理OpenCV图片读取、缩放、绘制框打包发布PyInstaller将 Python 应用打包为 exe3. 环境准备与安装3.1 基础环境说明本文示例环境以 Windows 10/11 为主Python 使用 3.9 或 3.10 版本。需要说明的是不同版本的 PySide6、PyTorch、ultralytics 对 Python 版本要求不同实际安装时请先确认本机 Python 版本避免依赖冲突。推荐环境操作系统Windows 10/11 或 Ubuntu 20.04/22.04 Python3.9 或 3.10 CUDA11.8 或 12.1如果使用 GPU PyTorch2.x ultralytics8.x PySide66.5 或更高 OpenCV4.8 或更高3.2 创建虚拟环境使用 conda 创建虚拟环境避免多个项目依赖互相污染conda create -n metal_defect python3.10 conda activate metal_defect如果电脑没有安装 conda也可以用 venvpython -m venv metal_defect_env metal_defect_env\Scripts\activate3.3 安装 PyTorchGPU 版本安装命令需要根据本机 CUDA 版本调整建议先到 PyTorch 官网确认。以 CUDA 11.8 为例pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118如果只是 CPU 环境做界面演示可以执行pip install torch torchvision torchaudio这里提醒一下训练模型时强烈建议使用 GPU否则 YOLOv8n 在 CPU 上训练一个 epoch 可能就要很久影响调试效率。3.4 安装 ultralytics 和 PySide6pip install ultralytics pip install pyside6 pip install opencv-python pip install numpy安装完成后验证import torch import ultralytics from PySide6.QtWidgets import QApplication print(torch:, torch.__version__) print(cuda available:, torch.cuda.is_available()) print(ultralytics:, ultralytics.__version__)如果能正常输出说明环境就绪。4. 数据集准备与标注4.1 数据采集注意事项金属表面缺陷检测的数据集质量和数量直接决定模型效果。采集图片时需要注意覆盖多角度光照同一类缺陷在不同光照下形态差异很大最好覆盖暗场、亮场、侧光等多种光源角度。覆盖多材质不锈钢、铝合金、铸铁、铜件的反光特性和纹理都不一样尽量分开建类。小缺陷要多拍近景小目标缺陷在整图中占比很小模型容易漏检可以在采集时切 ROI 放大。背景要贴近真实产线如果数据集图片都是纯色背景实际部署时遇到复杂背景会掉点。4.2 数据标注推荐使用 LabelImg 或 X-AnyLabeling 进行标注。以 LabelImg 为例pip install labelimg labelimg标注时类别名称建议跟配置文件保持一致比如0: scratch # 划痕 1: pit # 凹坑/麻点 2: oxidation # 氧化斑 3: breakage # 破损标注完成后会生成 VOC 格式的 XML 文件或者 YOLO 格式的 txt 文件。4.3 YOLO 标签格式YOLO 标签是归一化坐标class_id center_x center_y width height例如0 0.512345 0.334567 0.123456 0.045678 2 0.723456 0.612345 0.087654 0.032109注意这里宽高是归一化到 0~1 的值不是像素坐标。4.4 划分数据集并生成配置如果标注结果为 VOC XML 格式需要转换成 YOLO txt 格式。下面给出一段转换脚本的核心逻辑import os import xml.etree.ElementTree as ET import random def voc_to_yolo(xml_file, class_names, output_dir): tree ET.parse(xml_file) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) txt_name os.path.splitext(os.path.basename(xml_file))[0] .txt txt_path os.path.join(output_dir, txt_name) lines [] for obj in root.findall(object): class_name obj.find(name).text if class_name not in class_names: continue class_id class_names.index(class_name) bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) x_center (xmin xmax) / 2 / img_w y_center (ymin ymax) / 2 / img_h width (xmax - xmin) / img_w height (ymax - ymin) / img_h lines.append(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) with open(txt_path, w) as f: f.write(\n.join(lines))数据集整理完成后在datasets目录下创建metal_defect.yaml# 文件路径datasets/metal_defect.yaml train: datasets/metal_defect/images/train val: datasets/metal_defect/images/val nc: 4 names: [scratch, pit, oxidation, breakage]5. 训练 YOLOv8 缺陷检测模型5.1 训练命令在项目根目录执行from ultralytics import YOLO model YOLO(yolov8n.pt) results model.train( datadatasets/metal_defect.yaml, epochs200, imgsz640, batch16, device0, workers4, patience30, namemetal_defect_yolov8n )训练如果使用命令行yolo train datadatasets/metal_defect.yaml modelyolov8n.pt epochs200 imgsz640 batch16 device05.2 关键参数解释epochs训练轮数。金属缺陷样本量不多时200 轮一般是够的。imgsz输入图片分辨率。如果小缺陷比较多建议尝试 1280但推理速度会下降。batch批大小根据显存调整。GTX 1660 Ti 6G 显存跑 YOLOv8nbatch 16 基本可以。patience早停轮数验证集指标连续多少轮不提升就停止训练防止过拟合。device设备编号0表示第一块 GPUCPU 则填cpu。workers数据加载线程数。5.3 训练过程监控训练过程中终端会实时输出每个 epoch 的 mAP、精确率、召回率、损失值。同时会在runs/detect/metal_defect_yolov8n/目录下生成results.png用于查看损失函数曲线和指标曲线。关于yolov8画损失函数曲线图这个问题ultralytics 已经自动生成了曲线图不需要自己额外画。如果你想用 CSV 数据二次绘图可以在训练结束后导入results.csv自己用 matplotlib 绘制这个后面在实际项目中很常用。5.4 数据增强与增量训练金属缺陷样本往往很难大批量采集。如果只有几百张图片建议优先使用预训练权重yolov8n.pt做迁移学习而不是从头训练。ultralytics 默认会加载 COCO 预训练权重这对小数据集非常友好。如果后续产线新增了缺陷类型可以在已有模型基础上继续训练model YOLO(runs/detect/metal_defect_yolov8n/weights/best.pt) model.train( datadatasets/metal_defect_v2.yaml, epochs100, imgsz640, batch16, device0, namemetal_defect_incremental )增量训练时注意如果新增了类别需要重新修改data配置中的nc和names不能直接沿用旧配置。5.5 验证模型效果训练完成后可以用验证集评估模型model YOLO(runs/detect/metal_defect_yolov8n/weights/best.pt) metrics model.val(datadatasets/metal_defect.yaml) print(metrics.box.map) print(metrics.box.map50)map是 mAP0.5:0.95map50是 mAP0.5。工业检测项目通常更关注 mAP0.5因为缺陷检测允许的定位精度要求因产品而异。6. 模型导出与准备6.1 导出 ONNXPySide6 应用推理可以直接加载.pt文件但为了部署稳定性和推理速度建议导出为 ONNX 格式model YOLO(runs/detect/metal_defect_yolov8n/weights/best.pt) model.export(formatonnx, imgsz640, dynamicFalse)导出后会在同目录下生成best.onnx。6.2 推理测试先用一行代码验证模型能否正常推理from ultralytics import YOLO model YOLO(runs/detect/metal_defect_yolov8n/weights/best.onnx) results model.predict(test_images/001.jpg, conf0.25, imgsz640) print(results[0].boxes)如果能看到每个检测框的xyxy、conf、cls信息说明模型可以正常使用。7. 基于 PySide6 的桌面检测系统开发7.1 界面功能设计PySide6 桌面应用主要实现以下功能选择待检测图片。批量导入整个目录下的图片。实时使用摄像头或视频流检测扩展功能。展示原图和检测结果图。显示每张图片的缺陷统计信息。导出检测结果图片和统计报告。我们拆成两个核心文件detector.py负责加载模型和推理main_window.py负责界面逻辑。7.2 detector.py 模型推理封装# 文件路径app/detector.py from ultralytics import YOLO import numpy as np class MetalDefectDetector: def __init__(self, model_path: str, conf_thres: float 0.25): self.model YOLO(model_path) self.conf_thres conf_thres def predict(self, image: np.ndarray): results self.model.predict( sourceimage, confself.conf_thres, imgsz640, verboseFalse ) return results[0] def get_class_names(self): return self.model.names这里将模型推理逻辑单独封装界面线程调用时只需要传入numpy图像即可。7.3 main_window.py 界面主窗口# 文件路径app/main_window.py import sys import cv2 import numpy as np from PySide6.QtWidgets import ( QMainWindow, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QFileDialog, QListWidget, QPlainTextEdit, QSplitter, QMessageBox, QComboBox ) from PySide6.QtCore import Qt, QThread, Signal from PySide6.QtGui import QImage, QPixmap from detector import MetalDefectDetector class InferThread(QThread): 推理线程避免界面卡顿 result_ready Signal(object, str) def __init__(self, detector, image): super().__init__() self.detector detector self.image image def run(self): result self.detector.predict(self.image) img_array result.plot() self.result_ready.emit(img_array, self.image)注意模型推理是不能放在 Qt 主线程里的否则界面会卡死。上面用一个InferThread来处理耗时逻辑推理完成后通过信号把结果传回界面。接着是主窗口的搭建class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(金属表面缺陷检测系统) self.setMinimumSize(1100, 700) self.detector None self.current_image None self.result_image None self.left_label QLabel(原始图片) self.right_label QLabel(检测结果) self.left_label.setAlignment(Qt.AlignCenter) self.right_label.setAlignment(Qt.AlignCenter) btn_load_img QPushButton(选择图片) btn_load_dir QPushButton(批量导入) btn_save QPushButton(保存结果) btn_load_model QPushButton(加载模型) self.model_combo QComboBox() self.model_combo.addItems([runs/detect/metal_defect_yolov8n/weights/best.pt, runs/detect/metal_defect_yolov8n/weights/best.onnx]) self.log_text QPlainTextEdit() self.log_text.setReadOnly(True) btn_load_model.clicked.connect(self.load_model) btn_load_img.clicked.connect(self.load_image) btn_load_dir.clicked.connect(self.load_dir) btn_save.clicked.connect(self.save_result) splitter QSplitter(Qt.Horizontal) splitter.addWidget(self.left_label) splitter.addWidget(self.right_label) layout QVBoxLayout() top_layout QHBoxLayout() top_layout.addWidget(self.model_combo) top_layout.addWidget(btn_load_model) top_layout.addWidget(btn_load_img) top_layout.addWidget(btn_load_dir) top_layout.addWidget(btn_save) top_layout.addStretch() layout.addLayout(top_layout) layout.addWidget(splitter, stretch1) layout.addWidget(self.log_text) container QWidget() container.setLayout(layout) self.setCentralWidget(container) self.log(系统初始化完成请先加载模型。) def log(self, msg): self.log_text.appendPlainText(msg) def load_model(self): model_path self.model_combo.currentText() self.detector MetalDefectDetector(model_path) self.log(f模型加载成功: {model_path}) self.log(f类别信息: {self.detector.get_class_names()}) def load_image(self): if self.detector is None: QMessageBox.warning(self, 提示, 请先加载模型) return file_path, _ QFileDialog.getOpenFileName( self, 选择图片, , 图片文件 (*.png *.jpg *.bmp *.jpeg) ) if not file_path: return image cv2.imread(file_path) image_rgb cv2.cvtColor(image, cv2.COLOR_BGR2RGB) self.current_image image_rgb self.show_image(self.left_label, image_rgb) self.log(f加载图片: {file_path}) self.infer_thread InferThread(self.detector, image_rgb) self.infer_thread.result_ready.connect(self.on_result_ready) self.infer_thread.start() self.log(开始推理...) def load_dir(self): if self.detector is None: QMessageBox.warning(self, 提示, 请先加载模型) return dir_path QFileDialog.getExistingDirectory(self, 选择目录) if not dir_path: return import os for fname in os.listdir(dir_path): if fname.lower().endswith((.png, .jpg, .bmp, .jpeg)): image_path os.path.join(dir_path, fname) image cv2.imread(image_path) image_rgb cv2.cvtColor(image, cv2.COLOR_BGR2RGB) self.current_image image_rgb self.show_image(self.left_label, image_rgb) self.log(f批量推理图片: {fname}) self.infer_thread InferThread(self.detector, image_rgb) self.infer_thread.result_ready.connect(self.on_result_ready) self.infer_thread.start() def save_result(self): if self.result_image is None: QMessageBox.warning(self, 提示, 没有可保存的检测结果) return file_path, _ QFileDialog.getSaveFileName( self, 保存结果, result.png, 图片文件 (*.png *.jpg) ) if not file_path: return cv2.imwrite(file_path, self.result_image) self.log(f结果保存至: {file_path}) def on_result_ready(self, img_array, original): self.result_image img_array img_rgb cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB) self.show_image(self.right_label, img_rgb) self.log(推理完成) staticmethod def show_image(label, img_rgb): h, w, ch img_rgb.shape bytes_per_line ch * w q_image QImage(img_rgb.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap QPixmap.fromImage(q_image) scaled pixmap.scaled( label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation ) label.setPixmap(scaled) def main(): app QApplication(sys.argv) window MainWindow() window.show() sys.exit(app.exec()) if __name__ __main__: main()7.4 关于 PySide6 QLineEdit 输入校验很多 PySide6 开发初学者会遇到一个问题如果用 QLineEdit 让用户输入置信度阈值或模型路径需要校验输入是否合法。常见的做法是调用text()获取文本后自行判断from PySide6.QtWidgets import QLineEdit, QMessageBox conf_edit QLineEdit() conf_edit.setPlaceholderText(请输入置信度阈值例如 0.25) def get_conf_value(): text conf_edit.text().strip() if not text: QMessageBox.warning(None, 提示, 置信度阈值不能为空) return None try: val float(text) except ValueError: QMessageBox.warning(None, 提示, 请输入合法数字) return None if not (0 val 1): QMessageBox.warning(None, 提示, 阈值范围应为 0~1 之间) return None return val或者使用 QDoubleValidatorfrom PySide6.QtGui import QDoubleValidator validator QDoubleValidator(0.0, 1.0, 2, conf_edit) validator.setNotation(QDoubleValidator.StandardNotation) conf_edit.setValidator(validator)用 QValidator 的好处是一开始就从输入层拦截非法字符后续取值时只需要做空值判断。7.5 运行桌面应用在app目录下执行python main.py界面启动后先选择模型文件点击“加载模型”再选择单张图片或批量导入目录右侧就能看到检测结果。8. 常见问题与排查思路8.1 问题排查表问题现象常见原因解决思路训练时 CUDA out of memorybatch 太大或输入分辨率太高调小 batch或改用 YOLOv8n降低 imgszCPU 训练速度极慢未安装 GPU 版 PyTorch检查torch.cuda.is_available()重装对应 CUDA 版本模型检测小缺陷效果差输入分辨率太低小目标特征丢失提高 imgsz 到 1280或裁剪 ROI 训练界面点击加载图片后卡死推理放在主线程阻塞 Qt 事件循环使用 QThread 执行推理PySide6 界面中文乱码Qt 字体不支持中文或编码问题设置系统字体为微软雅黑代码文件保存为 UTF-8加载 ONNX 模型报错缺少 onnxruntimepip install onnxruntime-gpu或onnxruntime检测框太密误检多置信度阈值过低调高 conf 到 0.4~0.5或检查训练数据标注质量新增类别后旧模型无法推理类别数不匹配重新训练或增量训练确保 yaml 中 nc 和 names 一致results.png 没有生成训练提前中断或版本过旧检查runs/detect/目录确认训练完整结束8.2 数据集问题导致模型效果差模型效果不好时第一优先级不是改网络结构而是先检查数据集标注框是否紧贴缺陷边界。每类缺陷样本数是否足够建议每类至少 200 张。训练集和验证集图片来源是否重复是否有相似图片泄露。图片统一分辨率是否正常或存在大量空白背景。8.3 PySide6 部署到其他电脑开发环境跑通后如果要把应用发给没装 Python 的同事使用可以用 PyInstaller 打包pip install pyinstaller pyinstaller -D -w main.py注意-w表示不显示控制台窗口。如果模型文件较大可以将.pt或.onnx放到外部指定路径也可以放到打包目录内一起分发。9. 最佳实践与工程建议9.1 小样本场景下的训练策略工业场景经常碰到只有一两百张缺陷图的情况这时候不要盲目加大模型。优先用yolov8n.pt预训练权重微调同时开启更激进的数据增强。如果缺陷很小可以对图片做切片预处理把大图切块后训练推理时再拼接检测结果。也可以利用yolov8增量训练的特性先训练容易识别的缺陷类别再逐步加入难例。每一步都冻结前面层的参数避免灾难性遗忘。9.2 模型推理性能优化优先导出 TensorRT 或 ONNX 格式代替.pt直接推理。输入尺寸不要无脑拉高640 到 1280 之间需要根据实际缺陷大小做实验。批量推理时可以使用更高的 batch但桌面端实时交互建议单张推理并启用线程池。如果 CPU 部署可以使用 OpenVINO 导出格式推理速度明显提升。9.3 界面与推理线程分离PySide6 开发中耗时操作必须放到子线程执行。不要直接在button.clicked回调里调用模型预测否则 UI 会进入“无响应”状态。推荐使用QThread或QThreadPool QRunnable。另外摄像头实时检测场景下不要每帧都创建新线程应该使用常驻工作线程配合队列否则线程频繁创建销毁会带来额外开销。9.4 安全与生产环境注意事项在真实产线部署时必须注意以下几点模型上线前在测试环境用历史数据回放验证确认误检率和漏检率可接受。涉及模型更新时保留旧版本的备份支持快速回滚。系统不能直接控制产线剔除机构检测结果只能作为人工复检的参考或者经过严格安全联锁后再接入执行机构。记录每次检测的原始图片、结果坐标、置信度方便后续追溯和模型迭代。标注数据涉及客户产品图纸或内部零部件时做好数据脱敏和访问控制。9.5 代码可维护性建议模型路径、类别配置、阈值等参数不要硬编码在界面代码中建议使用配置文件。检测逻辑与界面逻辑严格分层方便以后把同样的模型接入 Web 服务或边缘设备。日志记录要包含图片名、检测时间、缺陷类型、坐标信息而不只是界面提示。为推理接口写单元测试例如单张正常图、纯色图、超大图、灰度图确保不崩溃。10. 总结与下一步学习建议这套基于 YOLOv8/YOLOv5 PySide6 的金属表面缺陷检测系统核心思路并不复杂训练阶段用 YOLO 系列完成缺陷目标检测部署阶段用 PySide6 搭建桌面交互界面。关键难点在于业务层面比如小缺陷的漏检、样本不均衡、推理速度与精度的平衡这些都不存在一劳永逸的参数需要针对具体产线反复迭代。下一步可以从这几个方向深入如果缺陷类别之间存在明显的纹理差异可以尝试给 YOLOv8 替换主干网络比如引入 ConvNeXt V2 等结构做改进实验。如果小目标缺陷漏检严重可以尝试在 YOLOv8 中添加多头注意力机制 MHSA增强特征表达能力。如果产品种类多、换型频繁可以考虑多模型并行或动态加载模型而不是一个大模型包打天下。如果需要 Web 化可以把检测模块封装成 FastAPI 服务PySide6 只做客户端这样多个工位可以共用一套推理服务。工业视觉项目里算法模型只是其中一环数据质量、界面体验、日志追溯、部署运维同样重要。建议在动手训练之前先花时间把产线的实际缺陷类型、光照环境、检测节拍摸清楚这些业务信息对最终系统效果的影响往往比换一个更大的网络结构还要明显。

相关新闻