zoukankan      html  css  js  c++  java
  • 8.1 图形验证码的识别

    8.1 图形验证码的识别

    我们首先识别最简单的一种验证码,即图形验证码。这种验证码最早出现,现在也很常见,一般由 4 位字母或者数字组成。例如,中国知网的注册页面有类似的验证码,链接为:http://my.cnki.net/elibregister/commonRegister.aspx,页面如图 8-1 所示:

    图 8-1 知网注册页面

    表单的最后一项就是图形验证码,我们必须完全正确输入图中的字符才可以完成注册。

    1. 本节目标

    以知网的验证码为例,讲解利用 OCR 技术识别图形验证码的方法。

    2. 准备工作

    识别图形验证码需要库 tesserocr。安装此库可以参考第 1 章的安装说明。

    3. 获取验证码

    为了便于实验,我们先将验证码的图片保存到本地。

    打开开发者工具,找到验证码元素。验证码元素是一张图片,它的 src 属性是 CheckCode.aspx。我们直接打开这个链接 http://my.cnki.net/elibregister/CheckCode.aspx,就可以看到一个验证码,右键保存即可,将其命名为 code.jpg,如图 8-2 所示。

    图 8-2 验证码

    这样我们就可以得到一张验证码图片,以供测试识别使用。

    4. 识别测试

    接下来新建一个项目,将验证码图片放到项目根目录下,用 tesserocr 库识别该验证码,代码如下所示:

    import tesserocr
    from PIL import Image
    
    image = Image.open('code.jpg')
    result = tesserocr.image_to_text(image)
    print(result)
    

    在这里我们新建了一个 Image 对象,调用了 tesserocr 的 image_to_text() 方法。传入该 Image 对象即可完成识别,实现过程非常简单,结果如下所示:

    JR42
    

    另外,tesserocr 还有一个更加简单的方法,这个方法可直接将图片文件转为字符串,代码如下所示:

    import tesserocr
    print(tesserocr.file_to_text('image.png'))
    

    不过,此种方法的识别效果不如上一种方法好。

    5. 验证码处理

    接下来我们换一个验证码,将其命名为 code2.jpg,如图 8-3 所示。

    图 8-3 验证码

    重新用下面的代码来测试:

    import tesserocr
    from PIL import Image
    
    image = Image.open('code2.jpg')
    result = tesserocr.image_to_text(image)
    print(result)
    

    可以看到如下输出结果:

    FFKT
    

    这次识别和实际结果有偏差,这是因为验证码内的多余线条干扰了图片的识别。

    对于这种情况,我们还需要做一下额外的处理,如转灰度、二值化等操作。

    我们可以利用 Image 对象的 convert() 方法参数传入 L,即可将图片转化为灰度图像,代码如下所示:

    image = image.convert('L')
    image.show()
    

    传入 1 即可将图片进行二值化处理,如下所示:

    image = image.convert('1')
    image.show()
    

    我们还可以指定二值化的阈值。上面的方法采用的是默认阈值 127。不过我们不能直接转化原图,要将原图先转为灰度图像,然后再指定二值化阈值,代码如下所示:

    image = image.convert('L')
    threshold = 80
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    
    image = image.point(table, '1')
    image.show()
    

    在这里,变量 threshold 代表二值化阈值,阈值设置为 80。之后我们看看结果,如图 8-4 所示。

    图 8-4 处理结果

    我们发现原来验证码中的线条已经去除,整个验证码变得黑白分明。这时重新识别验证码,代码如下所示:

    import tesserocr
    from PIL import Image
    
    image = Image.open('code2.jpg')
    
    image = image.convert('L')
    threshold = 127
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    
    image = image.point(table, '1')
    result = tesserocr.image_to_text(image)
    print(result)
    

    即可发现运行结果变成如下所示:

    PFRT
    

    那么,针对一些有干扰的图片,我们做一些灰度和二值化处理,这会提高图片识别的正确率。

    6. 本节代码

    本节代码地址为:https://github.com/Python3WebSpider/CrackImageCode

    7. 结语

    本节我们了解了利用 tesserocr 识别验证码的过程。我们可以直接用简单的图形验证码得到结果,也可以对验证码图片做预处理来提高识别的准确度。

  • 相关阅读:
    Summary for sql join in Oracle DB
    Merge data into table in Oracle
    PLSQL存储过程传出大量异常错误信息
    oracle 11g plsql解析json数据示例
    识别'低效执行'的SQL语句
    如何开启MySQL 5.7.12 的二进制日志
    Linux下ps命令详解 Linux下ps命令的详细使用方法
    Linux(Unix)时钟同步ntpd服务配置方法
    MySQL 常用命令总结
    MySQL 数据库通过日志恢复
  • 原文地址:https://www.cnblogs.com/ciquankun/p/13329233.html
Copyright © 2011-2022 走看看