指针式仪表读数的实现过程可分成两部分,一是找到仪表在图像中的具体位置,二是刻度分析与计算指针位置所代表的读数。
对于第一部分,实现方法有两种,一是使用训练好的仪表模型,二是使用特征点匹配。第一种方法对环境的适应度更好,但需要大量图片去训练。第二种方法只需要一张模板图片,但是在复杂环境中可能效果没那么理想。根据实际使用场景,对于一个要检测的仪表,采集上百张图片进行标记,然后训练,不太现实。所以本文使用第二种方法。
对于第二部分,也有两种实现方法,一是使用训练好的姿态模型,二是识别刻度和指针,然后使用各种几何方法进行计算。同样的,要采集大量图片去标记和训练,也不太现实,所以本文使用第二种方法。
在本文中,所使用的方法皆为OpenCV本身具备,可查询具体实现算法。
一、模板图片的制作
要做特征点匹配,首先需要一张模板图片。可以对仪表进行一次正规化的拍摄(清晰,背景单调,无大量高光和阴影,无明显变形),然后进行简单的图像处理,作为模板图片。当然,这一过程也可以用程序去简化,只需要拍摄一张比较好的照片即可。
1、在拍摄照片上人工划定仪表所在矩形。
2、使用Grabcut算法,得到更准确的仪表范围。
3、进行形态学运算,处理细小孔洞和边刺。
4、生成最外围轮廓,得到最终的模板图片。
5、如图模板图拍摄有变形,可以根据刻度信息,进行圆拟合,然后对图片进行透视变换,尽量将圆盘校正为正圆。
原图如下图所示:

经过上述计算,得到的模板图如下图所示:

二、目标范围寻找
有了模板图片之后,就可以匹配模板图片和实际要检测图片的关键点,找出仪表的实际区域。
我们作为测试的图片如下图所示:

使用模板图片的关键点匹配情况如下图所示:

然后使用单应性投影算法,可得到模板图在待检测图中的对应区域。把该区域的图像提取出来,即为目标图像。实际过程中需要进行二值化和形态学运算,把毛刺和孔洞排除。由于测试图片的拍摄很可能变形,需要进行圆盘较正,否则在角度计算时偏差较大。

三、刻度与指针分析
我们用肉眼去看第二部分的结果图,读数大概是6.4。
分析刻度,第一步将图片转换成二值图。考虑到阴影和高光的影响,使用自适应二值化。得到如下结果:

然后检测图像中的直线,得到如下结果:

接着就是几何分析方法。
1、检测盘心。先假设盘心在图像中央,搜索出刻度,根据刻度拟合出圆,得到新的圆心。如果能够在图像中找到圆,可结合此信息对圆心进行进一步的校正。
2、搜索出刻度线条。刻度起点离盘心的距离基本是恒定的,根据这个信息可确定哪些线条是刻度。
3、搜索出指针线条。指针是长度比较长的线条,而且起点离盘心很近,根据这个信息确定哪些线条是刻度。
经过上面的计算,可得到如下结果:

刻度起点、刻度终点、指针与圆盘的交点,根据上面三个信息,可计算出指针划过了量程的比例。如上图,经过测试,计算出来的结果是0.237,乘以量程25,是5.925。这跟我们的目标6.4偏差还是比较大的。这是由于盘面发生变形,并不是准确的正圆导致的。
优化的方法是,不使用整个盘面刻度计算比例,使用临近的刻度去做计算。可以根据刻度长度,使用K-Means算法,得出最长一组刻度。然后根据常见划分份数,猜测这组刻度所对应的比例。在上图中,指针所指位置在5和10之间,以此两个刻度重新计算比例,得到的结果是0.256,乘以量程25,是6.4,跟肉眼所看结果一般无二。