原文地址: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库的作者: 文安哲的博客
如果觉得这个文章对你有帮助,可以适当支持一下原创,谢谢!