yolo26快速实战,plc与yolo 结合工业质检基础部份
PLC 到机器视觉编程:新手快速实战(YOLO26 + Ultralytics)
适合人群:做过 PLC/工控,想切入机器视觉的工程师;或刚入门深度学习的新手。
学完你能做到:安装环境 → 跑通官方小数据集 → 完整训练一个自己的目标检测模型 → 看懂训练指标 → 掌握前后处理原理 → 导出 ONNX 并部署到其他平台。
工具链:Python + Ultralytics(YOLO26)+ ONNX Runtime + Netron
目录
- 一、机器视觉能做什么:适用场景
- 二、YOLO 历史版本与差异(选型不迷路)
- 三、环境安装
- 四、快速体验:加载预训练模型 + COCO8 小数据集
- 五、完整训练一个识别模型
- 六、深入:训练监控与关键指标解读
- 七、深入:模型评估与结果分析
- 八、深入:前处理(Letterbox 与 NCHW)
- 九、深入:后处理(过滤、NMS 与坐标还原)
- 十、模型导出与可视化查看
- 十一、发布到其他推理平台
- 结语
一、机器视觉能做什么:适用场景
如果你熟悉 PLC,可以把机器视觉理解成产线上的"眼睛":PLC 负责逻辑控制,视觉负责"看"——而 YOLO 是目前工业界最常用的"眼睛"之一,因为它快(毫秒级)且准。
1.1 六大视觉任务
|
任务 |
英文 |
干什么 |
典型应用 |
|---|---|---|---|
|
目标检测 |
Detection |
识别图像中物体的类别和位置(画框) |
最基础、应用最广 |
|
实例分割 |
Segmentation |
在检测基础上,分割出物体的像素级轮廓 |
医学影像、工业质检 |
|
姿态估计 |
Pose Estimation |
识别人体关键点(关节等) |
动作分析、体感交互 |
|
图像分类 |
Classification |
判断整张图属于哪一类 |
产品分级、缺陷粗筛 |
|
旋转框检测 |
OBB |
检测带旋转角度的目标 |
航拍船舶、斜排零件 |
|
多目标跟踪 |
Tracking |
在视频中持续追踪多个目标 |
车流统计、产线计数 |
由易到难的关系:
分类(图像是啥?)→ 检测(东西在哪?)→ 分割(轮廓多精确?)
→ 姿态(关节在哪?)→ OBB(带角度怎么办?)→ 跟踪(视频里怎么追?)
1.2 标杆案例:工业质检
以长三角某电子制造基地为例,引入 YOLO 后实现 AI 全自动检测,替代近百名质检员:
|
指标 |
效果 |
|---|---|
|
检测速度 |
80 毫秒/板(整板 PCB) |
|
检测准确率 |
99.5% |
|
投资回报周期 |
不到 8 个月收回成本 |
为什么工业质检是视觉落地最成熟的场景?
- 场景封闭:光照、背景固定,图像质量稳定,模型泛化压力小;
- 缺陷标准明确:合格/不合格规则清晰,标注目标明确;
- 实时性要求高:产线不停,需要毫秒级响应——正是 YOLO 的强项;
- 人力替代价值大:质检是重复性劳动,易疲劳误判,AI 可 24/7 工作("熄灯工厂")。
二、YOLO 历史版本与差异(选型不迷路)
YOLO(You Only Look Once,你只看一次)的核心思想:把检测当回归问题,一次前向传播就出结果,因此天生快。
|
版本 |
发布 |
主要贡献 / 特点 |
|---|---|---|
|
YOLO v1~v3 |
2016~2018 |
Joseph Redmon 原创,Darknet 框架(C语言)。v3 引入多尺度预测,成为经典 |
|
YOLO v4 |
2020 |
Alexey Bochkovskiy 接棒,仍基于 Darknet,引入 CSP、Mosaic 增强等技巧,"平价显卡也能练" |
|
YOLO v5 |
2020 |
Ultralytics 用 PyTorch 重写,工程化极好(pip 安装、三行推理),引爆工业界 |
|
YOLO v6 / v7 |
2022 |
美团 v6 面向工业部署;v7 提出 E-ELAN,训练技巧丰富 |
|
YOLO v8 |
2023 |
Ultralytics 革命性版本:锚框-free(Anchor-Free)、统一支持检测/分割/姿态/分类,至今应用最广 |
|
YOLO v9 / v10 |
2024 |
v9 提出 GELAN 架构;v10 来自清华,主打免 NMS(端到端,后处理极简) |
|
YOLO v11 / v12 |
2024~2025 |
v11 是 v8 的全面加强版(精度更高、参数更少);v12 引入注意力机制 |
|
YOLO26 |
2026 |
Ultralytics 新一代命名(跳版对齐年份),端到端导出(NMS 内置在模型里),小模型 yolo26n 速度精度再提升 |
选型建议(新手直接抄)
- 学习/新项目:直接用最新稳定版 YOLO26(本文所用),旧教程的 v8 写法 95% 兼容;
- 模型大小:先看
n(nano,最快)→ 不够准再试s→m; - 一句话:版本之间原理相通,API 基本一致,学会一个全会。
三、环境安装
# 安装 ultralytics(自动带上 PyTorch 等依赖)
pip install ultralytics
# 国内加速
pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple
验证安装:
import ultralytics
print(ultralytics.__version__) # 能打印版本号即成功
GPU 用户:安装前先确认 NVIDIA 驱动 + CUDA,PyTorch 会按需自动装 GPU 版;没有显卡也能用 CPU 跑通全流程,只是慢。
3.1 查看与调整设置
from ultralytics import settings
settings # 显示当前设置(数据集目录、运行目录等)
settings['runs_dir'] = './my_runs' # 自定义训练输出目录
settings.reset() # 恢复默认
常用配置项:
|
配置项 |
作用 |
|---|---|
|
|
数据集默认存放路径 |
|
|
训练结果输出目录 |
|
|
权重默认存放目录 |
四、快速体验:加载预训练模型 + COCO8 小数据集
先跑通,再深入。 Ultralytics 内置了迷你数据集 COCO8(8 张图),专门用于流程演示。
4.1 三行代码完成第一次推理
from ultralytics import YOLO
model = YOLO('yolo26n.pt') # 首次运行自动下载权重(n=nano 最轻量)
results = model('image.jpg') # 传入任意图片路径
模型规格对照(yolo26 + 后缀):
|
文件 |
规格 |
特点 |
|---|---|---|
|
|
nano |
最轻最快,入门首选 |
|
|
small |
速度精度平衡 |
|
|
大模型 |
精度更高,显存要求更高 |
4.2 常用推理方式
results = model('image.jpg', save=True) # 保存标注后的图片
results = model('video.mp4', save=True) # 视频
results = model(0, show=True) # 摄像头实时检测
# 查看结果细节
for r in results:
print(r.boxes.cls) # 类别编号
print(r.boxes.conf) # 置信度
print(r.boxes.xyxy) # 框坐标 (x1,y1,x2,y2)
五、完整训练一个识别模型
5.1 准备数据集:目录结构
dataset/
├── images/
│ ├── train/ # 训练集图片(约80%)
│ └── val/ # 验证集图片(约20%)
└── labels/
├── train/ # 训练集标签(与图片同名 .txt)
└── val/ # 验证集标签
关键规则:
images/train/xxx.jpg↔labels/train/xxx.txt(文件名一致,仅扩展名不同);- 标签为 YOLO 格式,每行一个目标:
<class_id> <x_center> <y_center> <width> <height>
- 后 4 个值是归一化的(0~1,占图片宽高的比例),不是像素;
- 无目标的图片对应一个空 txt,不能不建。
5.2 配置文件 data.yaml
path: ./dataset # 数据集根目录
train: images/train # 训练集(相对 path)
val: images/val # 验证集
test: # 测试集,可选
names: # 类别编号 → 名称(编号从0开始)
0: person
1: bicycle
5.3 训练核心代码
from ultralytics import YOLO
model = YOLO('yolo26n.pt') # 加载预训练权重(迁移学习,效果更好)
results = model.train(
data='data.yaml', # 数据集配置(必填)
epochs=100, # 训练轮数
imgsz=640, # 输入尺寸
batch=16, # 批次大小(爆显存就调小)
device=0, # GPU编号;无显卡写 'cpu'
)
5.4 训练后得到什么
runs/detect/train/
├── weights/best.pt # ★ 验证集 mAP 最高的权重(部署就用它)
├── weights/last.pt # 最后一轮权重(断点续训用)
├── results.png # 损失与指标曲线
└── confusion_matrix.png # 混淆矩阵
六、深入:训练监控与关键指标解读
6.1 四大指标
|
指标 |
含义 |
标准 |
|---|---|---|
|
Loss(损失值) |
预测与真实答案的"差距" |
持续下降并趋稳才好 |
|
Precision(精确率) |
模型说"是目标"的里面,真目标占多少 → 准不准 |
越高误报越少 |
|
Recall(召回率) |
真实目标里,被找出来的占多少 → 全不全 |
越高漏检越少 |
|
mAP |
综合 P 和 R 的总评分,核心指标 |
越高越好,入门看 mAP@0.5 |
捕鱼类比:Precision = 网里真鱼的比例;Recall = 捞出池塘里鱼的比例。
6.2 训练中这些指标"长什么样"
每个 epoch 终端会输出:
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
12/100 3.4G 0.512 0.301 0.455 48 640
每轮验证后输出:
Class Images Instances Box(P R mAP50 mAP50-95)
all 200 480 0.872 0.815 0.856 0.623
box_loss / cls_loss / dfl_loss:框位置、分类、分布三部分损失;P / R:精确率、召回率;mAP50:IoU=0.5 时的 mAP(最常用);mAP50-95:更严格标准。
6.3 训练后:results.png 曲线判断
|
现象 |
结论 |
|---|---|
|
train/val loss 都降、最后平稳 |
✅ 正常 |
|
train loss 降、val loss 后期上升 |
⚠️ 过拟合(加数据/加增强/早停) |
|
loss 全程不降 |
❌ 查 data.yaml 路径、标签格式、学习率 |
6.4 用代码读取指标
# 训练返回对象直接取
print(results.results_dict['metrics/mAP50(B)'])
print(results.results_dict['metrics/precision(B)'])
# 或读 CSV 画自定义曲线(适合对比实验)
import pandas as pd
df = pd.read_csv('runs/detect/train/results.csv')
七、深入:模型评估与结果分析
7.1 独立评估
model = YOLO('runs/detect/train/weights/best.pt')
metrics = model.val()
print(metrics.box.map50) # mAP@0.5
print(metrics.box.map) # mAP@0.5-95
print(metrics.box.mp) # Precision
print(metrics.box.mr) # Recall
7.2 混淆矩阵(confusion_matrix.png)怎么看
- 行 = 真实类别,列 = 预测类别,对角线 = 预测正确(越深越好);
background列有数字 → 漏检(真目标没检出来);background行有数字 → 误检(把背景当目标);- 两类互有数字 → 类别混淆(外观相似/样本不足)。
7.3 评估三件套
model.val()拿数字 →confusion_matrix.png找错因 →val_batch0_pred.jpg肉眼验货,交付永远用best.pt。
八、深入:前处理(Letterbox 与 NCHW)
为什么要自己写前处理? 因为部署到别的平台(C++/嵌入式/手机)时没有 model('img.jpg') 帮你做,必须自己实现一模一样的流程。
8.1 完整前处理代码
import cv2
import numpy as np
input_image = 'image.jpg'
new_shape = (640, 640)
# ① 读图 + 记录原始尺寸(坐标还原要用!)
img = cv2.imread(input_image)
img_height, img_width = img.shape[:2]
# ② BGR → RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# ③ Letterbox:等比缩放,保持长宽比
shape = img.shape[:2] # (H, W)
r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
new_unpad = round(shape[1] * r), round(shape[0] * r) # 缩放后 (W, H)
dw, dh = (new_shape[1] - new_unpad[0]) / 2, (new_shape[0] - new_unpad[1]) / 2
if shape[::-1] != new_unpad: # 尺寸变了才缩放
img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
# ④ 填充灰边(114 是 YOLO 标准填充色),凑成 640×640
top, bottom = round(dh - 0.1), round(dh + 0.1)
left, right = round(dw - 0.1), round(dw + 0.1)
img = cv2.copyMakeBorder(img, top, bottom, left, right,
cv2.BORDER_CONSTANT, value=(114, 114, 114))
# ⑤ 归一化 0~255 → 0~1
image_data = np.array(img) / 255.0
# ⑥ HWC → CHW(通道提前)
image_data = np.transpose(image_data, (2, 0, 1))
# ⑦ 加批次维度 + float32:(C,H,W) → (1,C,H,W)
image_data = image_data[None].astype(np.float32)
8.2 为什么用 Letterbox 而不是直接拉伸?
直接拉伸会让目标变形(人变胖、车变扁),影响精度。Letterbox 流程:
原图 (1080×1920, BGR)
│ 转RGB + 等比缩放
▼
缩放图 (360×640)
│ 左右各补 140 像素灰边
▼
模型输入 (640×640) → /255 → CHW → (1,3,640,640) float32
8.3 维度变换必考知识点
(H, W, 3) HWC # OpenCV 读入,BGR
│ 转RGB/缩放/填充
(640, 640, 3)
│ /255.0
归一化 0~1
│ transpose(2,0,1)
(3, 640, 640) CHW
│ [None] + float32
(1, 3, 640, 640) NCHW float32 ← 喂给模型的最终形态
九、深入:后处理(过滤、NMS 与坐标还原)
9.1 置信度过滤
conf_thres = 0.5 # 置信度阈值
max_det = 100 # 最多保留框数
prediction = outputs[0]
output = [pred[pred[:, 4] > conf_thres][:max_det] for pred in prediction]
- 模型原始输出约 24000 个候选框(YOLO26),每行
[x, y, w, h, 置信度, 各类别分数...]; pred[:, 4] > conf_thres:布尔索引,先砍掉没把握的;[:max_det]:双保险,控制上限。
阈值调参经验:
|
conf_thres |
效果 |
场景 |
|---|---|---|
|
0.7~0.9 |
框少而准,易漏检 |
误报代价高(质检误判) |
|
0.3~0.5 |
框多而全,误报增 |
漏检代价高(安防) |
|
0.5 |
平衡 |
默认起点 |
9.2 关于 NMS(非极大值抑制)
同一个目标常被框中多次,NMS 负责去重:保留置信度最高的框,删除与它重叠度(IoU)超过阈值的其他框。
好消息:本文的 ONNX 是端到端导出的——从 Netron 图可见 TopK/Gather 已内置在模型里,相当于模型自己做了大半 NMS,Python 侧可以省略。
但如果你用老版本导出的 ONNX 或原始 PyTorch 权重,必须自己写 NMS(cv2.dnn.NMSBoxes或 torchvision 的nms),否则满屏重叠框。
9.3 坐标还原(重点易错)
推理得到的坐标是 640×640 填充图上的,要映射回原图,两步都不能少:
x_original = (x_640 - left) / r # 先减填充,再除以缩放比
y_original = (y_640 - top) / r
⚠️ 只减填充不除 r,在非正方形图片上框会整体偏移/缩放错位。
9.4 结果可视化(含中文标签)
from PIL import Image, ImageDraw, ImageFont
img = Image.open('image.jpg')
imgw, imgh = img.size
font_text = ImageFont.truetype("chinese_cht.ttf", 30, encoding="utf-8") # PIL默认字体不支持中文!
draw = ImageDraw.Draw(img)
for one_label in output[0]:
xmin, ymin, xmax, ymax, score, label_id = one_label.tolist()
label = cfg['names'][int(label_id)]
xmin = int((xmin - left) / r)
ymin = int((ymin - top) / r)
xmax = int((xmax - left) / r)
ymax = int((ymax - top) / r)
draw.rectangle((xmin, ymin, xmax, ymax), outline='red', width=3)
draw.text([xmin, ymin - 30], f'{label} {score:.2f}',
fill='white', font=font_text)
img.show()
💡 Windows 可换系统字体:C:/Windows/Fonts/msyh.ttc(微软雅黑)。
十、模型导出与可视化查看
10.1 导出 ONNX
model = YOLO('runs/detect/train/weights/best.pt')
path = model.export(format='onnx') # 输出 runs/detect/train/weights/best.onnx
常用导出参数:
model.export(format='onnx', imgsz=640, half=True, simplify=True)
# half=True FP16半精度:更小更快(需硬件支持)
# simplify 简化结构,兼容性更好
10.2 用 Netron 查看模型结构
打开 netron.app(网页版,免安装),拖入 best.onnx 即可看到计算图。
从图里可以直接读出:
- 输入:
1×3×640×640(NCHW,照此写前处理); - 输出:
1×300×4(框坐标)+1×300(类别/分数)——照此写后处理; - 内置后处理:TopK、Gather 等节点说明 NMS 已融入模型。
Netron 四大用途:核对输入输出 shape、排查导出错误、学习网络结构、给部署文档配图。
10.3 用 ONNX 模型推理
# 方式一:Ultralytics 直接加载(最省事)
onnx_model = YOLO('best.onnx')
results = onnx_model('image.jpg')
# 方式二:onnxruntime 原生推理(部署到无 ultralytics 的环境)
import onnxruntime as ort
import numpy as np
available = ort.get_available_providers()
providers = [p for p in ("CUDAExecutionProvider", "CPUExecutionProvider") if p in available]
session = ort.InferenceSession('best.onnx', providers=providers or available)
input_name = session.get_inputs()[0].name
outputs = session.run(None, {input_name: image_data}) # image_data 是前处理产物
十一、发布到其他推理平台
模型和推理引擎是两回事:模型是"大脑",推理引擎是"发动机",不同平台有不同的最优发动机。导出前先问:目标设备是什么?
|
目标平台 |
推理引擎 |
导出格式 |
|---|---|---|
|
服务器/PC(NVIDIA GPU) |
TensorRT / ONNX Runtime |
|
|
服务器/PC(Intel CPU) |
OpenVINO |
|
|
安卓手机 |
NCNN / TFLite |
|
|
苹果手机 |
CoreML |
|
|
树莓派/嵌入式 |
ONNX Runtime / NCNN |
|
对应导出代码:
model.export(format='engine') # NVIDIA TensorRT,速度最快
model.export(format='ncnn') # 安卓手机常用(腾讯NCNN,纯C++无依赖)
model.export(format='coreml') # 苹果设备
典型工业落地架构(PLC 视角)
相机拍照 → 工控机(GPU)跑 ONNX/TensorRT 推理 → 检测结果(OK/NG + 坐标)
→ 通过 TCP/Modbus/IO 信号发给 PLC → PLC 控制剔除/报警/分拣
这就是"PLC + 机器视觉"的典型分工:视觉负责判断,PLC 负责执行。
结语
回顾全文链路:
适用场景认知 → YOLO版本选型 → 安装 → 预训练模型快速体验
→ 数据集准备 → 训练 → 指标监控 → 评估分析
→ 前处理 → 后处理 → 导出ONNX → Netron查看 → 多平台部署
入门路线建议:
- 第一周:跑通第三~五章,用 COCO8 或自己的小数据集完成第一次训练;
- 第二周:读懂第六~九章,把前后处理代码手敲一遍(这是面试和部署的真功夫);
- 第三周:完成导出部署,尝试把模型跑在目标平台上,打通与 PLC 的通信闭环。
机器视觉不难,难的是动手。祝你在工控智能化的浪潮里,早日让自己的产线"睁开眼睛"。
浙公网安备 33010602011771号