抄表是一项极其重要的任务,在现实生活中被广泛使用。许多仪表读数需要手动定期检查和记录仪表读数,以反映设备是否安全运行。由于电表的形状、刻度、指针和特性各不相同,并且存在不同的设备位置,例如变电站中的高压设备,因此很难进行定期的人工检查。
目前,变电站环境中仍然普遍使用带有刻度和指针的传统电表。在实际应用环境中,传统的人工计数不仅涉及许多人为因素,而且容易受到环境的干扰,有触电的危险。随着无人值守变电站的逐步推广,配备自动抄表识别技术的巡检机器人或无人机得到了广泛的应用。因此,利用计算机视觉方法实现智能抄表成为研究热点 [1]。
因此,在本文中,我们将看到一种基于深度学习的读取工业电表的解决方案,该解决方案是在 Google Summer of Code 2023 下创建的,并在英特尔 OpenVINO 工具包组织的主持下实施。

第 1 部分:方法 主要任务是 “准确读取帧/图像中的每个仪表”。整个任务可以归类为计算机视觉任务,因为我们将收到的所有数据都将以图像或视频的形式出现。 该任务可进一步分为两大任务:
- 检测
- 分割
检测
首先,我们需要检测帧中的仪表,单个帧中可能存在一个或多个仪表。检测是最基本的计算机视觉任务之一,有很多方法可以解决这个问题。对于此解决方案,我们选择了 Deep Learning,因为 DL 对对象检测有大量的研究和支持。
在深度学习中,也有很多模型和架构可以满足对象检测的相同目的;选择一个总是很困难的。但是,我们选择了 EfficientDet-d0 进行检测,这是一个可扩展且高效的对象检测模型 [2],并以更少的参数实现了最先进的精度。

分割
一旦我们在框架中检测到仪表并裁剪它,下一步就是找到刻度和指针,然后使用这些信息来计算读数。为此,我们使用了语义分割的方法,这意味着我们将图像中的每个像素分类为其中一个类,这将产生一个可用于定位指针和缩放的分割图,从而计算读数。同样为此,有许多模型,如 UNET、DeepLab、FCN 等。在 UNET 和 DeepLab 中,我们选择了 UNET,因为推理时间和准确性的差异很小。


计算读数
一旦我们得到分割图,最后要做的就是使用分割图计算读数。为此,我们首先将圆形仪表分割转换为矩形,然后找到指针位置和刻度位置,借助它们的相对位置,我们最终可以根据仪表范围和仪表间隔计算读数。

实现
为了实现该解决方案,我们使用了 TensorFlow 作为深度学习框架,以及一些其他库,例如 TensorFlow 官方对象检测 API 和 SegmentationModel。为了进行推理,我们使用了 OpenVINO 框架。
检测器训练

我们使用了 Tensorflow 模型花园中的 EfficientDet,并使用官方 TF 对象检测 API 对其进行训练。它是一个开源项目,提供了在 TensorFlow 中从头开始构建和训练模型所需的所有工具。您可以从 TF 的 Model Zoo 上提供的各种模型架构中进行选择。 您可以按照 detector_training.ipynb 中的训练代码和步骤进行操作。
分割器训练

我们使用了 Segmentation-Model 中的 UNET。Segmentation-Model 是一个开源 Python 库,其中包含 UNET、FPN、PSPNet 和 LinkNet 等最著名的分割模型的 TensorFlow 实现。 您可以按照 segmentor_training.ipynb 中的训练代码和步骤进行操作。 由于大多数电表具有不同的形状、大小和功能,因此建议使用您自己的数据集重新训练模型,其中包含您的电表类型。 要使用自定义数据进行训练,您只需两个目录,分别包含图像和分割图或注释图。然后使用 ‘load_image’ 函数将它们转换为数据。其余代码和步骤与上述笔记本相同。 OpenVINO 推理

一旦我们有了训练好的模型,我们所要做的就是构建一个管道,该管道可以将帧作为输入并返回另一张带有绘制结果的图像。 我们可以直接使用 TensorFlow 模型,但我们使用 OpenVINO 运行时进行推理,因为有一系列可用的工具可以帮助我们改进推理并简化部署。 要使用 OpenVINO 推理,我们需要以 OpenVINO 中间表示形式(即 XML 和 BIN 文件)对模型进行序列化,这是一种标准化文件格式,用于表示针对英特尔硬件优化的神经网络模型。这些 OpenVINO IR 文件使解决方案具有跨平台性,因为它们可以在任何具有 OpenVINO 运行时的系统上使用。 获得 OpenVINO IR 后,我们可以使用管道中的模型来实现预期的结果。
管道将首先对图像进行预处理以进行检测,然后裁剪检测到的部分并对其进行预处理以进行分割,然后使用预测的分割图计算读数,最后绘制结果。有关代码和推理过程的更多详细信息,请查看 OV-meter-reader.ipynb 。
第 2 部分:优化和 GUI 由于现在我们有了读取模拟仪表的 DL 解决方案,下一步是优化多摄像机输入的管道以及用户友好的基于 Web 的 GUI。
优化
该项目的目标是同时监控多个模拟仪表,因此我们不能仅仅依赖分步或同步执行,因为在推理完成之前,结果可能会过时。因此,为了克服这个问题,我们使用异步管道执行。
使用 OpenVINO™ 进行异步推理
OpenVINO Runtime 支持同步或异步模式下的推理。异步 API 的主要优势在于,当设备忙于推理时,应用程序可以并行执行其他任务(例如,填充输入或计划其他请求),而不是等待当前推理先完成。 AsyncInferQueue:AsyncInferQueue 包装器类可以支持异步模式管道。此类自动生成 InferRequest 对象池(也称为 “jobs”) ,并提供同步机制来控制管道的流。这是在 Asynchronous 模式下管理推理请求队列的一种更简单的方法。

我们通过创建一个管道来实现这一点,如下所示: “main_loop”将捕获或读取帧并对其进行预处理以进行检测,从而创建检测 InferRequest。 此检测 InferRequest 完成后,它将调用 ‘detector_callback’ 函数,该函数将进一步处理检测结果并启动分段 InferRequst。 最后,一旦分割 InferRequest 完成,它将调用 ‘segmentor_callback’ 函数,该函数将计算读数并绘制结果。
高级性能提示
尽管 OpenVINO™ 中所有支持的设备都提供低级性能设置,但在极少数情况下不建议使用它们。在 OpenVINO 运行时中配置性能的首选方法是使用性能提示。这是一个面向未来的解决方案,与自动设备选择推理模式完全兼容,并在设计时考虑了可移植性。 吞吐量和延迟:“吞吐量”和“延迟”性能提示都会自动配置异步管道以使用最佳数量的流和推理请求。 Multi-Stream Execution:为模型创建多个流。对于 CPU 插件,每个流都有自己的主机线程,这意味着可以同时处理传入的推理请求。
结果 在尝试了这些优化的不同组合后,我们决定使用 Performance Hint:Latency 以及 Multi-Stream execution。

基于 Web 的 GUI
为了使我们的项目更像一个真实的解决方案,我们决定创建一个基于 Web 的 GUI,用户可以使用我们的 DL 解决方案监控多个仪表。 当谈到网站的后端时,Flask 和 Django 被证明是最佳选择,因为它们具有灵活性、功能、易于实施和大量可用支持。对于这个项目,我们使用了 Flask,因为它比 Django 相对简单和轻量级。 对于前端,我们使用了 HTML、CSS 和 JavaScript 来使其更加用户友好,添加了一些重要的功能,并充当处理后端生成数据的桥梁。
主页 主页基本上是所有事情发生的地方,万用表监控,每个表的最新三个读数将与边界框绘图图像一起显示。因此,用户可以通过实时视频源监控多个仪表。

“设置”页面
在设置页面上,用户可以修改仪表参数,例如仪表的范围、间隔数和刷新时间。刷新时间 是相机捕获新帧、处理新帧并显示输出的时间。 我们希望为用户提供尽可能多的灵活性,因此我们让用户决定,而不是对这些参数进行硬编码。因此,用户可以同时监控多个不同的仪表。

技术支持微信号:18633330660
发表回复