指针压力表读数2:Pytorch实现指针压力表读数(含训练代码)
目录
指针压力表读数2:Pytorch实现指针压力表读数(含训练代码)
1. 前言
2.指针压力表读数方法
(1)角度法获取读数
(2)指针和刻度检测
3.指针压力表数据集
4.指针压力表检测模型训练
5.指针压力表指针和刻度关键点检测
(1)项目安装
(2)准备Train和Test数据
(3)配置文件configs
(4)开始训练
(5)Tensorboard可视化训练过程
6.指针压力表模型检测效果
7.指针压力表读数项目代码
(1)指针压力表读数推理代码(Pytorch)
(2)指针压力表读数训练代码和测试代码+数据集(Pytorch)
8.指针压力表读数C++和Android版本
1. 前言
本篇文章是项目《指针压力表读数》系列文章之《PyTorch实现指针压力表读数》。项目基于 PyTorch 深度学习框架,构建了一套完整的指针压力表自动读数识别方案。整体流程采用“压力表检测 + 关键点检测 + 读数计算”的三阶段设计:首先利用 YOLO11 模型从复杂工业背景中快速定位压力表表盘区域,裁剪得到表盘 ROI;随后在 ROI 内对表盘量程范围起点(零刻度线)、量程范围终点(最大刻度线)、指针起点和指针终点四个关键位置进行关键点检测;最后基于关键点之间的几何关系计算指针偏转角度,并结合量程信息换算得到最终压力读数。
其中,压力表表盘检测采用 YOLO11 模型。YOLO11 在检测速度、小目标识别能力和模型导出兼容性方面具有较好优势,能够适应工业现场中表盘尺度变化大、拍摄角度倾斜、光照不均等复杂场景。 表盘指针关键点检测则基于开源 HRNet 进行改进,构建了完整的指针压力表读数训练与测试流程。HRNet 通过保持高分辨率特征表示,能够更稳定地回归指针尖端、表盘中心等细长或弱纹理关键点;在此基础上,项目进一步引入轻量化分支,支持高精度 HRNet、LiteHRNet 以及 MobileNet 等多种骨干网络的训练和测试,从而在检测精度、推理速度和模型体积之间进行灵活权衡。
为了方便后续模型工程化和 Android 平台部署,项目同时提供了 Python、C++ 和 Android 多个版本的实现。Python 版本主要用于算法验证、模型训练、离线测试和效果可视化;C++ 版本基于 ONNX 或 MNN等推理后端实现,便于在边缘设备、工控机或嵌入式平台上集成;Android 版本则面向移动端巡检场景,支持相机采集、实时推理和读数结果显示。
轻量化Mobilenet-v2模型在普通Android手机上可以达到实时的检测效果,CPU(4线程)约40ms左右,GPU约30ms左右 ,基本满足业务的性能需求。下表格给出HRNet,以及轻量化模型LiteHRNet和Mobilenet的计算量和参数量,以及其检测精度
| 模型 | input-size | params(M) | GFLOPs | AP |
| HRNet-w32 | 192×192 | 28.48M | 5734.05M | 0.9801 |
| LiteHRNet18 | 192×192 | 1.10M | 182.15M | 0.9708 |
| Mobilenet-v2 | 192×192 | 2.63M | 529.25M | 0.9589 |
先展示一下指针压力表读数检测效果:
Android指针压力表读数APP Demo体验:https://download.csdn.net/download/guyuealian/93758160
【尊重原创,转载请注明出处】https://blog.csdn.net/guyuealian/article/details/168873246
更多项目《指针压力表读数》系列文章请参考:
- 指针压力表读数1:指针压力表数据集下载https://blog.csdn.net/guyuealian/article/details/168873184
- 指针压力表读数2:Pytorch实现指针压力表读数(含训练代码) https://blog.csdn.net/guyuealian/article/details/168873246
- 指针压力表读数3:C/C++实现指针压力表读数(可实时检测) https://blog.csdn.net/guyuealian/article/details/168873267
- 指针压力表读数4:Android实现指针压力表读数(可实时检测) https://blog.csdn.net/guyuealian/article/details/168873316
2.指针压力表读数方法
(1)角度法获取读数
项目采用最简单、最直接的指针压力表读数方法—角度法获取读数。该方法通过观察指针在刻度盘上的位置来获取被测量的角度值,仅需获得零刻度线与指针之间的夹角度数、零刻度线与量程终点之间的夹角度数,即可依据比例关系计算出示数。
计算过程简洁明了,无需复杂图像处理或高精度传感设备。由于该方法仅依赖角度比例关系,不受表盘直径、刻度分布样式等因素限制,因而具有原理简单、读数速度快、适用范围广泛的优点,可适用于多种规格和类型的指针式压力表。同时,该方法对硬件要求低、实现成本小,便于在现场快速部署与应用,为指针压力表的自动化读数提供了一种高效、可靠的技术途径。
角度法中各参数示意图如图:
其中,M表示最大刻度即仪表的量程。通过三者之间的关系,可以求得仪表的读数:
(2)指针和刻度检测
角度法获取读数的核心在于通过算法准确获取指针指向、零刻度线和最大刻度线的位置信息。具体可采用关键点检测方法实现:分别检测量程范围起点(零刻度线)、量程范围终点(最大刻度线)、指针起点和指针终点四个关键点。其中,零刻度线与最大刻度线共同确定刻度盘的量程基准及角度参照系,指针起点与指针终点则共同确定指针的实际指向方向。在获取上述关键点坐标后,以指针起点为顶点,分别计算指针方向与零刻度线方向、零刻度线方向与最大刻度线方向之间的夹角,进而依据角度比例关系即可换算出压力表示数。采用关键点检测方法具有定位精度高、鲁棒性强的优点,能够有效应对表盘倾斜、光照变化及指针遮挡等复杂情况,为角度法的准确读数提供可靠保障。
算法流程如下:采用“压力表检测 + 关键点检测 + 读数计算”的三阶段:首先利用 YOLO11 模型从复杂工业背景中快速定位压力表表盘区域,裁剪得到表盘 ROI;随后在 ROI 内对表盘量程范围起点(零刻度线)、量程范围终点(最大刻度线)、指针起点和指针终点四个关键位置进行关键点检测;最后以指针起点为顶点,计算指针方向与零刻度线方向之间的夹角,以及零刻度线方向与最大刻度线方向之间的量程夹角,进而依据角度比例关系换算出压力表的读数
压力表读数=(指针与零刻度线夹角/零刻度线与量程夹角)×量程
3.指针压力表数据集
关于指针压力表数据集说明,请参考:https://blog.csdn.net/guyuealian/article/details/168873184
4.指针压力表检测模型训练
项目采用使用ultralytics YOLO11模型实现压力表目标检测,模型训练比较简单,可参考官方教程 :GitHub - ultralytics/ultralytics: Ultralytics YOLO27, YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking · GitHubUltralytics YOLO27, YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking - ultralytics/ultralyticshttps://github.com/ultralytics/ultralytics
5.指针压力表指针和刻度关键点检测
整套工程项目基本结构如下:
. ├── configs # 训练配置文件 ├── data # 一些数据 ├── libs # 一些工具库 ├── pose # 姿态估计模型文件 ├── work_space # 训练输出工作目录 ├── demo.py # 模型推理demo文件 ├── README.md # 项目工程说明文档 ├── requirements.txt # 项目相关依赖包 └── train.py # 训练文件(1)项目安装
项目依赖python包请参考requirements.txt,使用pip安装即可,项目代码都在Ubuntu系统和Windows系统验证正常运行,请放心使用;若出现异常,大概率是相关依赖包版本没有完全对应
numpy==1.21.6 matplotlib==3.2.2 Pillow==8.4.0 bcolz==1.2.1 easydict==1.9 onnx==1.8.1 onnx-simplifier==0.2.28 onnxoptimizer==0.2.0 onnxruntime==1.6.0 opencv-contrib-python==4.5.2.52 opencv-python==4.5.1.48 pandas==1.1.5 PyYAML==5.3.1 scikit-image==0.17.2 scikit-learn==0.24.0 scipy==1.5.4 seaborn==0.11.2 sklearn==0.0 tensorboard==2.5.0 tensorboardX==2.1 torch==1.7.1+cu110 torchvision==0.8.2+cu110 tqdm==4.55.1 xmltodict==0.12.0 pycocotools==2.0.2 pybaseutils==0.9.4 basetrainer json_tricks==3.17.3项目安装教程请参考(初学者入门,麻烦先看完下面教程,配置好Python3.10开发环境):
- 推荐使用Python3.10,更高版本可能不支持
- 项目开发使用教程和常见问题和解决方法
- 视频教程:1 手把手教你安装CUDA和cuDNN(1)
- 视频教程:2 手把手教你安装CUDA和cuDNN(2)
- 视频教程:3 如何用Anaconda创建pycharm环境
- 视频教程:4 如何在pycharm中使用Anaconda创建的python环境
(2)准备Train和Test数据
下载指针压力表数据集:pressure-meter1和pressure-meter1,然后解压到本地
(3)配置文件configs
项目支持HRNet以及轻量化模型LiteHRNet和Mobilenet模型训练,并提供对应的配置文件;你需要修改对应配置文件的数据路径;本篇以训练HRNet-w32为例子,其配置文件在configs/coco/hrnet/w32_adam_hand_192_192.yaml,修改该文件的训练数据集路径TRAIN_FILE(支持多个数据集训练)和测试数据集TEST_FILE的数据路径为你本地数据路径,其他参数保持默认即可,如下所示:
WORKERS: 8 PRINT_FREQ: 20 DATASET: DATASET: 'custom_coco' TRAIN_FILE: - '/home/pressure-meter1/train/coco_kps.json' - '/home/pressure-meter2/train/coco_kps.json' TEST_FILE: '/home/pressure-meter1/val/coco_kps.json' FLIP: true ROT_FACTOR: 45 SCALE_FACTOR: 0.3 SCALE_RATE: 1.0 JOINT_IDS: [ ] FLIP_PAIRS: [ ] SKELETON: [[2, 0], [2, 1], [2, 3]]配置文件的一些参数说明,请参考
| 参数 | 类型 | 参考值 | 说明 |
| WORKERS | int | 8 | 数据加载处理的进程数 |
| PRINT_FREQ | int | 10 | 打印LOG信息的间隔 |
| DATASET | str | custom_coco | 数据集类型,目前仅支持COCO数据格式 |
| TRAIN_FILE | List | - | 训练数据集文件列表(COCO数据格式),支持多个数据集 |
| TEST_FILE | string | - | 测试数据集文件(COCO数据格式),仅支持单个数据集 |
| FLIP | bool | True | 是否翻转图片进行测试,可提高测试效果 |
| ROT_FACTOR | float | 45 | 训练数据随机旋转的最大角度,用于数据增强 |
| SCALE_FACTOR | float | 1.25 | 图像缩放比例因子 |
| SCALE_RATE | float | 0.25 | 图像缩放率 |
| JOINT_IDS | list | [ ] | [ ]表示所有关键点,也可以指定需要训练的关键点序号ID |
| FLIP_PAIRS | list | [ ] | 图像翻转时,关键点不受翻转影响的ID号 |
| SKELETON | list | [ ] | 关键点连接线的序列列表,用于可视化效果 |
(4)开始训练
修改好配置文件后,就可以开始准备训练了:
- 训练高精度模型HRNet-w48或者HRNet-w32
# 高精度模型:HRNet-w48 python train.py -c "configs/coco/hrnet/w32_adam_192_192.yaml" --workers=8 --batch_size=32 --gpu_id=0 --work_dir="work_space/pressure_meter" # 高精度模型:HRNet-w32 python train.py -c "configs/coco/hrnet/w48_adam_192_192.yaml" --workers=8 --batch_size=32 --gpu_id=0 --work_dir="work_space/pressure_meter"- 训练轻量化模型LiteHRNet
# 轻量化模型:LiteHRNet python train.py -c "configs/coco/litehrnet/litehrnet18_192_192.yaml" --workers=8 --batch_size=32 --gpu_id=0 --work_dir="work_space/pressure_meter"- 训练轻量化模型Mobilenetv2
# 轻量化模型:Mobilenet python train.py -c "configs/coco/mobilenet/mobilenetv2_192_192.yaml" --workers=8 --batch_size=32 --gpu_id=0 --work_dir="work_space/pressure_meter"下表格给出HRNet,以及轻量化模型LiteHRNet和Mobilenet的计算量和参数量,以及其检测精度AP; 高精度检测模型HRNet-w32,AP可以达到0.9801,但其参数量和计算量比较大,不合适在移动端部署;LiteHRNet18和Mobilenet-v2参数量和计算量比较少,合适在移动端部署;虽然LiteHRNet18的理论计算量和参数量比Mobilenet-v2低,但在实际测试中,发现Mobilenet-v2运行速度更快。轻量化Mobilenet-v2模型在普通Android手机上可以达到实时的检测效果,CPU(4线程)约40ms左右,GPU约30ms左右 ,基本满足业务的性能需求
| 模型 | input-size | params(M) | GFLOPs | AP |
| HRNet-w32 | 192×192 | 28.48M | 5734.05M | 0.9801 |
| LiteHRNet18 | 192×192 | 1.10M | 182.15M | 0.9708 |
| Mobilenet-v2 | 192×192 | 2.63M | 529.25M | 0.9589 |
(5)Tensorboard可视化训练过程
训练过程可视化工具是使用Tensorboard,使用方法,在终端输入:
# 基本方法 tensorboard --logdir=path/to/log/ # 例如 tensorboard --logdir=work_space/pressure_meter/hrnet_w32_4_192_192_custom_coco_20261023_092104_1319/log点击终端TensorBoard打印的链接,即可在浏览器查看训练LOG信息等:
6.指针压力表模型检测效果
demo.py文件用于推理和测试模型的效果,填写好配置文件,模型文件以及测试图片即可运行测试了;demo.py命令行参数说明如下:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| -c,--config_file | str | - | 配置文件 |
| -m,--model_file | str | - | 模型文件 |
| target | str | - | 骨骼点类型,如hand,coco_person,mpii |
| image_dir | str | data/image | 测试图片的路径 |
| video_file | str,int | - | 测试的视频文件 |
| out_dir | str | output | 保存结果,为空不保存 |
| threshold | float | 0.3 | 关键点检测置信度 |
| device | str | cuda:0 | GPU ID |
| range | float | -1 | 压力表量程范围,-1表示未知。 |
下面以运行LiteHRNet18为样例,其他模型修改--config_file或者--model_file即可
- 测试图片(参数range表示压力表量程范围,请根据实际情况填写)
python demo.py -c work_space/pressure_meter/LiteHRNet18_4_192_192_custom_coco_20261023_105744_0418/litehrnet18_192_192.yaml -m work_space/pressure_meter/LiteHRNet18_4_192_192_custom_coco_20261023_105744_0418/model/best_model_209_1.0000.pth --image_dir data/images --out_dir output --range -1- 测试视频文件(参数range表示压力表量程范围,请根据实际情况填写)
python demo.py -c work_space/pressure_meter/LiteHRNet18_4_192_192_custom_coco_20261023_105744_0418/litehrnet18_192_192.yaml -m work_space/pressure_meter/LiteHRNet18_4_192_192_custom_coco_20261023_105744_0418/model/best_model_209_1.0000.pth --video_file data/video01.mp4 --out_dir output --range 100- 测试摄像头(参数range表示压力表量程范围,请根据实际情况填写)
python demo.py -c work_space/pressure_meter/LiteHRNet18_4_192_192_custom_coco_20261023_105744_0418/litehrnet18_192_192.yaml -m work_space/pressure_meter/LiteHRNet18_4_192_192_custom_coco_20261023_105744_0418/model/best_model_209_1.0000.pth --video_file 0 --out_dir output --range -1运行效果:
下面效果图只显示了指针与零刻度线夹角/零刻度线与量程夹角的比值,指针读数时,需要将比值×量程(最大刻度),获得真实的压力表指针读数。
7.指针压力表读数项目代码
如需下载项目源码,请WX关注【AI吃大瓜】,回复【指针压力表】即可下载
(1)指针压力表读数推理代码(Pytorch)
- 提供YOLO11n指针压力表目标检测推理代码
- 提供高精度版本HRNet-w32,以及轻量化模型LiteHRNet和Mobilenet-v2的推理代码(不含训练代码)。
- 提供训练好的模型:高精度版本HRNet-w32,以及轻量化模型LiteHRNet和Mobilenet-v2模型,配置好环境,可直接运行demo.py
- 提供指针压力表:零刻度线、最大刻度线、指针起点和指针终点共四个关键点检测推理代码demo.py
- 推理代码demo.py提供视频关键点去抖动算法(filter=true)
- 推理代码demo.py支持图片,视频和摄像头测试。
如果你需要配套的训练数据集和训练代码,请查看下面部分
(2)指针压力表读数训练代码和测试代码+数据集(Pytorch)
- 提供pressure-meter1和pressure-meter2指针压力表读数数据集,含labelme数据标注文件。
- 提供YOLO11n指针压力表目标检测推理代码
- 提供高精度版本HRNet-w32,以及轻量化模型LiteHRNet和Mobilenet-v2的推理代码和训练代码。
- 提供训练好的模型:高精度版本HRNet-w32,以及轻量化模型LiteHRNet和Mobilenet-v2模型,配置好环境,可直接运行demo.py
- 提供指针压力表:零刻度线、最大刻度线、指针起点和指针终点共四个关键点检测推理代码demo.py
- 推理代码demo.py提供视频关键点去抖动算法(filter=true)
- 推理代码demo.py支持图片,视频和摄像头测试。
8.指针压力表读数C++和Android版本
- 指针压力表读数3:C/C++实现指针压力表读数(可实时检测) https://blog.csdn.net/guyuealian/article/details/168873267
- 指针压力表读数4:Android实现指针压力表读数(可实时检测) https://blog.csdn.net/guyuealian/article/details/168873316
指针压力表读数Android APK安装包体验效果: https://download.csdn.net/download/guyuealian/93758160