图像识别技术——验证码识别
[1]一、数字图像处理基础
一幅图像可以定义为一个二维数组f(x,y),这里x,y是空间坐标,而在任何一对空间坐标(x,y)上的幅值f称为该点图像的强度或灰度。当x,y和幅值f为有限的、离散的数值时,称该图像为数字图像。
自然界呈现在人眼中的图像是连续的模拟信号,在计算机处理前,必须用图像传感器把光信号转换为表示亮度的电信号,再通过取样和量化得到一副数字图像。取样是对图像在坐标上进行离散化的过程,每一个取样点称为一个像素。量化是对图像灰度上的离散化过程。取样后将得到M*N个像素,每个像素量化得到一个灰度值L,以L表示灰度值的允许取值范围,则数字图像存储需要的比特数b可以表示为:
图像的灰度值取值范围被称为图像的动态范围。把占有灰度级全部有效段的图像称为高动态范围图像,高动态范围图像有较高的对比度。相反,地动态范围的图像看上去是冲淡了的灰暗格调。
二、图像的预处理:
主要是对图像进行灰度化、二值化、抑噪(滤波)等技术。
1、图像的灰度化
RGB系统中一个颜色值由3个分量组成,这样的图像称为彩色图像,RGB系统称为颜色空间模型。常见的颜色空间模型还有HSI、CMYK等。如果一幅图像的颜色空间是一维的(一个颜色值只有一个颜色分量),则这幅图像就是一副灰度图。在位图图像中,一般以R=G=B来显示灰度图像。
图 1 原始图片
常用的灰度化方法有以下三种:
其中,公式(2.1)的方法来源于I色彩空间中I分量的计算公式,公式(2.2)来源于NTSC色彩空间中Y分量的计算公式。公式(2.3)是基于采用保留最小亮度(黑色)的方法。
图 2 用公式2.2灰度化后的图片
RGB彩色图像可以看成是由3副单色的灰度图像构成的,可以直接取RGB通道中的任一个通道得到灰度化图像,如,前提是图像中目标像素的亮度信息主要分布在B通道上,否则灰度化结果将是亮度信息的大量丢失。灰度图像又叫亮度图像,由归一化的取值表示亮度,最大取值表示白色,最小取值表示黑色。
以P(x,y)表示图像中一个点,x、y分别是图像的横坐标和纵坐标,R(x,y)表示R通道的颜色分量,G(x,y)表示G通道的颜色分量,B(x,y)表示B通道的颜色分量。点P(x,y)的亮度值用L(x,y)表示。彩色图像的亮度没有严格的定义和计算公式,一般用公式(2.1)来计算,我们记作L1(x,y)。同样的用公式(2.2)计算的亮度值记作L2(x,y),用公式(2.3)计算的亮度值记作L3(x,y)。可以证明:
公式(2.1)取RGB通道的平均值,得到的图像相对比较柔和,同时也缩小了目标和背景的平均亮度差,不利于后续的阀值处理。公式(2.2)考虑了人眼对绿色的适应度最强,蓝色次之,红色最差。在处理绿色调和蓝色调的验证码图像时,公式(2.2)的效果令人满意,但在处理红色调的图像时,因为公式中红色的权值很小,灰度化后目标像素和背景像素的亮度差值被严重缩小,效果还不如公式(2.1)。公式(2.3)基于一个前提,那就是有限保留目标像素的亮度信息,利于后续的阀值分割。
需要说明的是,要根据图像灰度化的目的不同,原图色彩特征的不同,选择合适的灰度化方法。
2、图像的二值化
一般24位RGB图像的灰度图是8位256个灰度级的,如果把这个灰度级减少到1位2个灰度级,就得到一副二值图,二值图像中的数据全部是0或1。
图 3 二值化后图像
三、字符分割:
字符分割包括从验证码图像中分割出字符区域和把字符区域划分成单个字符两个部分。如果采用统计特征匹配以及神经网络法识别,必须要先分割出单个的字符。简单的分割方法包括等距分割、积分投影分割、交叉点分割、求连通区等。其中,粘连字符的分割是一个难点,复杂的粘连情况下分割比较困难,是一个硬人工智能问题。
四、字符识别
字符识别就是把处理后的图片还原回字符文本的过程。可以分成基于字符分割的识别(包括采用神经网络、SVM、各种统计距离的识别法)和模板匹配法识别。
字符识别的常用做法是:先获取该字符的特征码,然后使用各种分类算法将对该特征码进行分类,将其打上相应的类标签。分类模型的训练,是对字符库中的每个字符进行特征化处理,得到每个字符的特征码,该字符的标签就是该字符本身,利用特征码加上字符的标签对字符库中的所有数据进行训练,得到相应的分类模型。
当然,得到了待识别字符的特征码后,也可以使用相似性度量和字符库中的字符的特征码进行比较,将该字符识别为与其特征码相似性最高的字符。
现在的问题就集中在如何获取字符的特征码。文章[2]中介绍了一种简单的获取特征码的方法:
对于二值化后的图像进行分割,分割出来的图像是一个个的字符,如下图所示:
图 4 对图像进行分割,确定每个图像的边界
在每个字符的边界内,按行(或列)扫描该图片,检测其中的每个像素点,如果像素为白色则为0,如果像素为黑色则为1,将这些0和1连起来组成的字符串就构成了该字符图片的特征码。
参考文献:
[1] 《带干扰的验证码识别研究》 吕刚 浙江工业大学硕士学位论文
[2] 《C#中识别验证码》 http://www.360doc.com/content/11/0117/16/4304924_87149528.shtml
[3] 一些常用的代码 http://www.sharejs.com/codes/csharp/5611
[4] C#验证码识别实践 http://blog.csdn.net/stevenkylelee/article/details/8263890