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

焊缝缺陷检测毕设实战:YOLOv8环境搭建、数据集标注与模型训练全流程

简介面向计算机相关专业毕设与课程设计场景基于YOLOv8实现化工管道焊缝缺陷检测包含可视化界面、完整数据集与部署教程下载后按README说明即可运行。代码经测试通过可输出核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果与标签分布图适合答辩展示也便于在此基础上改进检测逻辑或扩展缺陷类型。资源包共97个文件以Python源码70个py、训练权重4个pt、配置文件与说明文档xml/txt为主另含界面图标和演示视频整体24.21MB。界面交互、模型训练、视频检测等模块一应俱全目录结构简洁便于按需查看。已有56人浏览学习适合初次接触目标检测的学生用于快速上手并理解YOLOv8训练与推理流程也可作为课程设计或毕业设计的完整参考。1. 焊缝缺陷检测为什么选YOLOv8这套毕设系统的三大件拆解化工管道在长期承压运行后焊缝是最容易出问题的部位而射线底片评定一直依赖检验人员肉眼读片。YOLOv8介入之后这件事就变成了一条可复现的流水线加载一份训练好的权重把底片或数字图像丢进去出来就是带类别标签和置信度的检测框。你说的这个系统本质上就是由“完整数据集 YOLOv8源码 可视化界面 部署教程”四块拼起来的适合机械、化工、计算机方向正在做毕设或课程设计的同学。我看了不少类似项目最容易被低估的不是训练而是数据整理和界面对接。数据决定模型上限界面决定演示效果训练反而只占整个工作量的三成左右。如果你手上拿到的这份源码包连部署教程都带了那你要做的不是改模型结构而是把环境跑通、把数据看明白、把界面的调用逻辑理顺然后换成自己的数据集重新训练一遍。这篇文章就按这个顺序来写。2. 环境搭建与首次运行把“简单部署”从口号变成能演示的界面2.1 CPU也能跑版本搭配方案先解决环境。YOLOv8不是独立框架它对应的是ultralytics这个Python包环境要求其实很宽松Python 3.8到3.10之间最稳PyTorch 2.0以上ultralytics装 8.x 版本即可。如果你的机器没有独立显卡也不用慌CPU能跑推理只是速度慢一些演示一张图完全够用。很多同学就是按“ubuntu20.04搭建yolov8环境cpu版本”的思路来做本地部署这套组合是经过大量验证的。我一般建议用conda先建一个干净环境避免把系统Python搞乱conda create -n weld_yolo python3.9 -y conda activate weld_yolo pip install ultralytics8.2.0 torch torchvision如果你有NVIDIA显卡先看驱动支持什么CUDA版本再装对应的PyTorch。CPU版则不需要关心CUDA直接pip install torch torchvision就会拉CPU版本。装完后用一行命令验证python -c from ultralytics import YOLO; print(YOLO(yolov8n.pt))能打印出模型对象说明环境没问题。注意yolov8n.pt是ultralytics自动下载的预训练权重首次运行需要联网下载慢的话可以手动把权重文件放进项目weights目录。2.2 目录结构与启动入口拿到项目包先别急着双击任何文件先看目录。典型结构是这样weld_defect_system/ ├── weights/ │ └── best.pt ├── datasets/ │ ├── images/ │ └── labels/ ├── main.py ├── requirements.txt └── 部署教程.mdweights/best.pt是训练好的模型main.py是可视化界面入口requirements.txt是依赖清单。先打开部署教程文档再对照requirements.txt装依赖顺序不要反。有些项目会用pip install -r requirements.txt一键装但要注意里面可能有opencv-python、PyQt5这类体积较大的包耐心等。界面启动一般是python main.py如果项目里没有main.py去找带“UI”“window”“gui”字样的脚本比如window.py或gui.py。启动后界面会弹出文件选择框选一张焊缝图像点击检测按钮左侧显示原图右侧显示带框的结果。这一步能跑通说明源码、权重、界面三块都是完整的。2.3 用最小推理脚本验证权重启动界面之前我建议先用命令行把权重跑一遍这样能快速定位问题是出在环境、权重还是界面上。新建一个test_infer.pyfrom ultralytics import YOLO model YOLO(weights/best.pt) results model.predict( sourcedemo.jpg, conf0.25, iou0.5, imgsz640, saveTrue, projectruns/detect, nameweld_test, ) print(results[0].boxes.cls) print(results[0].boxes.conf) print(results[0].boxes.xyxy)这段代码里的conf0.25是置信度阈值低于这个值的框会被丢弃调低会看到更多候选框但误检也会增多iou0.5是NMS去重的交并比阈值同一条缺陷的重叠框会被合并imgsz640是输入分辨率焊缝气孔这种小目标可以试着提到768。跑完后结果图保存在runs/detect/weld_test下。boxes.cls输出的是类别索引比如[0, 1]表示检测到了两个缺陷分别是第0类和第1类boxes.conf是置信度boxes.xyxy是左上角和右下角坐标。看到这行输出就可以放心打开界面了。3. 焊缝缺陷数据集与YOLO标注六类缺陷的标签怎么做才算合格3.1 六类缺陷长什么样难在哪化工管道焊缝射线底片里最常见的缺陷类别有六种气孔、夹渣、未熔合、未焊透、咬边、裂纹。这六类在底片上的形态差异很大也是你在标注阶段要反复区分的对象气孔圆形或椭圆形暗斑边缘清晰通常成串或成群出现是最好标的一类。夹渣不规则块状暗区边界模糊常藏在焊缝内部标的时候很容易画大。未熔合沿坡口方向的细长直线暗影宽度很窄需要放大图片才能看清。未焊透焊缝根部一条连续或断续的暗线比夹渣更规则。咬边焊缝边缘母材上的凹陷呈条状紧贴焊缝边界。裂纹最棘手的一类细长、曲折、末端尖锐长宽比经常超过10:1。难点很清楚气孔和夹渣是大目标裂纹和未熔合是小目标。如果你拿到的数据集是从公开的X射线焊缝数据集比如GDXray这类里整理的那类别分布基本就是按上面六类给的如果是自己拍的底片标注前一定先做类别确认别把“夹渣”和“未熔合”混在一起后面训练的模型会一直懵。3.2 labelme标注与YOLO格式转换标注阶段用labelme还是labelImg都行但要注意一点labelme保存的是JSON文件不能直接给YOLOv8训练必须转成YOLO格式的txt。YOLO的标签格式是每行五个数class_id x_center y_center width height其中坐标全部是归一化比例不是像素值。比如一张1000×800的图缺陷中心在(500, 400)宽200、高100那么这一行就是0 0.5 0.5 0.2 0.125。类别的顺序由你的类别清单决定不是写死的气孔就是0。转换完成后写一个校验脚本检查所有标签这步能省下训练时的排查时间import os label_dir datasets/weld/labels/train class_names [porosity, slag, lack_of_fusion, incomplete_penetration, undercut, crack] for fname in os.listdir(label_dir): if not fname.endswith(.txt): continue path os.path.join(label_dir, fname) with open(path, encodingutf-8) as f: lines f.read().strip().splitlines() for i, line in enumerate(lines): parts line.split() if len(parts) ! 5: print(f{fname} 第{i1}行: 必须5个数, 实际{len(parts)}个) continue cls int(parts[0]) x, y, w, h map(float, parts[1:]) if not (0 cls len(class_names)): print(f{fname} 第{i1}行: 类别索引越界 - {cls}) if not (0 x 1 and 0 y 1 and 0 w 1 and 0 h 1): print(f{fname} 第{i1}行: 归一化坐标越界 - {line})这段脚本的重点是检查出三类问题长度不对、类别越界、坐标越界。坐标越界最常见的来源是标注工具在图片边缘画框时或转换脚本四舍五入出错坐标计算成了负数或大于1的值。越界的标签不会被YOLO直接报错但会产生质量很差的候选框手动排查极麻烦。3.3 数据集划分与重复检查数据准备好后按train / val划分常见比例是85/15或80/20。我习惯用脚本随机划分同时把图片和标签一起拷过去import random import os from shutil import copy2 random.seed(42) images [f for f in os.listdir(images_all) if f.endswith((.jpg, .png, .jpeg))] random.shuffle(images) split int(len(images) * 0.85) train_list images[:split] val_list images[split:] for split_name, file_list in [(train, train_list), (val, val_list)]: os.makedirs(fdatasets/weld/images/{split_name}, exist_okTrue) os.makedirs(fdatasets/weld/labels/{split_name}, exist_okTrue) for file_name in file_list: copy2(os.path.join(images_all, file_name), os.path.join(datasets/weld/images, split_name, file_name)) label_name os.path.splitext(file_name)[0] .txt src_label os.path.join(labels_all, label_name) if os.path.exists(src_label): copy2(src_label, os.path.join(datasets/weld/labels, split_name, label_name)) else: print(f警告: {file_name} 缺少标签文件)跑完脚本后检查两个事第一labels/val里不能有和images/train同名的文件防止数据泄露第二检查是否有空标签文件即txt文件大小为0这类文件对应的图像会被YOLO忽略导致实际参与训练的图像数量比预期少。检查空标签用一行find命令find datasets/weld/labels/train -name *.txt -size 0如果结果不为空要么重新标注要么把这些图片从数据集里移出去。4. 训练自己的焊缝模型五个必调参数与loss曲线判读4.1 先写对data.yamlYOLOv8训练时需要一个数据集配置文件这是新手最容易写错的地方。在项目根目录建weld.yamlpath: /home/yourname/weld_defect_system/datasets/weld train: images/train val: images/val nc: 6 names: 0: porosity 1: slag 2: lack_of_fusion 3: incomplete_penetration 4: undercut 5: crackpath必须写绝对路径YOLOv8对相对路径的解析经常出问题train和val是相对path的路径不能加前缀/nc是类别数这里6names的索引必须和标签txt里的class_id一一对应。很多“No labels found”的报错最后查下来都是path少了一层目录。4.2 训练命令与参数表数据集就绪后训练命令长这样yolo train modelyolov8n.pt dataweld.yaml epochs120 batch16 imgsz640 workers4 device0yolov8n.pt是COCO预训练权重在这个基础上做迁移学习收敛比从零训练快得多。如果你有GPU但显存只有6G左右把batch降到8没有GPU就把devicecpu加上但训练时间会拉长到几小时甚至十几小时建议先跑少量轮次验证流程。几个必调参数按下面这张表来参数建议值说明epochs100-150焊接缺陷特征不算复杂120轮左右足够收敛batch8-16受显存约束OOM就减半imgsz640-768气孔、裂纹占比小768能明显提升小目标召回lr00.005-0.01预训练权重迁移时学习率过大容易把已有特征冲掉patience30验证集指标连续30轮不提升就早停workers4-8数据加载线程数CPU不够就调低训练过程中终端会实时打印每个epoch的loss和mAP不用盯着看但要注意有没有出现nan。lr0设了0.01还出现loss爆炸通常是数据里混入了异常标签回到第3章跑一遍校验脚本。4.3 用loss曲线和mAP判断训练状态训练完成后所有指标都落在runs/detect/train/目录下。不要只看最后的mAP要把训练过程拉成曲线看。YOLOv8训练时自动生成results.csv用脚本画出来import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(runs/detect/train/results.csv) plt.figure(figsize(10, 4)) plt.plot(df[epoch], df[train/box_loss], labeltrain_box_loss) plt.plot(df[epoch], df[val/box_loss], labelval_box_loss) plt.xlabel(epoch) plt.ylabel(loss) plt.legend() plt.grid(True) plt.savefig(loss_curve.png)正常的收敛曲线是训练和验证的box_loss同步下降并趋于平缓。如果训练loss一直降但验证loss在后半段反弹说明过拟合常见对策是减小lr0、增大数据增强的scale参数或者补充更多标注样本。如果两条loss都在高位震荡不下降先查标签是否有错再查学习率是否设置合理。模型权重会保存两份best.pt是验证集mAP最高的版本last.pt是最后一轮的版本。部署时一律用best.pt不要觉得训练轮数越多权重越好。我自己的习惯是只保留best.pt然后拿它对一张训练集之外的底片做一次推理确认检测框落在真实缺陷位置上再谈部署。5. 部署踩坑与排查五个高频问题让项目翻车在答辩前5.1 训练时反复报“No labels found”现象yolo train启动后很快报错提示Dataset weld.yaml error、labels not found或No labels found in ...训练直接中止。原因大概率是三件事之一——weld.yaml里的path写成了相对路径images/train和labels/train路径下对应文件不匹配图片后缀不是.jpg/.png导致YOLO没扫描到。解决先用ls datasets/weld/images/train | head -3看一下图片文件确实存在再确认find datasets/weld/labels/train -name *.txt | wc -l的txt数量和图片数量一致最后把path改成绝对路径后重新跑一次。5.2 界面点“开始检测”直接卡死或白屏现象界面能打开但一点检测按钮就无响应Windows里显示“未响应”过几秒甚至永久卡住。原因main.py里把model.predict()直接放在了按钮点击回调里推理阻塞了Qt的事件循环。这是新手写界面最常犯的错误严格说不是YOLO的问题是线程模型的问题。解决把推理放到QThread里执行或用线程池提交任务。如果不想改线程结构至少在界面启动前先加载best.pt不要在点击时才YOLO(...)模型加载也是耗时操作。改了线程后推理过程中界面还能正常拖动窗口就是一个合格的修复。5.3 气孔、裂纹漏检严重mAP卡在低位现象大目标夹渣能检出小目标气孔和裂纹几乎全部漏掉mAP50一直上不去。原因两个主因第一是imgsz640对直径只有十几个像素的气孔来说太小第二是置信度阈值设太高比如conf0.5小目标本来置信度就低直接被过滤了。解决训练时把imgsz768推理时降到conf0.15-0.2观察候选框数量。如果训练集里裂纹样本太少比如不足150个实例先做数据扩增——水平翻转、小角度旋转、亮度抖动对细长目标有效。裂纹这类缺陷样本数量压倒算法技巧。5.4 CPU训练慢到让人想直接放弃现象一台只有CPU的笔记本跑yolov8mimgsz640一个epoch要好几分钟120轮根本没法等。原因模型规模选大了。yolov8m的参数量是yolov8n的三倍多倍数级CPU推理本来就慢训练更是放大十倍。解决训练用yolov8n.ptimgsz640batch4先把流程跑通最后做演示时再考虑换大的模型权重。如果真的需要高性能权重本地用小模型完成开发验证用云GPU跑一轮完整训练再把best.pt下载回来本地部署这是个成熟的低成本路线。5.5 中文路径导致图像读不出来、文字乱码现象图像放在D:\实验数据\底片\001.jpg这种带中文路径的位置界面检测不出结果或者终端输出一堆???乱码界面上的标签中文显示成方块。原因OpenCV 的imread不支持中文路径会静默返回空图matplotlib 默认字体不含中文字形。解决训练推理都不走中文路径项目目录统一用英文如果必须读用np.fromfile加cv2.imdecode代替imreadimport cv2 import numpy as np data np.fromfile(实验数据/底片/001.jpg, dtypenp.uint8) img cv2.imdecode(data, cv2.IMREAD_COLOR)界面中文乱码则是在matplotlib里手动指定中文字体比如plt.rcParams[font.sans-serif] [SimHei]。这个问题在答辩演示时特别容易翻车提前检查演示机的中文语言包。6. 进阶验证导出ONNX用未参与训练的图像做一次读片测试训练完模型下一步不只是演示而是做一个更接近工程实践的验证把best.pt导出成ONNX再用非训练数据检验泛化能力。ONNX的好处是摆脱PyTorch依赖推理速度更快也方便以后接C或嵌入式端。导出命令很简单yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640 simplifyTrue导出的best.onnx可以直接用ultralytics的接口加载省去手写预处理和后处理的麻烦from ultralytics import YOLO model YOLO(runs/detect/train/weights/best.onnx) result model.predict(unseen_001.jpg, conf0.25, imgsz640)[0] print(result.boxes.cls.tolist()) print(result.boxes.conf.tolist())我的验收标准是从未参与训练和验证的图像里再挑出20张六类缺陷至少能检出四类且每张图的误报控制在两个以内。如果漏检集中在某一类就针对那类补数据重新训练如果误报多就把置信度阈值上调。用这个指标代替单看mAP会更贴近答辩时“现场演示一张没见过的图”的场景。这几年在毕设辅导里我提醒最多的一句话是YOLOv8本身是稳定可靠的项目翻车基本都是环境版本冲突、数据标签混乱、界面线程阻塞这三类问题花在排查上的时间远大于写代码的时间。每次拿到新的数据集先写一个校验脚本把标签全查一遍再开始训练。希望这套操作思路帮你在自己的焊缝缺陷检测项目里少走一段弯路。本文还有配套的精品资源点击获取
分享:

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

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