为了解决工业表计自动读数中的关键环节——指针与刻度检测问题,本文提出一种基于 YOLOv8-pose 模型的关键点检测方法。该方法通过分别构建指针关键点检测与刻度关键点检测两个模型,实现对表盘中指针(表头和中心点)以及刻度点的自动定位。在训练阶段,利用自定义数据集对模型进行微调;在预测阶段,通过关键点定位与后续数据处理,实现对工业表计关键信息的准确提取,为后续读数计算提供数据支撑。
1. 简介
工业表计(如压力表、电表、气表等)在设备监控和自动化管理中扮演重要角色。传统人工抄表存在效率低、易出错的问题,而自动化检测则可以大幅提升读数准确率和实时性。本文在前端表计区域检测的基础上,进一步聚焦于表针和刻度的关键点定位。具体来说,指针部分主要检测表头和表盘中心两个关键点,而刻度部分则检测每个刻度对应的位置,再通过 OCR 模块识别刻度数值。本文详细介绍了模型的训练和预测代码,并对实验结果进行了分析。
2. 模型训练
本文使用 Ultralytics 的 YOLO 框架,并基于 YOLOv8-pose 模型对指针和刻度关键点进行检测。下面分别给出指针和刻度关键点检测的训练代码及说明。
2.1 指针关键点检测训练
指针检测任务主要聚焦于两个关键点:
- 表头点:指针末端,用于确定指针指向。
- 中心点:表盘中心,用于作为角度计算的参考。
训练代码示例如下:
import torch
import warnings
warnings.filterwarnings("ignore")
from ultralytics import YOLO
if __name__ == '__main__':
# 指针关键点检测模型的配置与预训练权重
yolo_yaml = "/root/cv/task_1/yolo_model/my_yolov8x-pose.yaml"
yolo_pt = "/root/cv/task_1/yolov8n-pose.pt"
data_yaml = "/root/autodl-tmp/meter_data/pointer_keypoint_detect/dataset.yaml"
# 构建模型(也可直接加载预训练权重)
model = YOLO(yolo_yaml)
# 开始训练,设置 epochs、imgsz 和 batch 大小
results = model.train(data=data_yaml, epochs=100, imgsz=640, batch=8)
# 模型验证,评估检测效果
model.val()
在上述代码中,我们采用自定义数据集进行训练。数据集内包含了指针关键点的标注信息,经过 100 个 epoch 的训练后,模型能较好地学习指针的表头与中心点位置。
2.2 刻度关键点检测训练
刻度检测任务针对表盘上的每个刻度点进行定位,并结合 OCR 技术获取刻度数值。训练代码示例如下:
import torch
from ultralytics import YOLO
if __name__ == '__main__':
# 刻度关键点检测模型采用相同的 YOLOv8-pose 结构,通过加载预训练权重构建
model = YOLO('/root/cv/task_2/my_yolov8x-pose.yaml').load('yolov8n-pose.pt')
# 利用刻度数据集进行训练,设置适当的 lr0 和 batch 大小
results = model.train(data="/root/autodl-tmp/meter_data/scale_keypoint_detect/dataset.yaml",
epochs=100, imgsz=640, batch=16, lr0=0.002)
# 模型验证
model.val()
这里的训练过程与指针检测类似,不同之处在于训练数据集标注了刻度点信息,通过调整学习率和 batch 大小,确保模型对刻度小目标具有较好的定位精度。
3. 预测与结果展示
训练完成后,我们分别对指针和刻度关键点进行预测,通过代码可视化检测结果。以下分别给出预测代码及结果展示说明。
3.1 指针关键点预测
在预测阶段,加载训练好的指针关键点检测模型,对单张表计图像进行推理,提取边界框和关键点信息。预测代码如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from ultralytics import YOLO
# 加载指针关键点检测模型
model = YOLO("/root/cv/runs/pose/train4/weights/best.pt")
objs_labels = model.names
# 对单张图片进行预测
results = model(['/root/cv/datas/test_data/test.jpg'],
save=False, imgsz=640)
frame = cv2.imread("/root/cv/datas/test_data/test.jpg")
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 绘制检测结果
for result in results:
# 绘制检测边界框
boxes = result.boxes.cpu().numpy()
for box in boxes.data:
l, t, r, b = box[:4].astype(np.int32)
conf, id = box[4:]
id = int(id)
cv2.rectangle(frame, (l, t), (r, b), (0, 0, 255), 2)
cv2.putText(frame, f"{objs_labels[id]} {conf * 100:.1f}%", (l, t - 10),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# 绘制关键点及指向线(例如:从中心到表头)
keypoints = result.keypoints.cpu().numpy()
for keypoint in keypoints.data:
for i in range(len(keypoint)):
x, y, _ = keypoint[i]
cv2.circle(frame, (int(x), int(y)), 10, (0, 255, 0), -1)
if len(keypoint) >= 2:
x0, y0, _ = keypoint[0]
x1, y1, _ = keypoint[1]
cv2.line(frame, (int(x0), int(y0)), (int(x1), int(y1)), (255, 0, 255), 4)
plt.imshow(frame)
plt.show()
cv2.imwrite('/root/cv/task_1/frame.jpg', frame)
代码中,我们首先读取图像并进行颜色空间转换,然后对检测结果中的边界框和关键点进行遍历绘制。关键点以圆点标记,并使用线段连接两个关键点,直观展示指针的方向信息。
3.2 刻度关键点预测
刻度检测的预测流程与指针类似,同样加载训练好的刻度检测模型,并对目标图像进行推理,绘制检测框和关键点。预测代码如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from ultralytics import YOLO
# 加载刻度关键点检测模型
model = YOLO('/root/cv/task_2/runs/pose/train7/weights/best.pt')
objs_labels = model.names
# 对目标图片进行预测(图片为已裁剪出的单个表计区域)
results = model(['/root/cv/test/task_0_result/test.jpg'],
save=False, imgsz=640)
frame = cv2.imread("/root/cv/test/task_0_result/test.jpg")
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 绘制检测结果与关键点
for result in results:
boxes = result.boxes.cpu().numpy()
for box in boxes.data:
l, t, r, b = box[:4].astype(np.int32)
conf, id = box[4:]
id = int(id)
cv2.rectangle(frame, (l, t), (r, b), (0, 0, 255), 2)
cv2.putText(frame, f"{objs_labels[id]} {conf * 100:.1f}%", (l, t - 10),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
keypoints = result.keypoints.cpu().numpy()
for keypoint in keypoints.data:
for i in range(len(keypoint)):
x, y, _ = keypoint[i]
cv2.circle(frame, (int(x), int(y)), 10, (0, 255, 0), -1)
if len(keypoint) >= 2:
x0, y0, _ = keypoint[0]
x1, y1, _ = keypoint[1]
cv2.line(frame, (int(x0), int(y0)), (int(x1), int(y1)), (255, 0, 255), 4)
plt.imshow(frame)
plt.show()
cv2.imwrite('/root/cv/task_2/frame.jpg', frame)
该代码同样对预测结果进行解析,通过绘制边界框和关键点,直观展示刻度关键点的位置,为后续通过 OCR 模块识别刻度数字并构建刻度映射提供基础。
4. 实验结果与讨论
通过上述训练和预测流程,本文所提出的指针与刻度关键点检测方法在复杂工业表计图像中均取得了良好的效果。具体结果表明:
- 指针关键点检测:模型能够在多角度、不同光照条件下准确定位表头与中心点,提取的关键点为后续角度计算提供了准确依据。
- 刻度关键点检测:模型有效检测到各个刻度点的位置,结合 OCR 识别后,可实现表盘刻度的数值映射,从而进一步提升整体读数精度。
尽管模型整体表现良好,但在部分低对比度或噪声较大的图像中,关键点定位仍存在一定误差。后续工作将针对数据增强策略、模型结构优化及后处理算法进一步改进检测精度。
5. 小结
本文基于 YOLOv8-pose 模型实现了工业表计中指针与刻度关键点的自动检测,构建了一套从数据预处理、模型训练到关键点预测的完整流程。实验结果验证了该方法在复杂工业场景下的有效性,为自动读数系统中的表针角度计算和刻度映射提供了坚实基础。未来工作将继续聚焦于模型轻量化、多尺度特征融合及环境适应性优化,以实现更高效的工业表计智能监控系统。