《------往期经典推荐------》
二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】,持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~
《------正文------》
目录
基本功能演示
【CV综合实战】基于深度学习的工业压力表智能检测与读数系统【python源码+Pyqt5界面+数据集+训练代码】
摘要:在工业环境中,压力表作为关键的监控设备,用于实时监测各种系统和流程中的压力变化,对确保生产安全与效率至关重要。本文基于
YOLO11的深度学习框架
,通过783
张实际场景中拍摄的工业压力表
相关图片,训练了可进行压力表
目标检测的模型,然后用Unet网络,通过414张分图片
训练压力表指针与刻度分割模型,对检测出的压力表指针与刻度进行分割,然后通过OpenCV进行后处理的读数读取。最终基于以上内容制作了一款带UI界面的工业压力表智能检测与读数系统
,更便于实际应用。该系统是基于python
与PyQT5
开发的,支持图片
、视频
以及摄像头
进行压力表数据读取,并保存检测结果
。本文提供了完整的Python代码和使用教程,给感兴趣的小伙伴参考学习,完整的代码资源文件获取方式见文末。
引言
该系列文章主要介绍一个《基于深度学习的工业压力表智能检测与读数系统》
的制作流程:包含了项目所有源码与模型训练数据集、训练代码与训练结果等内容
。最终实现效果如下:
该系统制作主要包括以下几步:
- 压力表目标检测模型的训练,
该项目使用的是YOLO11
; - 压力表指针与刻度分割模型的训练,
该项目使用的是Unet
; - OpenCV对分割结果进行后处理,并读取压力表读数;
- 系统软件界面的制作。
上一篇文章《【CV综合实战】基于深度学习的工业压力表智能检测与读数系统【1】压力表位置检测》实现了第一步:压力表的位置检测。
这篇文章介绍第二步,通过训练分割模型对检测出的压力表指针与刻度进行分割。 分割效果示例如下:
分割检测模型训练基本流程
本文介绍的第一步中,目标检测模型的训练流程如下:
搜集与整理数据集:
搜集整理实际场景中工业压力表
的相关数据图片,并进行压力表指针与刻度数据标注,为模型训练提供训练数据集;训练模型:
基于整理的数据集训练Unet
分割模型,实现压力表中指针与刻度分割,为后续读取压力表读数做准备;模型性能评估:对训练出的模型在验证集上进行了充分的结果评估和对比分析
,主要目的是为了揭示模型在关键指标(如Precision、Recall、mPA和mIOU等指标)上的表现情况
。
Unet模型简介
🔍 一、模型概要
U-Net是一种专为图像分割设计的卷积神经网络,由Olaf Ronneberger于2015年首次提出。其名称源于独特的U型对称结构,最初用于生物医学图像分割(如细胞、器官分割),后扩展至遥感、自动驾驶等领域。核心优势在于:
- 小样本高效性:在有限数据下表现优异,适合医学影像等标注成本高的场景;
- 精准边界分割:通过跳跃连接保留空间细节,实现像素级分类。
⚙️ 二、核心原理
1. 编码器-解码器结构
- 编码器(下采样路径):
- 由卷积层(Conv 3×3 + ReLU)和最大池化层(MaxPool 2×2)堆叠组成,逐步压缩图像尺寸(如572×572→32×32),提取高层语义特征。
- 每层通道数翻倍(64→128→256→512),增强特征抽象能力。
- 解码器(上采样路径):
- 通过转置卷积(Transposed Conv 2×2)逐步恢复分辨率,结合跳跃连接融合编码器的低级特征,提升定位精度。
2. 跳跃连接(Skip Connections)
- 作用:将编码器各层的特征图与解码器对应层拼接(Concatenate),解决下采样中的细节丢失问题。
- 优势:
- 多尺度特征融合:低层空间信息(边缘、纹理)与高层语义信息互补;
- 缓解梯度消失:加速训练收敛。
3. 损失函数与优化
- 损失函数:加权交叉熵损失(Weighted Cross-Entropy),对相邻目标边界赋予更高权重(如细胞间距<5像素)。
- 优化算法:带动量的随机梯度下降(SGD,动量=0.99),采用He初始化权重。
三、架构解析
1. 输入输出设计
- 输入:原始图像(如572×572×1灰度图),无填充(no padding)导致输出尺寸缩小。
- 输出:分割掩码(388×388×2),通过1×1卷积映射至类别通道(如背景/前景)。
2. 关键组件
组件 | 操作 | 作用 |
---|---|---|
双卷积层 | 2×[Conv 3×3 → ReLU] | 基础特征提取 |
下采样 | MaxPool 2×2 | 压缩空间尺寸,增加通道数 |
上采样 | Transposed Conv 2×2 → 特征拼接 → 双卷积层 | 恢复分辨率,融合多级特征 |
跳跃连接 | 裁剪编码器特征图与解码器拼接 | 保留细节信息 |
💡 现代改进:
- 添加批归一化(BN层)和填充(Padding)保持输入输出尺寸一致;
- 采用双线性插值替代转置卷积减少锯齿效应。
四、工作流程
- 数据预处理:标准化像素值、随机弹性变形增强数据鲁棒性;
- 特征提取:编码器逐层下采样,生成多层次特征图;
- 特征重建:解码器上采样并拼接跳跃特征,逐步恢复分辨率;
- 分割预测:末端1×1卷积输出像素类别概率,应用Softmax生成分割图。
模型训练、评估与推理
本项目使用的是Unet
模型进行分割模型训练,训练完成后对模型在验证集上的表现进行全面的性能评估及对比分析。总体流程包括:数据集准备、模型训练、模型评估。
1. 数据集准备与训练
通过网络上搜集关于实际场景中工业压力表
的相关图片,并使用Labelme标注工具对每张图片进行分割标注,分2个类别
:['指针','刻度']
。
最终数据集一共包含414张图片
,其中训练集包含374张图片
,验证集包含40张图片
。
部分图像及标注如下图所示:
注意:由于mask的像素点类别是用0,1,2序号表示的【以满足模型训练数据要求】,所以标注的图片看起来是黑色的。
2.模型训练
准备好数据集后,将图片数据以如下格式放置在项目目录中。在项目目录中新建datasets
目录,同时将检测的图片分为训练集与验证集放入Data
目录下。
数据准备完成后,通过调用train.py
文件进行模型训练,核心代码如下:
#coding:utf-8
# 加载数据
train_loader = torch.utils.data.DataLoader(train_dataset,
batch_size=batch_size,
num_workers=num_workers,
shuffle=True,
pin_memory=True,
collate_fn=train_dataset.collate_fn)
val_loader = torch.utils.data.DataLoader(val_dataset,
batch_size=1,
num_workers=num_workers,
pin_memory=True,
collate_fn=val_dataset.collate_fn)
# 初始化模型
model = create_model(num_classes=num_classes)
model.to(device)
params_to_optimize = [p for p in model.parameters() if p.requires_grad]
# 创建优化器
optimizer = torch.optim.SGD(
params_to_optimize,
lr=args.lr, momentum=args.momentum, weight_decay=args.weight_decay
)
scaler = torch.cuda.amp.GradScaler() if args.amp else None
# 创建学习率更新策略,这里是每个step更新一次(不是每个epoch)
lr_scheduler = create_lr_scheduler(optimizer, len(train_loader), args.epochs, warmup=True)
start_time = time.time()
for epoch in range(args.start_epoch, args.epochs):
train_loss, lr = train_one_epoch(model, optimizer, train_loader, device, epoch, num_classes,
lr_scheduler=lr_scheduler, print_freq=args.print_freq, scaler=scaler)
val_info, dice, val_loss = evaluate(model, val_loader, device=device, num_classes=num_classes)
3. 训练结果评估
模型训练完成后,会自动在SaveWeightsAndResults
目录下生成评估结果与相应的训练曲线。当然,也可以重新运行项目中的validation.py
脚本进行模型评估。生成的训练结果如下:
运行validation.py
模型评估脚本的话,评估结果如下:
{'global correct': 98.97600412368774,
'PA': ['99.3', '91.9', '89.9'],
'IoU': ['98.9', '82.2', '77.2'],
'precision': ['99.6', '88.6', '84.5'],
'recall': ['99.3', '91.9', '89.9'],
'mPA': 93.71547102928162,
'mean IoU': 86.10977530479431,
'mean precision': 90.90912938117981,
'mean recall': 93.71547102928162}
dice coefficient: 0.883
4. 使用模型进行推理
模型训练完成后,训练结果模型Unet_Train/SaveWeightsAndResults/20250701-165644/last.pth
文件。我们可以使用该文件进行后续的推理检测,运行predict.py
文件。
图片推理核心代码如下:
def main():
# 分割类别数目【不含背景】
classes = 2 # exclude background
# 模型路径
weights_path = "SaveWeightsAndResults/20250701-165644/best.pth"
# 预测的图片路径
img_path = "datasets/valid/images/6.jpg"
assert os.path.exists(weights_path), f"weights {weights_path} not found."
assert os.path.exists(img_path), f"image {img_path} not found."
with open(palette_path, "rb") as f:
pallette_dict = json.load(f)
pallette = []
for v in pallette_dict.values():
pallette += v
# get devices
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("using {} device.".format(device))
# create model
model = UNet(in_channels=3, num_classes=classes+1, base_c=32)
# load weights
model.load_state_dict(torch.load(weights_path, map_location='cpu')['model'])
model.to(device)
# load image
original_img = Image.open(img_path).convert('RGB')
# from pil image to tensor and normalize
data_transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize(mean=Config.mean, std=Config.std)])
img = data_transform(original_img)
# print("img.shape: {}".format(img.shape)) #torch.Size([3, 216, 256])
# expand batch dimension
img = torch.unsqueeze(img, dim=0)
# print("img.shape: {}".format(img.shape)) #torch.Size([1, 3, 216, 256])
model.eval() # 进入验证模式
with torch.no_grad():
# init model
img_height, img_width = img.shape[-2:]
init_img = torch.zeros((1, 3, img_height, img_width), device=device)
# 模型初始化推理
model(init_img)
执行上述代码后,会将压力表上的指针与刻度进行分割,结果如下:
原图
模型分割结果
更多结果示例如下:
总结
本文详细介绍了《工业压力表智能检测与读数系统》实现的第二步:压力表指针与刻度分割。
下一篇文章将详细介绍如何使用OpenCV对分割后的图片进行处理,进行压力表读数读取。
关于该系统涉及到的完整源码、UI界面代码、数据集、训练代码、训练好的模型、测试图片视频等相关文件,均已打包上传,感兴趣的小伙伴可以通过下载链接自行获取。
【获取方式】
关注末尾名片GZH【阿旭算法与机器学习】,发送【源码】获取下载方式
本文涉及到的完整全部程序文件:包括python源码、数据集、训练好的结果文件、训练代码、UI源码、测试图片视频等(见下图),获取方式见文末:
注意:该代码基于Python3.9开发,运行界面的主程序为
MainProgram.py
,其他测试脚本说明见上图。为确保程序顺利运行,请按照程序运行说明文档txt
配置软件运行所需环境。
好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!