本文,将会简述如何利用Matlab的强大功能,调用神经网络处理验证码的识别问题。
预备知识,Matlab基础编程,神经网络基础。
可以先看下:
验证码识别原理
Matlab对图像读入处理,去掉噪声点和较浅的点,进行二值化,将图像转变为0/1矩阵,这样就完成了预处理。
然后要对图像进行切割,取到每个数字的小图片位置,将其缩放至等大小,方便神经网络进一步处理。
最后将图片转成神经网络能够识别的格式,例如BP网络,则将其转为行向量,深卷积网络,则将其转为矩阵即可。
识别预处理
Matlab对验证码的识别是基于神经网络的,但预处理工作还是占了整体工作的大半,将数据整理好并处理成对应可用的格式,问题就简单了很多。
Matlab的一大缺陷是不注重数据结构,其结构体无比难用,所以我们这里将尽可能使用矩阵进行处理,而参数较多时,我们也只是简单的将其放入到元胞数组中,不优雅之处,敬请见谅。
首先介绍一下matlab的图像基本处理函数:
img = imread('path') # 返回一个图像的矩阵,其每个元素的值,包含rgb三个通道的数据。
imshow(img) # 显示图像
imgGray = rgb2gray(img) # 转为灰度图像
thresh = graythresh(imgGray); % 自动确定二值化阀值
BW = 1 - im2bw(imgGray,thresh); % 二值化,且取反,黑的部分是0,白的部分是1,
I2 = bwareaopen(BW, 8, 8); % 去除连通分量中小于10的离散点
我们看看目标的图片:
有很多随机的像素点干扰,我们需要将这些像素点去除,然后进行图像切割。
切割图片实际上很简单,就是对图片中每行每列进行统计,然后将形成的波形进行扫描,每个从0上升又下降到0的区域,就是一个字符。
切割后的图片:
下面我们来写一个完整的函数分割器函数,为了检测正确性,我们这里提供了isshow标记,如果设置为true,将会打印中间的调试信息。
% 图片分割器
function y = cutting(img, isshow)
if nargin < 2; isshow = false; end
if isshow;
imshow(img); % 显示彩色图像
end
imgGray = rgb2gray(img); % 转为灰度图像
thresh = graythresh(imgGray); % 自动确定二值化阀值 (这个不太好,有时会整体删除一个字)
BW = 1 - im2bw(imgGray,thresh); % 二值化
I2 = bwareaopen(BW, 8, 8); % 去除连通分量中小于10的离散点
varray = sum(I2);
imgsize = size(I2);
if isshow
figure; % 打开一个新的窗口显示灰度图像
imshow(imgGray); % 显示转化后的灰度图像
harray = sum(I2');
x1 = 1 : imgsize(1, 1);
x2 = 1 : imgsize(1, 2);
figure; % 打开一个新的窗口显示分割图
plot(x1, harray, 'r+-', x2, varray, 'y*-');
figure; % 打开一个新的窗口显示灰度图像
imshow(I2); % 显示转化后的灰度图像
end
va = mean(varray); % 计算平均值
harray = sum(I2');
vb = mean(harray);
%% matlab 设计的实在太烂!真是我有史以来见过的最烂的语言
%% 函数只有搅成一坨的情况下才能正确运行
%% 他们根部不知道如何用闭包,以及合理的封装对象
isanum = false;
sumy = 0;
for i = 1 : imgsize(1, 1)
if harray(i) > vb;
if isanum == false;
isanum = true;
cvb = i;
end
else
if isanum;
isanum = false;
cve