背景介绍
本篇文章分享笔者经历的一个计算机视觉方向的项目的经历与经验。
项目客户为大型国企,内部有很多设备在监控管道是否在正常运行,其中最常见的是压力表。
客户希望为压力表做一层保护,用另一个设备监控压力表的读数,达到一定阈值报警处理。
压力表有很多种类型,本次项目只针对上述图片的一种特定类型,但为了考虑后期项目的兼容,最好能兼顾多种表型,等后期想把算法扩展更多地方的时候,就不用重头在来,只需要针对某种表型进行训练,而不用更改业务逻辑。
项目要求
项目要求:
- 通过固定摄像机按一定频率拍摄图片,发送给算法端,算法返回结果(内网)
- 通过手持特定平板,拍摄图片,直接识别结果(算法也需要部署在平板中,园区网络貌似受干扰,无法直接传输)
- 精度要求(误差范围不偏离压力表设备正确读数: 0.1%)
项目分析
场景难点:
- 固定摄像机的拍摄时间不确定,从早上到傍晚,受天气影响等,结果会受光线的影响
- 手持设备拍摄的时候,会有角度问题,需要考虑
- 手持设备拍摄,会有反光问题,会把人像照射进图片,需要考虑
算法实现
- 提取仪表盘
无论是手持摄像机,还是固定摄像机,拍照的范围都会大于仪表盘本身,此时可以通过 yolo算法进行检测,yolo 算法很成熟,训练起来无费力
- 圆检测:对仪表盘进行分割处理拟合圆
仪表盘读数其实不仅可以直接读数获取,另一种方法是通过两端终点,以及指针的位置,圆心位置,算出偏转度数,即可得出结果
因为单纯去读取数字以及小段的刻度非常复杂,而两端终点以及指针相对来说更明显,也更容易读取
常规的圆检测可以利用霍夫圆检测
但我们场景更加复杂,无法简单拟合
思考一下,如果能让图片更加简单,只包含两种类型,一种是圆盘刻度区域,一种是圆盘内部“无意义"区域,这样划分岂不美哉,
上网搜索下,发现其实是有这块的工作的,是视觉分割领域,其中做的比较好的模型叫 deeplab 语义分割
我们去网上搜索了下,甚至有人已经用 deeplab 对表盘做语义分割,我们使用之后效果还不错:
然后配合适当的 opencv 膨胀等图像处理算法,减少噪音,最终通过 opencv 里自带的圆拟合算法在最外层拟合圆以及两端的端点
圆检测出后即可得出圆心位置
- 指针检测以及方向判断
第一步的仪表盘识别的时候,同时也做指针的标记,即可得到指针的位置
但是一般利用 yolo 检测的矩形框是水平的,如果需要做 transfer,需要特定配置,并且也没有那么准确,
此时我们利用直线检测算法检测出指针的方向
- 计算角度