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

正确率提升了不少。


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

查看所有标签

猜你喜欢:

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

Boolean Reasoning

Boolean Reasoning

Brown, Frank Markham / 2003-4 / $ 19.15

A systematic treatment of Boolean reasoning, this concise, newly revised edition combines the works of early logicians with recent investigations, including previously unpublished research results. Th......一起来看看 《Boolean Reasoning》 这本书的介绍吧!

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

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

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

在线 XML 格式化压缩工具