python判断图片是不是火车票_12306验证码图像识别程序源码-Python识别12306验证码 - PS下...

本文介绍如何利用Python进行12306验证码识别,通过爬虫收集验证码,使用百度OCR进行文字识别,然后通过图像哈希进行图片查重,提高识别准确率。在测试中,成功率达到了80.81%。
摘要由CSDN通过智能技术生成

2020年春运正式启动了,很多还在外地打工的朋友都还没有抢到票,其中就是我们的码农朋友,但是码农朋友平时都在写代码,没有时间抢票怎么办?这个时候就可以充分的利用自身优势了,用Python识别12306验证码来帮我们抢票,希望对大家有用。

如何让机器去识别?

(1) 基于图像识别

按照人类正常的思维习惯,想要选出符合标签的子图,就必须得判断出每张子图里的主体是什么。

所以,让机器去识别12306验证码的过程如下:

识别标签

识别每一张子图的主体

判断哪几张子图的主体和标签相符

在讲述该部分的内容之前,我想先安利下吴军大大的《数学之美》。

当时恰好在拜读此书,书中提到了自然语言处理(NLP)发展的2个阶段:“用电脑模拟人脑”到“基于数学模型和统计”。由此,我开始思考是否可以基于统计来实现12306验证码的识别。

再次回到本文开头的那张验证码图片,可以发现8张子图中有2张符合标签的“樱桃”图片,另有6张与标签毫无相关的图片,所以猜想:

如果能获得足够数量相同标签的12306验证码,那么正确的图片(即符合标签的图片)会大量重复出现

既然是猜想,自然需要实践的验证。

撸起袖子开始干!

Step1:写个小爬虫,从12306上爬取50,000张验证码,按1~50000进行编号

Step2:截取12306验证码标签区域(编号和原验证码图片保持一致),将标签图片丢给百度OCR接口,利用返回的文本信息进行自动分类,结果表明共有80个不同的类别

from aip import AipOcr

def baiduOCR(imagePath):

with open(imagePath, 'rb') as fp:

image = fp.read()

result = client.basicAccurate(image) # 每天500次免费调用额度

# result = client.basicGeneral(image) # 每天50000次免费调用额度

if 'words_result' in result:

temp = '\n'.join([w['words'] for w in result['words_result']])

# 修正常见的OCR错误

textOCR = temp.replace(',','').replace('一','').replace('/','').replace('-','').replace('^','').replace('A','').replace(u'呖',u'日历').replace(u'平',u'斗').replace(u'姗',u'珊').replace(u'痴',u'狮').replace(u'捉',u'报').replace(u'凤',u'风')

return textOCR

Step3:分割每张验证码上的8张子图,并存入对应标签的文件夹

举个栗子:“篮球”标签文件夹里的子图

Step4:图片查重

关于图片查重有好多种方法(具体原理可查阅以下“maggie”的回答),本文使用的是均值哈希(hash_size=16),通过计算2张图片的汉明距离(Hamming Distance)是否小于5来判定两图片是否一致。

PS:Python已有图像哈希库,安装后直接调用均值哈希算法即可。

pip install imagehash

具体步骤如下(以“篮球”标签为例):

1、新建“aHashDict”字典(key:保存图片的均值哈希值;value:以list形式保存对应图片的文件名)

2、遍历“篮球”文件夹内每一张图片,计算每张图片的均值哈希值

3、若图片哈希值与aHashDict字典中已有的key的汉明距离都不小于5,则说明该图片并未在此前出现过,则新建key,value对;若图片哈希值与某一key的汉明距离小于5,则说明该图片在此前出现过,故找到上述key对应的value,将图片的文件名添加进列表

from PIL import Image

import imagehash

def findSimilarImg(aHashDict, filename):

# 计算待检验图片的均值哈希(aHash)

img = Image.open(filename)

aHash = str(imagehash.average_hash(img,hash_size=16))

for k in aHashDict.keys():

# 计算汉明距离

temp = int(aHash, 16) ^ int(k, 16)

hammingDist=bin(temp).count('1')

# 判断两图片是否一致

if hammingDist < 5:

aHashDict[k].append(filename)

break

举个栗子,对“篮球”标签文件夹里的所有图片进行上述操作后,读取aHashDict来显示重现次数大于5的图片,如下视频所示,可看到满足上述要求的图片无一例外都是篮球!!!由此基本验证了我最开始的猜想是正确的!Bingo!!!

重点来了

有人会问了,前面讲了辣么多,可是还没提到怎么识别12306验证码呀!!!

不要急,其实12306验证码识别的核心内容都已经讲了,最关键的还是那句话:

如果能获得足够数量相同标签的12306验证码,那么正确的图片(即符合标签的图片)会大量重复出现

那么怎么做呢?

获取待验证的12306验证码

识别验证码的标签

读取对应标签的aHashDict字典

截取验证码上的8张子图,并计算每张子图均值哈希值(aHash)

对每一张子图的aHash与上述字典的所有key值计算汉明距离,如果与某key值的汉明距离小于5且该key值对应value的列表长度大于3(即训练样本里的重现次数大于3次),则说明该图片很有可能是正确的图片,pick it!!!

进行了100次12306验证码测试,排除1次无法识别标签的情况,共有99次有效测试,成功次数为80次,成功率为80.81%!!!

以上就是12306验证码图像识别程序源码,仅供学习使用哦。更多python教程尽在PS下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值