APP下载

基于KNN算法的仪表实时监控边缘平台*

2021-09-24胡琼铧应霜霜

科技创新与应用 2021年26期
关键词:仪表灰度边缘

胡琼铧,应霜霜,马 超

(哈尔滨理工大学 计算机科学与技术学院,黑龙江 哈尔滨 150080)

目前,利用物联网、人工智能以及移动互联网等新一代信息技术对现有生产、生活等不同场景下的各类基础设施进行改造、升级,以提高人们的生产、生活的效率以及便捷性已成为主流趋势。其中,仪表系统即是其中的一类主要基础设施。随着信息与通信、电子信息等技术的逐渐成熟,新铺设的仪表系统普遍具备数字化、智能化特征,可支持远程监控功能的实现。但是目前的现实场景下,仍存在大量的旧式仪表,它们无法支持远程监控功能的实现,这对于现在基础设施的改造、升级工作造成了较大的障碍。同时,简单的对旧式仪表系统进行替换,也存在较大的困难,例如,新式仪表系统普遍价格较高,现存的旧式仪表所处的场景不具备安装新式仪表系统的客观条件等。

针对这一问题,本文提供一种基于KNN算法的仪表实时监控边缘平台,其可部署在现有的旧式仪表系统周围,以实现对旧式仪表系统实时数据的智能识别,并将其传输至远程的云服务平台。本边缘平台的硬件部分以树莓派为基础,搭载图像采集模块以及基于KNN算法的图像智能识别模块,远端云服务平台采用前后端分离的架构,作为整个系统的控制中心,具有监控、统计、报警等多项功能,满足了对仪表系统这一基础设施的数字化、智能化管理需求。其中,在智能算法的选择方面,我们综合考虑了多种不同算法在执行时间、准确率与召回率、需要消耗的计算资源等多方面的情况,最终决定采用KNN算法,其是一种耗费计算资源较低,且性能较高的经典机器学习算法,相对来说,更合适资源受限的边缘计算平台。

1 实时监控边缘平台的总体设计架构

本边缘平台选择使用树莓派4(Raspberry Pi 4)作为硬件平台,搭载图像采集模块、图像传输模块。考虑暗光以及光线条件较差的环境,在摄像头搭载2-3个红外补光灯,补光灯可根据光照环境的强弱自动调节曝光补偿程度,从而使摄像头获得不错的成像效果。

利用摄像头指定时间间隔收集仪表盘的图像,成像保存在树莓派图像采集模块中,树莓派中的图像分析模块接收图片信息后,进行图像预处理:转化成灰度图、降噪、旋转图像使数字在水平线上、识别边缘和线条取得数字特征、高斯滤波、锐化、二值化处理,从而获得效果最佳的仪表盘二值化图像。然后,采用机器学习训练KNearestOcr模型,采用OpenCV集成的KNN算法识别字符。输出结果将其反馈到终端应用(移动端微信小程序,移动端App,网页等)。处理过的图像加入到模板库中,更新训练集,提高模型识别数字的精准程度。整体设计架构如图1所示。

图1 总体设计架构

2 基于OpenCV的仪表盘数字图像预处理

2.1 OpenCV库

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS等不同的操作系统上。它轻量级而且高效,集成了图像处理和计算机视觉方面的很多通用算法。

在此处,OpenCV库的主要任务是对采集仪表盘图像进行早期的预处理:提供转化为灰度图、图像降噪、图像旋转、高斯滤波、锐化、二值化处理等图像预处理的集成算法,从而获得效果最佳的二值化图像。

2.2 OCR模块

识别图像中的文本是一种非常流行的计算机视觉应用,此过程通常称为光学字符识别(Optical Character Recognition,OCR)。主要有以下步骤:

2.2.1 图像获取

利用OpenCV,我们只需要数行源代码即可实现通过USB网络摄像头获取电表图像以及从文件里获取图像信息。在这里我们定义一个基类ImageInput(),这个基类负责保留图像地址以及图像采集的时间戳。接下来需要派生类DirectoryInput()和CameraInput()各自实现nextImage()方法。前者负责从文件读取图像。后者负责通过VideoCapture.open()打开摄像头输入通道,获取图像。最后通过saveImage()方法存储图像。至此,提供了一个简单的USB视频类供摄像头获取图像以及进行读取、存储。分辨率为640×480像素,这对于本系统而言已经足够了。毕竟较高的分辨率并不能提高字符识别的准确性,并会占用更多的内存和CPU时间进行图像处理,而这在Raspberry Pi上是非常有限的资源。

2.2.2 cv::Mat图像存储

现在,我们来简要了解一下OpenCV是如何存储图像的。从文件中读取图像的imread()和从相机中捕捉图像的VideoCapture.read()都会产生类型为cv::Mat的对象。

命名空间前缀cv封装了OpenCV的大多数类和函数,以避免与其他库发生名称冲突。Mat是一个n维数组或矩阵,可以用来存储不同的东西。

Mat对象_img包含捕获的图像在默认情况下,imread()和VideoCapture.read()在BGR(蓝-绿-红)颜色空间中生成图像。这与已知的RGB颜色模型相同,只是记忆中的颜色通道反向排列。该模型用蓝、绿、红三个独立的强度值来描述图像的每个像素。

另一个常用的颜色模型是灰度,用单个灰度值对每个像素进行编码。在这种情况下,cv::Mat是一个二维矩阵,而它在BGR色彩空间是三维的。使用channels()函数可以检测图像的颜色模型。BGR返回值为3,灰度值为1。

一个常用的函数是用cvtColor方法将BGR图像转换为灰度:

cv::Mat color,gray;

color=cv::imread(filename);

cvtColor(color,gray,CV_BGR2GRAY);

2.2.3 图像处理

电表获取的图像存储在cv::Mat对象中。在我们能够对计数器进行字符识别之前,算法必须识别和提取计数器的单个数字。ImageProcessor类封装了这样做所需的所有方法。

使用setput()传递要处理的图像。函数process()执行完整的处理。成功时,getOutput()提供结果。它由图像矢量组成。每个图像都包含计数器的一个数字。函数process()将各个处理步骤委托给其他私有函数。每个图像的过程都是一样的:转换成灰度图像、旋转,使计数器的数字在水平线上、找到并切下每个数字。

2.2.4 图像旋转

将图像转换为灰度后,算法应该将图像旋转到计数器的所有数字在一条水平线上。得到水平排列的,明亮的轮廓。图像的旋转通过映射变换执行cv::warpAffine()函数。简单地说,这些就是图像的变化,所有的平行线即使经过平移、旋转和缩放变换后仍然是平行的。所有这些变换都可以用变换矩阵来描述。当要对同一幅图像应用多个映射变换时,出于性能方面的原因,通常有意义的做法是先一步一步地将每个变换矩阵相乘,最后对图像进行实际的变换。预设角度的图像旋转被外包给rotate()函数。

2.2.5 识别边缘和线条

其实,OpenCV的很大一部分是用于边缘和线条的识别。在此我们用的是Canny算法。Canny()接收灰度图像作为输入,输出一幅以检测到的边缘为输出的图像。

cv::Mat ImageProcessor::cannyEdges(){

cv::Mat edges;

cv::Canny(_imgGray,edges,

_config.getCannyThreshold1(),

_config.getCannyThreshold2());

return edges;

}

不重要的细节现在基本上从边缘图像消失了。然而,多余的图像信息仍然存在:仪表外壳边缘、计数器边缘和计数环边缘。图像依旧角度不正确,但是水平线的偏差正好是我们需要对齐图像的角度。

我们接下来通过cv::HoughLines()进行Hough变换,返回包含所有检测到的向量行。HoughLines()返回以弧度为单位的角度,而rotate()需要以角度为单位的旋转角度。

3 基于机器学习方法建立自动识别模型

由上一步得到的向量_digits的每个分量都包含一个数字的边缘图像。

计算机通过光学字符识别(OCR)的方法得到由图像来表示字符的信息。一种常用的技术是机器学习。第一步是用各种测试数据训练系统。这就产生了一个模型,它描述了从数据(图像)到信息(字符编码)的映射。使用这个模型,训练后的系统就可以在第二步中将未知数据转换成所需的信息,且每一轮图像识别后都会将得到的字符存储到本地并持续更新训练模板库,从而逐渐提高图像识别的精确度。

3.1 KNN概述

KNN(K-Nearest-Neighbor)算法是一种常见的监督学习方法。工作原理是提取样本,根据某种距离形式来计算与检测样本距离最靠近的K个“邻居”,以此来分类检测样本属于哪一类。

通常将样本中出现次数最多的标记作为分类的结果,越靠近平均值,样本就属于这一类。在计算样本距离时我们采用欧式距离公式来实现。

接下来就是最简单的转换,将数字图片黑色部分(背景)变0,有数字轮廓的部分变1。转换后的大小要合适,太小会影响识别准确度,太大会增加计算量。

3.2 利用KNN对数字进行识别

机器学习的算法有很多种,OpenCV在很大程度上实现了这些算法。为一个特定的问题选择正确的算法需要大量的经验和知识。下面使用了最简单的算法之一:K近邻(KNN)。众所周知,它非常准确,但另一方面,它消耗了大量的CPU时间和内存。这些缺点对我们的应用程序来说并不是那么关键——有足够的条件。虽然内存仅限树莓派,但对于只需要检测8-15位数字的小尺寸模型来说,它应该足够了。

对于训练和字符识别的实施,班级KNearestOcr负责:

class KNearestOcr{

public:

int learn(const cv::Mat&img);

char recognize(const cv::Mat&img);

voidsaveTrainingData();

boolloadTrainingData();

private:

cv::MatprepareSample(const cv::Mat&img);

voidinitModel();

cv::Mat_samples;

cv::Mat_responses;

CvKNearest*_pModel;

};

机器学习程序可以处理各种输入数据,而不仅仅是图片。输入数据的准备也称为“特征提取”。相关特征在我们利用OpenCV进行图像预处理中已经完成。它提供了数字的轮廓,没有任何背景和颜色信息。首先,它利用cv::resize()将所有的数字统一为10×10像素大小。由于KNN处理的是浮点数的一维向量,因此使用函数reshape()和convertTo()将图像矩阵转换为如下格式:

cv::MatKNearestOcr::

prepareSample(const cv::Mat&img){

cv::Matroi,sample;

cv::resize(img,roi,cv::Size(10,10));

roi.reshape(1,1).convertTo(sample,CV_32F);

return sample;

}

然后,构建两个字段_samples和_responses。_samples包含所有已经成功通过训练过程的特性(prepare-Sample的结果)。字段_responses包含训练器针对每个特性的相关“响应”——即对应的数字。接下来运行实施互动训练程序:

intKNearestOcr::learn(const cv::Mat&img){

cv::imshow('Learn',img);

int key=cv::waitKey(0);

if(key>'0'&&key<'9'){

_responses.push_back

(cv::Mat(1,1,CV_32F,(float)key-'0'));

_samples.push_back(prepareSample(img));

}

return key;

}

第一个cv::imshow()显示数字的图像。然后cv::waitKey()等待coach的输入。如果这是一个有效的数字,那么它将与相关的特性一起写入_responses和_samples。

用户可以使用键‘q’或‘s’随时终止训练过程。在‘s’的情况下,saveTrainingData()方法将字段_samples和_responses写入文件。

首先,KNearestOcr::loadTrainingData()初始化模型。

该模型现在能够对使用prepareSample()准备的任何图像进行分类,方法是确定最近的邻居特征并返回相关的、学习到的响应。

recognize()使用find_nearest()来确定两个最近的邻居及其到原始对象的距离。只有当两个值都匹配且距离低于阈值时,函数才返回一个有效的字符。需要花些时间来确定可配置的阈值ocrMaxDist。小的值会导致拒绝实际正确识别的值,并在捕获的数据中造成更长的差距。相反,如果数值太高,结果会有很多误差。对于本次的特定环境,作者发现使用值600000是最优的。

charKNearestOcr::recognize(

const cv::Mat&img){

charcres='?';

cv::Mat results,

neighborResponses,dists;

float result=_pModel->find_nearest(

prepareSample(img),2,

results,neighborResponses,dists);

if(0==

int(neighborResponses.at0,0)

-

neighborResponses.at0,1))

&&

dists.at0,0)

<

_config.getOcrMaxDist()){

cres='0'+(int)result;

}

returncres;

}

4 利用识别内容进行仪表数字化管理

经终端设备识别分析后的仪表读数通过MQTT协议发送到云端的服务器,云端提供管理员使用的管理平台,通过管理平台可以检查、管理接入平台的所有仪表,分析仪表历史数值,并可设置阈值,平台将在仪表读数超出阈值后向仪表所绑定的管理员进行多管道的通知,如:App推送通知、短信通知、电话呼叫通知。由此组成功能完整的数字仪表远程监控系统。

5 系统应用相关验证与结果

基于KNN算法的仪表实时监控边缘平台的实物以及部署场景如图2所示。其中,摄像头以及补光灯实时采集照片,通过树莓派微型计算系统实时向云端传输图像。在云服务器端利用OpenCV集成的算法对图像中的数字进行识别、切割、提取。训练KNearestOcr模型,利用KNN算法进行数字的识别。

图2 实时监控边缘平台的实物及部署场景

综上所述,该方法有效解决了部分旧仪表盘无法就地更换新型数字仪表盘的问题,实现了对旧仪表盘的数字化、智能化监控。通过此系统的设计与实现,验证了利用摄像头采集数字图像进行分析、监控、统计、报警是具有可行性的。该系统具有较好的推广价值,其实现成本较低,但结果识别的性能较高,经过对KNN分类模型的简单重新训练,即可以方便地移植到不同现实场景下的各类旧式仪表系统所在的工作场所。

猜你喜欢

仪表灰度边缘
采用改进导重法的拓扑结构灰度单元过滤技术
浙江中控自动化仪表有限公司
浙江中控自动化仪表有限公司
Bp-MRI灰度直方图在鉴别移行带前列腺癌与良性前列腺增生中的应用价值
Arduino小车巡线程序的灰度阈值优化方案
一张图看懂边缘计算
奔驰E260车行驶过程中仪表灯熄灭
宝马745Li车制动灯常亮且组合仪表上多个故障灯点亮
基于热区增强的分段线性变换提高室间隔缺损超声图像可懂度研究
在边缘寻找自我