《我的眼睛--图灵识别》第十章:实战演练:文字类识别
《我的眼睛–图灵识别》第十章:实战演练:文字类识别
1、标准数字
标准数字(Standard Numbers)是指10个数字使用的都是同属一种字体,它们的数字没有发生变形、没有扭曲、没有错位、存在有些变色但影响不大,字与字之间的间隔距离一样,同在一个水平对齐位置上,是非常标准且正规排列的验证图形码。
标准数字
当你看到了这个验证图形码时,应该就能很清楚的明白前面所描述的样子了。那么,要识别这个验证图形码就需要以下的几个步骤:
识别步骤
第1步,特征分析
开始时一定要收集稍微多一些的验证图形码图片,且其中必须包含了所有的数字,然后从中进行比较分析,看看有什么特征对识别是有用处的全部把它找出来。
我通常的做法就是把一堆的验证图形码放在一起整齐的排列,使用的是Photoshop工具把它们拼到一张图中(详情查阅:02开发环境和工具->Photoshop7),没有玩过Photoshop图像处理工具的也可以用其他同类软件来代替。
整齐排列
这样排列在一起就能够很容易的进行查看与分析。经过了眼睛对图像的获取与脑袋对图像数据计算的相互理解沟通后,现在来看一看通过分析得到的3个明显的识别特征:
(特征1)四位数,存在0到9的十个数字
(特征2)数字没有发生变形,位置固定且间距都是相等的
(特征3)数字颜色突出区分于背景(二值化),没有受到干扰影响
第2步,滤镜处理
像素获取
使用“鱼鱼抓点抓色”工具在屏幕上获取验证图形码的截图范围左上角坐标和右下角坐标。(详情查阅:02开发环境和工具->鱼鱼抓点抓色)
获取截图范围坐标
感谢微软提供了很多很方便的API函数,这里使用微软提供的截取屏幕图片API(Application Programming Interface:应用程序编程接口)的BitBlt和GetDIBits等函数。
之后,根据验证图形码的屏幕截图范围坐标进行图像数据的像素获取。(详情查阅:04基础:图片识别->像素获取)
(预览)图像数据
二值化
利用前面分析到的第3个特征“数字颜色突出明显区分于背景,没有受到干扰影响”进行二值化处理。只要根据颜色RGB分量值的平均值判断(阈值判断:大于等于140时为黑色,否则为白色),就能很容易得到与背景区分的二值化字符图像。(详情查阅:07预处理:图像滤镜->彩色图像滤镜->二值化)
二值化图像
当颜色RGB分量值的总和除以3,大于等于预设置的阈值140时,等于黑色(16进制:000000,10进制:0),否则等于白色(16进制:FFFFFF,10进制:16777215),即为二值化。种类不同的验证图形码,它们在二值化算法中的阈值大小设置也都是不一样的,根据实际情况再进行设置阈值的大小。
接下来要简单的提一下什么是颜色?
所谓颜色,其实就是由红(Red),绿(Green)和蓝(Blue)三原色组合而成的。
(RGB)三原色
颜色三原色分量简称:红色(R),绿色(G),蓝色(B)。取值范围都是:0~255,比如:(R=0,G=0,B=0)组合出来的就是黑色,(R=255,G=255,B=255)组合出来的就是白色。
第3步,切割图像
字符切割
利用前面分析到的第2个特征“数字没有发生变形,位置固定且间距都是相等的”进行字符的切割。得到起点位置坐标、数字宽高、字间距和文字数量,使用“切割_固定位置()”函数的切割方法进行切割,最终得到10个数字独立的字符图像数据。(详情查阅:08训练:图像字符切割->固定位置)
固定位置切割
(预览)10个字符图像数据
生成识别库
识别字库数据使用二进制的数字0和1来表示(也可以用其他字符来代替,如:a和b,但是这样体现黑白色就不直观了),黑色的就用数字0来代表,白色的用数字1来代表,生成出来的点阵识别字库就是一串看起来很像二进制码的字符串。(详情查阅:09训练:制作识别字库->生成字库)
完成点阵识别字库之后,需要对其加入该点阵识别字库所对应的文字、宽和高的数据进行保存到“识别库.lib”文件中。(详情查阅:09训练:制作识别字库->存储结构)
(记事本)识别库内容
第4步,文字识别
加载识别库
读取识别字库“识别库.lib”文件进行数据内容的加载,解析加载的数据内容并保存到变量“字库”的一维数组结构体中,这样“字库”中就会存储有10个数字的文字,宽,高和点阵的数据内容。(详情查阅:09训练:制作识别字库->使用字库)
“字库”一维数组
点阵比对
根据切割字符得到的字符图像数据与一维数组“字库”的数据内容第一个点阵识别字库的二进制数字开始进行一对一比较判断是否相等或不等,如果相等则会记录相等的数量,用于之后计算点数匹配的相似度。(详情查阅:06基础:验证图形码识别->什么是相似度)
(左:字符图像数据,右:点阵识别字库)一对一比较
直到完成该字符图像数据与所有字库的点阵比对,算出该字符图像数据分别对应字库的相似度百分比,并对其相似度进行大小排序,得到该字符图像数据所对应的字库中相似度最高的文字。
字符图像数据
数字8的比对结果
重复以上步骤,对其它的3个字符图像数据继续进行点阵比对,最终完成验证图形码上4位数字的识别。
数字2的比对结果
数字0的比对结果
数字1的比对结果
VB6代码:
调用例子:
Dim 图像数据() As Byte
Dim 起点X As Long, 起点Y As Long, 字宽 As Long, 字高 As Long, 字间距 As Long, 字数 As Long
Dim 切割字符() As 切割类型, 字库() As 字库类型
Dim 识别文字 As String, 文字 As String, i As Long
'1.获取
Call 来源_获取图片像素("C:\8201.bmp", 图像数据)
'2.滤镜
Call 滤镜_二值化(图像数据, 140, 图像数据)
起点X = 6
起点Y = 4
字宽 = 7
字高 = 11
字间距 = 13
字数 = 4
'3.切割
Call 切割_固定位置(图像数据, 起点X, 起点Y, 字宽, 字高, 字间距, 字数, 切割字符)
'4.字库
Call 字库_读取识别字库("C:\识别库.lib", 字库)
'5.识别
文字 = ""
For i = 0 To 字数 - 1
Call 点阵比对(切割字符(i).点阵, 切割字符(i).宽, 切割字符(i).高, 字库, 识别文字)
文字 = 文字 & 识别文字
Next
MsgBox 文字
封装函数:
Public Type 识别类型
相似度 As Long
'百分比 As Long
文字 As String
End Type
Public Sub 点阵比对(图像点阵 As String, 字宽 As Long, 字高 As Long, 字库数据() As 字库类型, 返回识别文字 As String)
Dim w As Long, h As Long, 宽 As Long, 高 As Long, n As Long, m As Long
Dim 识别数据() As 识别类型, i As Long, 数量 As Long, 相似点 As Long
数量 = UBound(字库数据)
ReDim 识别数据(数量) As 识别类型
For i = 0 To 数量
宽 = 字库数据(i).宽
高 = 字库数据(i).高
识别数据(i).文字 = 字库数据(i).文字
n = 0
m = 0
相似点 = 0
For w = 0 To 宽
If w > 字宽 Then Exit For '为数据越界处理
For h = 0 To 高
If h > 字高 Then Exit For '为数据越界处理
If Mid(图像点阵, 1 + n, 1) = Mid(字库数据(i).点阵, 1 + m, 1) Then '一对一比较
相似点 = 相似点 + 1
End If
Next
n = n + 字高 - 1
m = m + 字高 - 1
Next
识别数据(i).相似度 = 相似点
'识别数据(i).百分比 = 相似点 / ((宽 + 1) * (高 + 1)) * 100
Next
Call 相似度排序(识别数据, 0, 数量)
返回识别文字 = 识别数据(数量).文字
End Sub
按键精灵2014脚本:
调用例子:
Call Plugin.TULING.Pixel_FromPicture("C:\8201.bmp")
Call Plugin.TULING.Filter_Binaryzation("140-255") //二值化
//显示获取的图像
Call Plugin.TULING.Pixel_Preview()
数量 = Plugin.TULING.Incise_FixedLocation(6, 4, 7, 11, 13, 4) //固定位置切割
数量 = Plugin.TULING.Lib_Load("C:\识别库.lib")
TracePrint Plugin.TULING.OCR()