HTML5技术

字符型图片验证码识别完整过程及Python实现 - 一点一滴的Beer

字号+ 作者:H5之家 来源:H5之家 2016-07-16 16:00 我要评论( )

字符型图片验证码识别完整过程及Python实现 1摘要 验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的防火墙功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越来越严峻。本文介绍了一套字符验证码识别的完整流程,对于验证码安

字符型图片验证码识别完整过程及Python实现

1   摘要

验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的 防火墙 功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越来越严峻。本文介绍了一套字符验证码识别的完整流程,对于验证码安全和OCR识别技术都有一定的借鉴意义。

2   关键词

关键词:安全,字符图片,验证码识别,OCR,Python,SVM,PIL

3   免责声明

本文研究所用素材来自于某旧Web框架的网站 完全对外公开 的公共图片资源。

本文只做了该网站对外公开的公共图片资源进行了爬取, 并未越权 做任何多余操作。

本文在书写相关报告的时候已经 隐去 漏洞网站的身份信息。

本文作者 已经通知 网站相关人员此系统漏洞,并积极向新系统转移。

本报告的主要目的也仅是用于 OCR交流学习 和引起大家对 验证安全的警觉 。

4   引言

关于验证码的非技术部分的介绍,可以参考以前写的一篇科普类的文章:

互联网安全防火墙(1)--网络验证码的科普

里面对验证码的种类,使用场景,作用,主要的识别技术等等进行了讲解,然而并没有涉及到任何技术内容。本章内容则作为它的 技术补充 来给出相应的识别的解决方案,让读者对验证码的功能及安全性问题有更深刻的认识。

5   基本工具

要达到本文的目的,只需要简单的编程知识即可,因为现在的机器学习领域的蓬勃发展,已经有很多封装好的开源解决方案来进行机器学习。普通程序员已经不需要了解复杂的数学原理,即可以实现对这些工具的应用了。

主要开发环境:

  • python3.5

    python SDK版本

  • PIL

    图片处理库

  • libsvm

    开源的svm机器学习库

  • 关于环境的安装,不是本文的重点,故略去。

    6   基本流程

    一般情况下,对于字符型验证码的识别流程如下:

    7   素材准备

    7.1   素材选择

    由于本文是以初级的学习研究目的为主,要求 “有代表性,但又不会太难” ,所以就直接在网上找个比较有代表性的简单的字符型验证码(感觉像在找漏洞一样)。

    最后在一个比较旧的网站(估计是几十年前的网站框架)找到了这个验证码图片。

    原始图:

    放大清晰图:

    此图片能满足要求,仔细观察其具有如下特点。

    有利识别的特点 :

    以上就是本文所说的此验证码简单的重要原因,后续代码实现中会用到

    不利识别的特点 :

  • 图片背景有干扰噪点
  • 这虽然是不利特点,但是这个干扰门槛太低,只需要简单的方法就可以除去

    7.2   素材获取

    由于在做训练的时候,需要大量的素材,所以不可能用手工的方式一张张在浏览器中保存,故建议写个自动化下载的程序。

    主要步骤如下:

    这些都是一些IT基本技能,本文就不再详细展开了。

    关于网络请求和文件保存的代码,如下:

    def downloads_pic(**kwargs): pic_name = kwargs.get(, None) url = res = requests.get(url, stream=True) with open(pic_path + pic_name+, ) as f: for chunk in res.iter_content(chunk_size=1024): if chunk: # filter out keep-alive new chunks f.write(chunk) f.flush() f.close()

    循环执行N次,即可保存N张验证素材了。

    下面是收集的几十张素材库保存到本地文件的效果图:

    8   图片预处理

    虽然目前的机器学习算法已经相当先进了,但是为了减少后面训练时的复杂度,同时增加识别率,很有必要对图片进行预处理,使其对机器识别更友好。

    针对以上原始素材的处理步骤如下:

    8.1   二值化图片

    主要步骤如下:

  • 将RGB彩图转为灰度图
  • 将灰度图按照设定阈值转化为二值图
  • image = Image.open(img_path) imgry = image.convert() # 转化为灰度图 table = get_bin_table() out = imgry.point(table, )

    由PIL转化后变成二值图片:0表示黑色,1表示白色。二值化后带噪点的 6937 的像素点输出后如下图:

    1111000111111000111111100001111100000011 1110111011110111011111011110111100110111 1001110011110111101011011010101101110111 1101111111110110101111110101111111101111 1101000111110111001111110011111111101111 1100111011111000001111111001011111011111 1101110001111111101011010110111111011111 1101111011111111101111011110111111011111 1101111011110111001111011110111111011100 1110000111111000011101100001110111011111

    如果你是近视眼,然后离屏幕远一点,可以隐约看到 6937 的骨架了。

    8.2   去除噪点

    在转化为二值图片后,就需要清除噪点。本文选择的素材比较简单,大部分噪点也是最简单的那种 孤立点,所以可以通过检测这些孤立点就能移除大量的噪点。

    关于如何去除更复杂的噪点甚至干扰线和色块,有比较成熟的算法: 洪水填充法 Flood Fill ,后面有兴趣的时间可以继续研究一下。

    本文为了问题简单化,干脆就用一种简单的自己想的 简单办法 来解决掉这个问题:

    下面将详细介绍关于具体的算法原理。

    将所有的像素点如下图分成三大类

    种类点示意图如下:

     

    其中:

    当然,由于基准点在计算区域的方向不同,A类点和B类点还会有细分:

    然后这些细分点将成为后续坐标获取的准则。

    主要算法的python实现如下:

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 浓缩的才是精华:浅析GIF格式图片的存储和压缩 - 腾讯云技术社区

      浓缩的才是精华:浅析GIF格式图片的存储和压缩 - 腾讯云技术社区

      2017-04-07 15:08

    • 前端识别验证码思路分析 - 腾讯云技术社区

      前端识别验证码思路分析 - 腾讯云技术社区

      2017-03-30 10:00

    • HTML5本地图片裁剪并上传 - QxQstar

      HTML5本地图片裁剪并上传 - QxQstar

      2017-03-25 14:00

    • 图片展示丨标签 - xiaohaimiansBlog

      图片展示丨标签 - xiaohaimiansBlog

      2017-03-08 17:00

    网友点评
    r