gif验证码识别,gif动态验证码识别

2,247 阅读5分钟

​原文地址:mp.csdn.net/mp_blog/cre…

一、背景

       本案例研究的对象为某一类gif验证码识别,图例如下,这种验证码的特点是由多帧(图例是4帧,和验证码个数一样)图片组成的,任意一帧图片都只会缺少其中某个或者几个验证码。

此案例采用python语言,所用模块ddddocr、PIL等

二、前提条件

      要解决识别这种验证码,首先得能识别静态图片验证码,这里安利一个大神用深度学习训练出来的库:ddddocr,可以识别多种验证码(目前没有研究其他验证码,只是用来识别静态图片,准确率非常高)

这位大神的博客:文安哲的博客

我们稍微体验一下:

验证码素材:1.png

# encoding=utf8
# 识别验证码-静态

import ddddocr
from PIL import Image

def ivd(img):
    ocr = ddddocr.DdddOcr()
    res = ocr.classification(img)
    return res

if __name__ == '__main__':
    print(ivd(Image.open("1.png")))

运行结果

ps:ocr.classification支持多种形式的参数,可以直接传base64字符串,有兴趣的可以看看源码。

三、基本思路

回到我们的目标,gif验证码,以上代码还能有效果吗?我们可以把如下验证码放进去试试

运行结果:

可以看到,第一个字识别错了,那是因为这个gif的第一帧是这样的

我们用一个图片编辑器看看所有帧,如下4帧,可以看到每一帧都有干扰符号。

问题就比较清晰了,解决思路如下:

1、将GIF图片所有帧抽出来;

2、把每一帧图片按照一定的透明度合成一张静态的图片,得到所有验证码显示在一张图片的效果

3、将得到图片放入识别库ddddocr中,搞定!

四、具体实现步骤

1、将GIF图片抽帧,直接附代码吧

# encoding=utf8
# 识别验证码-GIF

from PIL import Image

# 获取GIF的各帧
def getJpg(img):
    im = Image.open(img)
    imgs = []
    try:
        while True:
            current = im.tell()
            img = im.convert('RGB')

             # 可以将各个帧图片保存出来观察一下
            img_path = 'gif-to-pic/' + str(current) + '.jpg'
            img.save(img_path)

            # 将获取的图片放到列表里面,给后面合成图片用
            imgs.append(img)
            im.seek(current + 1)
    except:
        pass
    return imgs

if __name__ == '__main__':
    imgs = getJpg("1.gif")
    print(imgs)

目录结构如下:

pics结果

2、把每一帧图片按照一定的透明度合成一张静态的图片,得到所有验证码显示在一张图片的效果

# encoding=utf8
# 识别验证码-GIF

from PIL import Image

# 获取GIF的各帧
def getJpg(img):
    im = Image.open(img)
    imgs = []
    try:
        while True:
            current = im.tell()
            img = im.convert('RGB')

            # 可以将各个帧图片保存出来观察一下
            # img_path = 'pics/' + str(current) + '.jpg'
            # img.save(img_path)

            # 将获取的图片放到列表里面,给后面合成图片用
            imgs.append(img)
            im.seek(current + 1)
    except:
        pass
    return imgs
# 多张图片合成一张
def conflate(img_paths):

    cage = [] # 笼子,把图片放进来合并,如果有两张就合并,一笼不容二虎
    num = 0
    for img in img_paths:
        num += 1
        cage.append(img)
        if len(cage) == 2:
            merge = Image.blend(cage[0], cage[1], 0.5) # 合并两张图片,透明度0.5
            cage = [merge] # 合并完,重置笼子
    # 把合成完的图片保存出来,只是为了看看结果,后续直接用merge识别就行了
    merge.save("cage/intact.jpg")
    return merge

if __name__ == '__main__':
    imgs = getJpg("1.gif")
    conflate(imgs)

合成结果

3、将得到图片放入识别库ddddocr中,即为完整代码

# encoding=utf8
# 识别验证码-GIF

from PIL import Image
import ddddocr

# 获取GIF的各帧
def getJpg(img):
    im = Image.open(img)
    imgs = []
    try:
        while True:
            current = im.tell()
            img = im.convert('RGB')

            # 可以将各个帧图片保存出来观察一下
            # img_path = 'pics/' + str(current) + '.jpg'
            # img.save(img_path)

            # 将获取的图片放到列表里面,给后面合成图片用
            imgs.append(img)
            im.seek(current + 1)
    except:
        pass
    return imgs

# 多张图片合成一张
def conflate(img_paths):

    cage = [] # 笼子,把图片放进来合并,如果有两张就合并,一笼不容二虎
    num = 0
    for img in img_paths:
        num += 1
        cage.append(img)
        if len(cage) == 2:
            merge = Image.blend(cage[0], cage[1], 0.5) # 合并两张图片,透明度0.5
            cage = [merge] # 合并完,重置笼子
    # 把合成完的图片保存出来,只是为了看看结果,后续直接用merge识别就行了
    merge.save("cage/intact.jpg")
    return merge

#识别验证码
def ivd(img):
    ocr = ddddocr.DdddOcr()
    res = ocr.classification(img)
    return res

if __name__ == '__main__':
    imgs = getJpg("1.gif")
    merge = conflate(imgs)
    res = ivd(merge)
    print(res)

最终结果:

4、用其他验证码,测试一下:

五、完整代码

​字数限制,可以去原文地址:mp.csdn.net/mp_blog/cre…

如果觉得对你有用,可以多去支持一下ddddocr库的作者: 文安哲的博客

如果觉得这个文章对你有帮助,可以适当支持一下原创,谢谢!