神经网络:识别一卡通网站验证码

less than 1 minute read

Published:

验证码识别原理

MATLAB 对图像读入处理,去掉噪声点和较浅的点,进行二值化,将图像转变为0/1矩阵。

然后要对图像进行切割,取到每个数字的小图片位置,将其缩放至等大小,方便神经网络进一步处理。

最后将图片转成神经网络能够识别的格式,例如 MATLAB 自带的神经网络 Toolbox,将其转为行向量即可。


上个学期写教服网脚本的时候,写过了对 JAccount 的验证码的识别。那时候柱子用的是TesseractOCR引擎,就算直接用,识别率也很高。那是因为 JAccount 的验证码十分“友好”,清晰易辨别,如图

我尝试直接把这个引擎套在一卡通网站的验证码上面,发现识别率太低,根本不能用。经过对比两个网站的验证码,发现一卡通网站的码比 JAccount 上的恶心多了。

  1. 整张图片非常小,每个数字只是用几十个像素黑点点出来的;
  2. 图片上的噪点很多,会干扰判断。如图

图片预处理

我先用Python写了个爬虫,在一卡通网站上爬了100张验证码图片。然后为了用50张作训练样本,人手把图片标注了名字。 随后的处理就是用把图片二值化,并且去除噪点。我采用去除噪点的办法就是去掉连通分量面积小于8的点。

img = imread(imgName);
img = imcrop(img,[2 2 36 15]); %去除验证码边框
imgGray = rgb2gray(img); %转成灰度图像
thresh = graythresh(imgGray); %自动确定二值化阈值
BW = 1 - im2bw(imgGray,thresh); %二值化取反
i2 = bwareaopen(BW,8,8); %去除连通分量面积小于8的点邻域选取8

最后一步就是切割图片。由于一卡通网站上的验证码数字位置相对固定,因此切割起来十分方便,只需要按固定位置切割即可,同时需要保证每个数字切出来的图片大小相同。

使用神经网络进行识别

预处理工作已经做好了,接下来的识别就很简单了。MATLAB 自带有4种神经网络的工具箱,我使用的是Neural Net Fitting工具箱。

组织训练数据

输入就是整个图像转1维向量,输出就是一个1×10的向量,分别表示得到的各个数字的概率。要得到识别的结果,就是找出其中最大的概率。

% 创建训练数据集
num=size(list,1);
%read image
for i = 3:num
    wordName = list(i).name;
    if(wordName(10:12)=='jpg')
        img = imread(wordName);
        word = str2num(wordName(1));
        imgSize = numel(img);
        input(i-2,:) = single(reshape(img',imgSize,1));
        output(i-2,:) = zeros(10,1);
        output(i-2,word+1) = single(1);
    end
end

直接使用工具箱进行训练。

实例测试

实际使用如图所示,只需要输入图片名字,便可返回识别结果。