python验证码识别实战2

栏目: Python · 发布时间: 6年前

内容简介:python验证码识别实战2

在上一篇文章中,我们使用sklearn对验证码进行了识别,为了提高识别率,今天来进行进一步优化。

观察验证码后,发现还可以对其进行旋转处理,这个验证码旋转角度在-30~30之间,那么如何判断旋转角度呢?这里我使用最简单粗暴的判断方式——如果旋转后的字符宽度小于旋转之前,则认为是合理的旋转。但这里还有一个问题需要处理,上一篇文章中我们为了简便直接根据固定的宽度对字符进行了分割,但是分割后字符在小图片中的位置不是固定的,需要手动将其放在中心位置。

首先判断每个字符的边界:

def get_border(img, f=False):
    """获取字符边界"""
    t = 999
    b = 0
    l = 999
    r = 0
    flag = 255 if f else 0
    w, h = img.size
    pixdata = img.load()
    for y in range(h):
        for x in range(w):
            if pixdata[x, y] == flag and y < t:
                t = y
            if pixdata[x, y] == flag and y > b:
                b = y
            if pixdata[x, y] == flag and x < l:
                l = x
            if pixdata[x, y] == flag and x > r:
                r = x
    return l, t, r, b

由于图片大小是30×30,所以我取999作为上、左边界初始值。上面代码中的 f 参数下面会说。接下来创建一个新的图片,并把提取出来的字符放到图片中心:

def resize_img(img):
    """把提取出来的字符放到新图片中央,方便旋转"""
    i_w = 30
    i_h = 30
    w, h = img.size
    image = Image.new('RGB', (i_w, i_h), (255, 255, 255))
    l = (i_w - w) // 2
    r = l + w
    t = (i_h - h) // 2
    b = t + h
    image.paste(img, (l, t, r, b))
    return image

由于pillow库对图片旋转后使用了黑色对边界进行填充,而我们的原始图片是白底黑字,所以还需要对图片进行反相操作,以免旋转造成的干扰:

def opposite(img):
    # 反相处理,注意传入的是灰度二值化后的图片
    tmp = np.array(img)
    tmp = 255 - tmp
    return Image.fromarray(tmp)

上面 get_border 函数中 参数的作用就是如果传入一张反相处理后的图片,则设其为 True 来获取边界。接下来旋转图片:

def rotate_img(imgname):
    """将初步切分的图片提取字符并修正旋转"""
    img = Image.open(imgname)
    img = binarizing(img,180)
    border = get_border(img)
    new = img.crop(border)
    new2 = resize_img(new)
    new2 = binarizing(new2,180)
    result = []
    o_l, o_t, o_r, o_b = get_border(new2)
    w = o_r - o_l
    new3 = opposite(new2)
    for ro in range(-30, 31, 3):
        # 一般旋转角度在-30到30之间,可以通过修改步长来精细控制
        tmp = new3.rotate(ro)
        l, t, r, b = get_border(tmp, f=True)
        if r - l <= w and abs(ro) > 9:
            # 如果旋转后字符宽度变小了,则认为需要旋转。并且角度要大于9
            w = r - l  # 这句话保证最合适的旋转度数在最后,即最窄
            result.append(ro)
    final_ro = result[-1] if result else 0
    return opposite(new3.rotate(final_ro))

关于 binarizing 函数请看上一篇文章。旋转图片如下:

python验证码识别实战2

可以看出,逆时针旋转27度时,字符就“立”起来了。当我们把字符旋转之后,再使用相同的代码进行预测,正确率如下:

knn score: 0.9
bayes score: 0.705
description tree score: 0.755

正确率提升了不少。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Wireshark网络分析就这么简单

Wireshark网络分析就这么简单

林沛满 / 人民邮电出版社 / 2014-11-6 / 39.00

Wireshark可能是世界上最好的开源网络包分析器,能在多种平台上(比如Windows、Linux和Mac)抓取和分析网络包,在IT业界有着广泛的应用。 《Wireshark网络分析就这么简单》采用诙谐风趣的手法,由浅入深地用Wireshark分析了常见的网络协议,读者在学习Wireshark的同时,也会在不知不觉中理解这些协议。作者还通过身边发生的一些真实案例,分享了Wireshark的......一起来看看 《Wireshark网络分析就这么简单》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具