详解Python验证码识别


Posted in Python onJanuary 25, 2016

以前写过一个刷校内网的人气的工具,Java的(以后再也不行Java程序了),里面用到了验证码识别,那段代码不是我自己写的:-) 校内的验证是完全单色没有任何干挠的验证码,识别起来比较容易,不过从那段代码中可以看到基本的验证码识别方式。这几天在写一个程序的时候需要识别验证码,因为程序是Python写的自然打算用Python进行验证码的识别。

以前没用Python处理过图像,不太了解PIL(Python Image Library)的用法,这几天看了看PIL,发现它太强大了,简直和ImageMagic,PS可以相比了。(这里有PIL不错的文档)

由于上面的验证码是24位的jpeg图像,并且包含了噪点,所以我们要做的就是去噪和去色,我拿PS找了张验证码试了试,使用PS滤镜中的去噪效果还行, 但是没有在PIL找到去噪的函数,后来发现中值过滤后可以去掉大部分的噪点,而且PIL里有现成的函数,接下来我试着直接把图像转换为单色,结果发现还是 会有不过的噪点留了下来,因为中值过滤时把不少噪点淡化了,但转换为音色时这些噪点又被强化显示了,于是在中值过滤后对图像亮度进行加强处理,然后再转换 为单色,这样验证码图片就变得比较容易识别了:

上面这些处理使用Python才几行:

im = Image.open(image_name)
im = im.filter(ImageFilter.MedianFilter())
enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
im.show()

接下来就是提取这些数字的字模,使用shell脚本下载100幅图片,抽出三张图片获取字模:

#!/usr/bin/env python
#encoding=utf-8
import Image,ImageEnhance,ImageFilter
import sys
image_name = "./images/81.jpeg"
im = Image.open(image_name)
im = im.filter(ImageFilter.MedianFilter())
enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
#im.show()
#all by pixel
s = 12 #start postion of first number
w = 10 #width of each number
h = 15 #end postion from top
t = 2 #start postion of top
im_new = []
#split four numbers in the picture
for i in range(4):
im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
im_new.append(im1)
f = file("data.txt","a")
for k in range(4):
l = []
#im_new[k].show()
for i in range(13):
for j in range(10):
if (im_new[k].getpixel((j,i)) == 255):
l.append(0)
else:
l.append(1)
f.write("l=[")
n = 0
for i in l:
if (n%10==0):
f.write("/n")
f.write(str(i)+",")
n+=1
f.write("]/n")

把字模保存为list,用于接下来的匹配;

提取完字模后剩下来的就是对需要处理的图片进行与数据库中的字模进行匹配了,基本的思路就是看相应点的重合率,但是由于噪点的影响在对(6,8) (8,3)(5,9)的匹配时容易出错,俺自己针对已有的100幅图片数据采集进行分析,采用了双向匹配(图片与字模分别作为基点),做了半天的测试终于 可以实现100%的识别率。

#!/usr/bin/env python
#encoding=utf-8
import Image,ImageEnhance,ImageFilter
import Data
DEBUG = False
def d_print(*msg):
global DEBUG
if DEBUG:
for i in msg:
print i,
print
else:
pass
def Get_Num(l=[]):
min1 = []
min2 = []
for n in Data.N:
count1=count2=count3=count4=0
if (len(l) != len(n)):
print "Wrong pic"
exit()
for i in range(len(l)):
if (l[i] == 1):
count1+=1
if (n[i] == 1):
count2+=1
for i in range(len(l)):
if (n[i] == 1):
count3+=1
if (l[i] == 1):
count4+=1
d_print(count1,count2,count3,count4)
min1.append(count1-count2)
min2.append(count3-count4)
d_print(min1,"/n",min2)
for i in range(10):
if (min1[i] <= 2 or min2[i] <= 2):
if ((abs(min1[i] - min2[i])) <10):
return i
for i in range(10): 
if (min1[i] <= 4 or min2[i] <= 4):
if (abs(min1[i] - min2[i]) <= 2):
return i
for i in range(10):
flag = False
if (min1[i] <= 3 or min2[i] <= 3):
for j in range(10):
if (j != i and (min1[j] <5 or min2[j] <5)):
flag = True
else:
pass
if (not flag):
return i
for i in range(10): 
if (min1[i] <= 5 or min2[i] <= 5):
if (abs(min1[i] - min2[i]) <= 10):
return i
for i in range(10):
if (min1[i] <= 10 or min2[i] <= 10):
if (abs(min1[i] - min2[i]) <= 3):
return i
#end of function Get_Num
def Pic_Reg(image_name=None):
im = Image.open(image_name)
im = im.filter(ImageFilter.MedianFilter())
enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
im.show()
#all by pixel
s = 12 #start postion of first number
w = 10 #width of each number
h = 15 #end postion from top
t = 2 #start postion of top
im_new = []
#split four numbers in the picture
for i in range(4):
im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
im_new.append(im1)
s = ""
for k in range(4):
l = []
#im_new[k].show()
for i in range(13):
for j in range(10):
if (im_new[k].getpixel((j,i)) == 255):
l.append(0)
else:
l.append(1)
s+=str(Get_Num(l))
return s
print Pic_Reg("./images/22.jpeg")

这里再提一下验证码识别的基本方法:截图,二值化、中值滤波去噪、分割、紧缩重排(让高矮统一)、字库特征匹配识别。
这里只是针对一般的验证码,高级验证码的识别这里有篇不错的文章,太复杂的话涉及的东西就多了,那俺就没兴趣了,人工智能(好恐怖),俺只喜欢简单的东西。

Python 相关文章推荐
使用Python的Supervisor进行进程监控以及自动启动
May 29 Python
Python3基础之基本运算符概述
Aug 13 Python
virtualenv实现多个版本Python共存
Aug 21 Python
numpy.random.seed()的使用实例解析
Feb 03 Python
Python3导入自定义模块的三种方法详解
Apr 13 Python
对Python 网络设备巡检脚本的实例讲解
Apr 22 Python
理想高通滤波实现Python opencv示例
Jan 30 Python
Python实现简单的列表冒泡排序和反转列表操作示例
Jul 10 Python
详解程序意外中断自动重启shell脚本(以Python为例)
Jul 26 Python
tensor和numpy的互相转换的实现示例
Aug 02 Python
Python pip 常用命令汇总
Oct 19 Python
python实现简易自习室座位预约系统
Jun 30 Python
Python网站验证码识别
Jan 25 #Python
谈谈Python进行验证码识别的一些想法
Jan 25 #Python
基于Python Shell获取hostname和fqdn释疑
Jan 25 #Python
21行Python代码实现拼写检查器
Jan 25 #Python
Python字符串、元组、列表、字典互相转换的方法
Jan 23 #Python
Python随手笔记第一篇(2)之初识列表和元组
Jan 23 #Python
Python爬虫模拟登录带验证码网站
Jan 22 #Python
You might like
php empty() 检查一个变量是否为空
2011/11/10 PHP
探讨PHP JSON中文乱码的解决方法详解
2013/06/06 PHP
PHP实现取得HTTP请求的原文
2014/08/18 PHP
PHP获取QQ达人QQ信息的方法
2015/03/05 PHP
WordPress中获取所使用的模板的页面ID的简单方法
2015/12/31 PHP
PHP预定义变量9大超全局数组用法详解
2016/04/23 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
javascript string字符串优化问题
2011/07/31 Javascript
js在输入框屏蔽按键,只能键入数字的示例代码
2014/01/03 Javascript
document.addEventListener使用介绍
2014/03/07 Javascript
jQuery实现网页顶部固定导航效果代码
2015/12/24 Javascript
解决AjaxFileupload 上传时会出现连接重置的问题
2017/07/07 Javascript
vue watch自动检测数据变化实时渲染的方法
2018/01/16 Javascript
vue 项目常用加载器及配置详解
2018/01/22 Javascript
Intellij IDEA搭建vue-cli项目的方法步骤
2018/10/20 Javascript
React中使用外部样式的3种方式(小结)
2019/05/28 Javascript
Python中的Numeric包和Numarray包使用教程
2015/04/13 Python
解决Python中由于logging模块误用导致的内存泄露
2015/04/23 Python
在Python中使用poplib模块收取邮件的教程
2015/04/29 Python
在Python中使用matplotlib模块绘制数据图的示例
2015/05/04 Python
Python实现爬取逐浪小说的方法
2015/07/07 Python
python使用rsa非对称加密过程解析
2019/12/28 Python
python 操作excel表格的方法
2020/12/05 Python
python语言time库和datetime库基本使用详解
2020/12/25 Python
一文读懂python Scrapy爬虫框架
2021/02/24 Python
阿根廷首家户外用品制造商和经销商:Montagne
2018/02/12 全球购物
Manuka Doctor英国官网:真正的麦卢卡蜂蜜和护肤品
2018/10/26 全球购物
介绍一下Prototype的$()函数,$F()函数,$A()函数都是什么作用?
2014/03/05 面试题
教师学习培训邀请函
2014/02/04 职场文书
挂靠协议书范本
2014/04/22 职场文书
伊索寓言教学反思
2014/05/01 职场文书
会计试用期自我评价
2014/09/19 职场文书
2016初一新生军训心得体会
2016/01/11 职场文书
怎样写工作总结啊!
2019/06/18 职场文书
python人工智能human learn绘图可创建机器学习模型
2021/11/23 Python
Python+Matplotlib图像上指定坐标的位置添加文本标签与注释
2022/04/11 Python