• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Matlab神经网络验证码识别 - MrCharles在cnblogs

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Matlab神经网络验证码识别

本文,将会简述如何利用Matlab的强大功能,调用神经网络处理验证码的识别问题。 
预备知识,Matlab基础编程,神经网络基础。 
可以先看下:

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的离散点
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我们看看目标的图片: 

有很多随机的像素点干扰,我们需要将这些像素点去除,然后进行图像切割。

切割图片实际上很简单,就是对图片中每行每列进行统计,然后将形成的波形进行扫描,每个从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 = i;
                sumy = sumy + 1;
                if isshow;
                    hold on;
                    plot([0 imgsize(1,2)], [cvb cvb],\'r--\');
                    plot([0 imgsize(1,2)], [cve cve], \'r--\');
                end
            end
        end
    end

    y = {}
    sumy = 0;
    for i = 1 : imgsize(1, 2);
        if varray(i) > va;
            if isanum == false;
                isanum = true;
                ctb = i;
            end
        else
            if isanum;
                isanum = false;
                cte = i;
                sumy = sumy + 1;
                if isshow;
                    hold on;
                    plot([ctb ctb], [0 imgsize(1,1)],\'r--\');
                    plot([cte cte], [0 imgsize(1,1)],\'r--\');
                end
                t = I2(cvb:cve, ctb:cte);
                y{sumy} = t;
            end
        end
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

我们这个函数实现了对图片的预处理工作,成功的将大部分图片分割成了小图片,放到返回的元胞数组中,但这还有一个重要的问题,就是切割后的图片并不等大小。

并且,我们为了让这些图片能够方便的进行训练,希望将他们归好类别,方便标记。将图像等大小十分简单,只需要将图像的最大的长和宽找到,然后对矩阵进行扩展,多余的位置补0即可。

%% 将数字分类放置
for i = 1 : length(imgs_name)
    img_name = imgs_name{i};
    imgs = cutting(imread([\'train/\',img_name,\'.jpg\']), false);
    if (length(imgs) == length(img_name))
        imgs_num_size = length(img_name);
        for j = 1 : imgs_num_size
            tmp_num = str2num(img_name(j)) + 1;
            imgs_sample_num(tmp_num) = imgs_sample_num(tmp_num) + 1;
            imgs_sample{tmp_num, imgs_sample_num(tmp_num)} = imgs{j};
            tmp_size = size(imgs{j});
        end
    end
end

max_size = [16 16];

%% 归一化所有样本,使其等大小
for i = 1 : 10
    for j = 1 : imgs_sample_num(i)
        temp = zeros(max_size);
        imgs_size = size(imgs_sample{i, j});
        temp(1:imgs_size(1,1), 1:imgs_size(1,2)) = imgs_sample{i, j};
        imgs_sample{i, j} = temp;
        % figure;
        % imshow(temp);
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

  • 鲜花

    握手

    雷人

    路过

    鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
使用matlab处理图像的基础知识发布时间:2022-07-18
下一篇:
matlab 图片批量读取发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap