图像验证码识别(八)——字符归一化

前面提到了将验证码上的字符分割成一个单独的字符图片而且保存,可是扣下来的字符串可能会有倾斜的现象,由于如今不少网页验证码为了防止破解都对字符进行了必定的扭曲和旋转,即便是同一个网站的验证码,每一个相同的字符颇有可能都是不同的,因此为了提升识别的正确率,在这里最好能让每次进行训练的字符可以保持同一个角度。因此首先须要作的就是旋转倾斜。

1、旋转倾斜ide

旋转倾斜的目的就是要提升识别的正确率,若是字符‘A’的模板是标准的,让一个横着的‘A’去训练确定得不到正确的结果。不过怎么旋转呢?想要将每一个字符都旋转到印刷体的角度那是很难的,也是没必要要的,在这里采用的思想就是每次都旋转成为“最瘦的”。每次分割出来一个字符不论是横着的仍是竖着的,均可以回到“最瘦”的角度。具体作法就是利用OpenCV的旋转函数.函数

[cpp]  view plain  copy
  1. cv::Mat M = cv::getRotationMatrix2D(center, angle, scale);  

getRotationMatrix2D这个函数所作的就是计算旋转矩阵,熟悉计算机图形学的都知道,图形在作各类变换的时候都是在原有的矩阵上乘以变换矩阵。这里center是CvPoint2D32f类型的结构体,其有两个float类型的变量分别表示要旋转的图像的宽和高,angle就是要旋转的角度,scale是旋转后的缩放系数。获得变换矩阵以后就能够进行旋转操做了

[cpp]  view plain  copy
  1. warpAffine(m_Mat,rotate_mat, M,cvSize(getWidth(),getHeight()),INTER_LINEAR,BORDER_CONSTANT,cvScalar(WHITE) );  

warpAffine函数就是进行旋转操做。

鉴于大部分验证码的旋转都不是特别夸张,因此处理时我让字符从旋转的范围定在顺时针-15度到15度,每次旋转一度,而后计算最左边第一个黑色像素到最右边第一个黑色像素的距离,取距离最小的角度最终让字符旋转那个角度。测试


能够看到分割出来的字符和原始的仍是有点不太同样,因为测试用的验证码倾斜的并不明显,因此这里调整的也不是很明显。网站

2、归一化spa

因为验证码大小不一,图片上又大量背景像素,所以在进行最后一步识别的时候,还应该将验证码的大小缩放到固定的大小。在这里我是先获得字符像素的最小外包矩形,这样能够先把没有用的白色背景像素干扰取消掉。接下来就是将全部的字符都统一缩放到16*16的大小,这样最终获得的通过预处理的标准字符就能够开始训练识别了。.net