博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
刻度尺识别项目
阅读量:2051 次
发布时间:2019-04-28

本文共 2771 字,大约阅读时间需要 9 分钟。

刻度尺识别项目

简介

好久不见了,我看了一下我最近的博客到现在已经3个月时间没更新了。这是因为我最近都在忙毕业设计,所以一直没有时间更新。我这三个月的收获还是丰富的,最近会慢慢通过博客和大家分享。现在马上水上一篇吧。如果大家有看过我的这一篇博客的话,可能会好奇我最后的gif demo是怎么完成的。那个其实是我大三的一个srp项目。现在我就介绍一下它。

实现效果

需求不用啰嗦,直接看看效果即可,其实我也是做得比较简单,还有很多可以改进的地方。

1. demo1

在这里插入图片描述

2. demo2

在这里插入图片描述

实现流程

我完成上述的基本功能主要包含以下即可步骤。

  • 刻度尺的标定
  • 数字位置的检测和分割
  • 数字识别
  • 结果可视化
  • 部署到web

其中,✔的是必须的,而其余的是个性化的可选项。

实现原理

刻度尺的标定

刻度尺的标定是非常重要的一环。考虑到刻度尺位置是相对固定的,因此通过简单的人工标定过程就可以知道指针、刻度和数字的相对位置。当然也可以用如今非常厉害的基于深度学习的目标检测技术,大家可以自行发挥。

下面是标定的示意图:

在这里插入图片描述
从demo中可以看到整个读数系统可以象形地作成上图。需要关注的是:1)指针的位置;2)刻度尺读数的位置,我们不妨假定我们可以框出数字,那么框框的中心坐标就是读数的位置;3)读数到指针所指位置的距离;首先数字的起始位置都是有一条粗黑实线,然后得到的实线到指针的像素距离需要转换成实际的刻度距离。

指针位置标定

指针位置标定非常简单,因为其一般呈现等腰三角形,我们把它的边缘绘制出来,然后求其角平分线,就得到指针的指向。

在这里插入图片描述

我的标定程序需要从上往下按顺序指定三个红点,指定后自动连接绿线(指针边缘),然后自动生成其角平分线(蓝线),整个程序是交互式的,执行过程有提示信息,最终标定文件会自动保存,下次使用时加载标定文件即可。

读数位置标定

假定我们得到离指针位置最近的数字的中心像素坐标,但我们还需要知道这个像素坐标离它低下那条粗黑实线有多远。在这里,我假定这个中心坐标的y坐标 y c y_c yc和粗实线所在的y坐标 y b y_b yb存在二次函数的关系,这其实并不严格,只是感觉。所以有:

y b = a y c 2 + b y c + c y_b = ay_c^2 + by_c + c yb=ayc2+byc+c
这样,我们对多张图片的多个位置标定出 ( y c , y b ) (y_c, y_b) (yc,yb),我们就可以拟合出系数。

在这里插入图片描述

程序需要人工框出所有数字,会自动返回红色中心点;然后人工点出黑色实线(蓝点),程序采集足够多组样本之后就可以拟合,生成拟合曲线:

在这里插入图片描述

这个拟合关系还是不错的。

刻度线标定

我们现在可以推出起始的粗实线的坐标,我们还需要知道:1)指针指向和刻度尺的交点(结束坐标);2)像素距离到刻度尺距离的转换。首先,我们先标定刻度,如下所示:

在这里插入图片描述
按从下到上或相反的顺序点出刻度,而且尽量使点排成大致的直线,这是因为在采集多张图以后,程序会把这个直线拟合出来。拟合出的刻度直线,和最开始标定出来的指针的角平分线求交点,得到的y轴方向坐标就是结束坐标。

有开始坐标和结束坐标,就还剩下距离转换的问题了。在这里我也是在此假设,任一y轴坐标 y 0 y_0 y0,它的上一个刻度和下一个刻度的像素增量 δ y ↑ , δ y ↓ \delta y_{\uparrow}, \delta y_{\downarrow} δy,δy也存在二次函数的关系,即:

δ y ↑ = a ↑ y 0 2 + b ↑ y 0 + c ↑ δ y ↓ = a ↓ y 0 2 + b ↓ y 0 + c ↓ \delta y_{\uparrow} = a_{\uparrow}y_0^2 + b_{\uparrow}y_0 + c_{\uparrow} \\ \delta y_{\downarrow} = a_{\downarrow}y_0^2 + b_{\downarrow}y_0 + c_{\downarrow} \\ δy=ay02+by0+cδy=ay02+by0+c
和上面一样,采集足够的样本之后拟合,拟合效果如下:
在这里插入图片描述
可见效果还是可以的。拟合之后,假定我们起始坐标和结束坐标为 y s , y e y_s,y_e ys,ye。那么我们可以求出 y s y_s ys下一个刻度的像素坐标:
y s , 1 = y s + δ y s = a ↓ y s 2 + ( b ↓ + 1 ) y s + c ↓ y_{s,1} = y_s + \delta y_s = a_{\downarrow}y_s^2 + (b_{\downarrow}+1)y_s + c_{\downarrow} ys,1=ys+δys=ays2+(b+1)ys+c
不断重复上述过程,我们可以求出毫米级读数 y s , k ≤ y e ≤ y s , k + 1 y_{s,k} \le y_e \le y_{s,k+1} ys,kyeys,k+1。如果需要取两位小数,那么在这个区间等比例取就可以了。

数字检测

数字检测使用我之前的博客提到的,里面详细介绍了如何配置和使用,模型输入原图片,返回数字的中心坐标。

数字分割

本人数字分割使用的同样是比较传统的方法。首先,将图像转化为灰度图,然后使用OTSU方法对图片进行二值化。最后,对二值化的图片使用,这个算法可以有效地抠出连通域。这样的话我们就得到单个分割的数字了。

mser = cv2.MSER_create(_min_area=min_area, _max_area=max_area)img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)		# 转为灰度图_, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)	# 二值化_, boxes = self.mser.detectRegions(img)		# MSER分割

数字识别

容易发现,我们需要识别的数字都是印刷体的。所以,数据集只需要印刷体数字0~9即可,你可能会觉得找数据集是件麻烦事,但印刷体数据集是可以用opencv生成的。这一部分我参考了开源项目,它非常详细地给出了生成数据集和数据增强的方案,并且训练了一个简单的CNN实现了高效的数字识别。

web部署

本人使用flask实现,但使用本地电脑作为服务器部署后只能供局域网访问,如果需要让国内的朋友都能访问的话,可以申请一个公网的服务器,比如阿里云等,然后把代码放到上面运行,别人就可以访问了。

附录

完整代码见:

转载地址:http://eoklf.baihongyu.com/

你可能感兴趣的文章
div标签布局的使用
查看>>
HTML中表格的使用
查看>>
(模板 重要)Tarjan算法解决LCA问题(PAT 1151 LCA in a Binary Tree)
查看>>
(PAT 1154) Vertex Coloring (图的广度优先遍历)
查看>>
(PAT 1115) Counting Nodes in a BST (二叉查找树-统计指定层元素个数)
查看>>
(PAT 1143) Lowest Common Ancestor (二叉查找树的LCA)
查看>>
(PAT 1061) Dating (字符串处理)
查看>>
(PAT 1118) Birds in Forest (并查集)
查看>>
数据结构 拓扑排序
查看>>
(PAT 1040) Longest Symmetric String (DP-最长回文子串)
查看>>
(PAT 1145) Hashing - Average Search Time (哈希表冲突处理)
查看>>
(1129) Recommendation System 排序
查看>>
PAT1090 Highest Price in Supply Chain 树DFS
查看>>
(PAT 1096) Consecutive Factors (质因子分解)
查看>>
(PAT 1019) General Palindromic Number (进制转换)
查看>>
(PAT 1073) Scientific Notation (字符串模拟题)
查看>>
(PAT 1080) Graduate Admission (排序)
查看>>
Play on Words UVA - 10129 (欧拉路径)
查看>>
mininet+floodlight搭建sdn环境并创建简答topo
查看>>
【UML】《Theach yourself uml in 24hours》——hour2&hour3
查看>>