文本验证码识别项目的总结

文本验证码识别项目的总结

    • 索引词条
    • 验证码识别的步骤
    • 数据获取
    • 预处理
      • *灰度化
      • *二值化
      • *去除噪声
    • 切割
      • *竖直投影切割
      • *连通域切割/CFS切割
      • *滴水算法切割
    • 生成数据集和测试集,以及识别验证码

毕业论文是要做这个方面的,最近把之前做的一些工作总结一下,这里只说具体思路,展示部分代码,为后面想要做文本验证码识别之类的朋友,提供思路和要检索的词条内容。如有错误,还请各位大佬们批评指正。

索引词条

如果想要快一点开始的,有关这个方向的一些关键词可以直接去搜索了解

  • 灰度化
  • 二值化
  • 全局阈值
  • OSTU阈值
  • 竖直投影切割
  • 连通域算法/CFS算法(这俩是一个算法)
  • 滴水算法
  • 聚类算法
  • 维诺图骨架形态分析

验证码识别的步骤

  1. 数据获取:自己爬虫爬取并生成验证码数据集;自己去找网上找现成数据集;自己生成验证码
  2. 预处理:灰度化、二值化、去除噪声、切除周围白色边框
  3. 将验证码进行切割,切割方法主要有竖直投影算法、连通域算法(CFS算法),滴水算法、SOM算法
  4. 生成数据集和验证集,并将其放入神经网络中识别

数据获取

  1. 可以使用selenium来模拟浏览器把验证码的位置进行截图保存(这里有一点栽坑的是,因为是模拟浏览器,有的网站名一样,但是要点击某些东西,才能触发验证码的出现。之前就没有点击,以为可能有会验证码,老是没有成功,是去请教了一位网友才知道的,耽搁了我很久时间)。后来发现只要一个验证码真的很简单,直接发送请求就可以了(但是之前花了我巨多时间,(lll¬ω¬))
  2. 代码中的获取验证码的url,其实只要点击验证码右击检查,就能看见src后面等于的那一堆就是了
    文本验证码识别项目的总结_第1张图片
    下述代码是怎么获取验证码的
def code_get(pic_num,scr,path):
    i = 0
    while i < pic_num:
    #这里的headers需要根据自己的浏览器进行修改的,我用的是谷歌浏览器。
        picture = rq.get(url=scr+str(i), headers= {'user-agent':'Chrome/10'} )
        with open(path+'code'+str(i)+'.jpg','wb') as f:
            f.write(picture.content)
        print("图片"+str(i)+"爬取完成")
        i+=1
        time.sleep(random.random() * 3)
# 这个是千图网的验证码的获取的php代码
url = 'https://www.58pic.com/index.php?m=userinfo&a=getImgCaptch&v= '
n = eval(input("请输入要爬取的图片数量:"))

预处理

*灰度化

原理:L=R0.299 +G0.587 +B*0.114
使用:使用python库的PIL的convert函数即可

from PIL import Image
src = ''
img = Image.open(src)
grey = img.convert('L')
grey.save('1.bmp')

*二值化

白话解说:就是设置一个阈值,如果大于该阈值的就设置为白色,小于该阈值的就设置为黑色,将图片变为非黑即白的样子。

  1. 全局阈值法:就是设置一个阈值,所有图像都使用这一个阈值
  2. ostu阈值:一位日本学者研究出来的,大致意思对于每张图片通过计算算出合适的阈值。(已经有实现的库了),想要使用的自行检索 skimage库中的filters.threshold_otsu
  3. 注意!! 此处有坑,记得图片最后保存为bmp格式,像我之前保存为jpg格式,导致之后实验过程中间出现介于黑色和白色之间的像素值。(原因:jpeg是有损的,bmp是无损的)

*去除噪声

这里我使用的方法,思路是通过检查每一个黑色像素的点,若该点四周的↑,↓,←,→,↖,↗,↙,↘八个点的像素值,如果一共有大于等于5个像素值为白色,则认为该点为噪声点,将其像素值变为白色。

切割

这就是八仙过海,各现神通了,神仙打架的地方。

*竖直投影切割

通过计算每一列所含的像素值之和,称其为竖直投影,然后选取其中值为0的地方进行切割,适用于简单的没有粘结的验证码字符

*连通域切割/CFS切割

通过判断某个像素是不是黑色且被访问过,如果没有被访问,就压入栈中,然后访问该点四周的点,并选取没有被访问的压入栈中。适合与字符之间没有粘结,但是有部分扭曲,导致竖直投影不太方便。

*滴水算法切割

模拟水滴掉落的,来进行切割。这里主要适用于字符之间有粘结的情况。感觉这个的难点在于选取对的起始点,至于每一个点的下一个点在哪里,公式都很清晰。选取起始点,我看的论文中,说选取投影过程中的极小值点比较好,我的实验结果也是这样。

生成数据集和测试集,以及识别验证码

我是通过生成tfrecord数据集格式,但是之后可能不支持了,所以不要学我。
我这里也栽跟头了,之前一直不知道怎么生成数据集和测试集,并且很傻的一件事情在于,我用的LeNet网络只能识别9个类别,后来发现只要修改最后的节点数目为我所需要的就可以了。
我是直接使用LeNet网络,比较简单的,所以就没什么特别说的。

你可能感兴趣的:(文本验证码识别项目的总结)