⑴ python pil 怎么去掉验证码线条
一、验证码识别的概念
机器识别图片主要的三个步骤为消去背景、切割字符、识别字符。而现有的字符验证码也针对这三个方面来设计强壮的验证码。
以下简图帮助大家理解验证码识别的流程:
二、处理流程
其中最为关键的就是好图像处理这一步了。图像处理功能模块包括图像的灰度化、二值化、离散噪声点的去除、倾斜度校正、字符的切割、图像的归一化等图像处理技术 。
1、 图像的灰度化
由于 256 色的位图的调色板内容比较复杂,使得图像处理的许多算法都没有办法展开,因此有必要对它进行灰度处理。所谓灰度图像就是图像的每一个像素的 R、G、B 分量的值是相等的。彩色图像的每个像素的 R、G、B 值是不相同的,所以显示出红绿蓝等各种颜色。灰度图像没有这些颜色差异,有的只是亮度上的不同。灰度值大的像素点比较亮(像素值最大为 255,为白色),反之比较暗(像素值最小为 0,为黑色)。图像灰度化有各种不同的算法,比较直接的一种就是给像素的 RGB 值各自一个加权系数,然后求和;同时还要对调色板表项进行相应的处理。
2、 图像的二值化
要注意的是,最后得到的结果一定要归一到 0-255 之内。因为这是每个字节表示
图像数据的极限。
3、 去噪
图像可能在生成、传输或者采集过程中夹带了噪声,去噪声是图像处理中常用的手法。通常去噪声用滤波的方法,比如中值滤波、均值滤波。但是那样的算法不适合用在处理字符这样目标狭长的图像中,因为在滤波的过程中很有可能会去掉字符本身的像素。
一个采用的是去除杂点的方法来进行去噪声处理的。具体算法如下:扫描整个图像,当发现一个黑色点的时候,就考察和该黑色点间接或者直接相连接的黑色点的个数有多少,如果大于一定的值,那就说明该点不是离散点,否则就是离散点,把它去掉。在考察相连的黑色点的时候用的是递归的方法。此处,我简单的用python实现了,大家可以参考以下。
#coding=utf-8"""
creat time:2015.09.14
"""import cv2import numpy as npfrom matplotlib import pyplot as pltfrom PIL import Image,ImageEnhance,ImageFilter
img_name = '2+.png'#去除干扰线im = Image.open(img_name)#图像二值化enhancer = ImageEnhance.Contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
data = im.getdata()
w,h = im.size#im.show()black_point = 0for x in xrange(1,w-1): for y in xrange(1,h-1):
mid_pixel = data[w*y+x] #中央像素点像素值
if mid_pixel == 0: #找出上下左右四个方向像素点像素值
top_pixel = data[w*(y-1)+x]
left_pixel = data[w*y+(x-1)]
down_pixel = data[w*(y+1)+x]
right_pixel = data[w*y+(x+1)] #判断上下左右的黑色像素点总个数
if top_pixel == 0:
black_point += 1
if left_pixel == 0:
black_point += 1
if down_pixel == 0:
black_point += 1
if right_pixel == 0:
black_point += 1
if black_point >= 3:
im.putpixel((x,y),0) #print black_point
black_point = 0im.show()041424344
原验证码:
4、分割
图像中一般会含有多个数字,识别的时候只能根据每个字符的特征来进行判断,所以还要进行字符切割的工作。这一步工作就是把图像中的字符独立的切割出来。
具体的算法如下:
第一步,先自下而上对图像进行逐行扫描直至遇到第一个黑色的像素点。记录下来。然后再自上而下对图像进行逐行扫描直至找到第一个黑色像素,这样就找到图像大致的高度范围。
第二步,在这个高度范围之内再自左向右逐列进行扫描,遇到第一个黑色像素时认为是字符切割的起始位置,然后继续扫描,直至遇到有一列中没有黑色像素,则认为这个字符切割结束,然后继续扫描,按照上述的方法一直扫描直至图像的最右端。这样就得到了每个字符的比较精确宽度范围。
第三步,在已知的每个字符比较精确的宽度范围内,按照第一步的方法,分别进行自上而下和自下而上的逐行扫描来获取每个字符精确的高度范围。
5、 图像的归一化
因为采集的图像中字符大小有可能存在较大的差异,或者是经过切割后的字符尺寸不统一,而相对来说,统一尺寸的字符识别的标准性更强,准确率自然也更高,归一化图像就是要把原来各不相同的字符统一到同一尺寸,在系统实现中是统一到同一高度,然后根据高度来调整字符的宽度。具体算法如下:先得到原来字符的高度,跟系统要求的高度做比较,得出要变换的系数,然后根据得到的系数求得变换后应有得宽度。在得到宽度和高度之后,把新图像里面的点按照插值的方法映射到原图像中。
不少人认为把每个字符图像归一化为 5×9 像素的二值图像是最理想的,因为图像的尺寸越小,识别速度就越高,网络训练也越快。而实际上,相对于要识别的字符图像, 5×9 像素图太小了。归一化后,图像信息丢失了很多,这时进行图像识别,准确率不高。实验证明,将字符图像归一化为 10×18 像素的二值图像是现实中是比较理想的,达到了识别速度快和识别准确率高的较好的平衡点。
三、识别
图像识别包括特征提取、样本训练和识别三大块内容。
验证码识别其中最为关键的就是去噪和分割,这对你的训练和识别的精度都有着很大的影响。这里只讲了大致的流程,其中每个细节都有很多工作要做,这里码字也很难讲清楚,大家可以以这个流程为主线,一步步的实现,最终也就能完成你的需求。
⑵ android识别验证码图片的原理与思路
假设已经把验证码图片保存到本地了
我说一下验证码识别的大致步骤吧
1,读取图片到bitmap
2,进行灰度操作
3,进行才二值操作
4,如果有干扰点 一般用滤波器或八邻域去干扰点
5,如果有干扰线 如果是简单的直线可以用扫描法,八后法等,复杂的应该根据特点调整算法
6,如果有干扰色块 也应该想法去除
7,如果有较大的倾斜 需要进行适当校正
8,此时得到的应该是比较干净的字符了,如果是非粘连的可以直接用投影法分割成单个字符
如果有粘连,需要根据图形特点从算法上做相应的处理,保证大致分割正确
9,分割成单个字符以后,如果字符比较正常 变形扭曲程序不大,可以直接用模式识别
如果变形扭曲较厉害,一般建议使用神经网络进行训练后再识别
如果是比较简单的验证码可以使用网上的一些组件,我常用的一个是OcrKingApi
不是太复杂的识别效果还可以,关键是免费的。使用文档可以看一下文库的链接
http://wenku..com/view/b5b6721555270722192ef7b3.html
⑶ 请教生成如图验证码的python算法
def gene_text():
source = list(string.letters)
for index in range(0,10):
source.append(str(index))
return ''.join(random.sample(source,number))#number是生成验证码的位数
然后我们要创建一个图片,写入字符串,需要说明的这里面的字体是不同系统而定,如果没有找到系统字体路径的话,也可以不设置
def gene_code():
width,height = size #宽和高
image = Image.new('RGBA',(width,height),bgcolor) #创建图片
font = ImageFont.truetype(font_path,25) #验证码的字体和字体大小
draw = ImageDraw.Draw(image) #创建画笔
text = gene_text() #生成字符串
font_width, font_height = font.getsize(text)
draw.text(((width - font_width) / number, (height - font_height) / number),text,
font= font,fill=fontcolor) #填充字符串
接下来,我们要在图片上画几条干扰线
#用来绘制干扰线
def gene_line(draw,width,height):
begin = (random.randint(0, width), random.randint(0, height))
end = (random.randint(0, width), random.randint(0, height))
draw.line([begin, end], fill = linecolor)
最后创建扭曲,加上滤镜,用来增强验证码的效果。
image = image.transform((width+20,height+10), Image.AFFINE, (1,-0.3,0,-0.1,1,0),Image.BILINEAR) #创建扭曲
image = image.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强
image.save('idencode.png') #保存验证码图片
⑷ 如何利用Python做简单的验证码识别
1摘要
验证码是目前互联网上非常常见也是非常重要的一个事物,充当着很多系统的防火墙功能,但是随时OCR技术的发展,验证码暴露出来的安全问题也越来越严峻。本文介绍了一套字符验证码识别的完整流程,对于验证码安全和OCR识别技术都有一定的借鉴意义。
然后经过了一年的时间,笔者又研究和get到了一种更强大的基于CNN卷积神经网络的直接端到端的验证识别技术(文章不是我的,然后我把源码整理了下,介绍和源码在这里面):
基于python语言的tensorflow的‘端到端’的字符型验证码识别源码整理(github源码分享)
2关键词
关键词:安全,字符图片,验证码识别,OCR,Python,SVM,PIL
3免责声明
本文研究所用素材来自于某旧Web框架的网站完全对外公开的公共图片资源。
本文只做了该网站对外公开的公共图片资源进行了爬取,并未越权做任何多余操作。
本文在书写相关报告的时候已经隐去漏洞网站的身份信息。
本文作者已经通知网站相关人员此系统漏洞,并积极向新系统转移。
本报告的主要目的也仅是用于OCR交流学习和引起大家对验证安全的警觉。
4引言
关于验证码的非技术部分的介绍,可以参考以前写的一篇科普类的文章:
互联网安全防火墙(1)--网络验证码的科普
里面对验证码的种类,使用场景,作用,主要的识别技术等等进行了讲解,然而并没有涉及到任何技术内容。本章内容则作为它的技术补充来给出相应的识别的解决方案,让读者对验证码的功能及安全性问题有更深刻的认识。
5基本工具
要达到本文的目的,只需要简单的编程知识即可,因为现在的机器学习领域的蓬勃发展,已经有很多封装好的开源解决方案来进行机器学习。普通程序员已经不需要了解复杂的数学原理,即可以实现对这些工具的应用了。
主要开发环境:
python3.5
python SDK版本
PIL
图片处理库
libsvm
开源的svm机器学习库
关于环境的安装,不是本文的重点,故略去。
6基本流程
一般情况下,对于字符型验证码的识别流程如下:
准备原始图片素材
图片预处理
图片字符切割
图片尺寸归一化
图片字符标记
字符图片特征提取
生成特征和标记对应的训练数据集
训练特征标记数据生成识别模型
使用识别模型预测新的未知图片集
达到根据“图片”就能返回识别正确的字符集的目标
7素材准备
7.1素材选择
由于本文是以初级的学习研究目的为主,要求“有代表性,但又不会太难”,所以就直接在网上找个比较有代表性的简单的字符型验证码(感觉像在找漏洞一样)。
最后在一个比较旧的网站(估计是几十年前的网站框架)找到了这个验证码图片。
原始图:
然后就将图片素材特征化,按照libSVM指定的格式生成一组带特征值和标记值的向量文
⑸ 如何快速学习神经网络算法识别验证码
验证码都是服务器生成的图片,如果是动态的,就是调用servlet生成的,怎么提取我还不太清楚,不过我想网络上应该会有很多资料。
我现在看的是识别验证码的东西,在截取到验证码图片之后,针对这个黑白背景,只有干扰线的验证码。
机器学习之识别简单验证码
时间 2016-10-15 22:46:31 随风'S Blog
主题 数据挖掘
关于验证码识别的文章网上很多图像识别的大神教程也比较多,不过大多数专业性太强了,对非专业人士读起来简直是天书,不过随着机器学习的普及,一大批机器学习的开源工具出现了,这也算对大多数像我一样的学渣的福音,由于最近项目中牵扯到了一些机器学习相关的东西,所以自己最近也一直在学习机器相关的东西,这篇验证码的识别也算是练手了,本文也算是学习中的笔记,所以文章中难免有一些错误,欢迎各路大神指点。
由于本人不是相关专业的,对于文中相关算法就不会具体去讨论了,主要以实战为目的。
准备工作
主要是用到了一些机器学习开源的框架以及一些辅助工具。
Scikit-Learn 比较有名的Python机器学习模块,主要是操作简单。
Pybrain Python机器学习模块,主要以神经网络为核心,所有的训练方法都以神经网络为一个实例。
pytesseract 图像识别小工具,本文主要是用来预处理训练样本的。
PIL Python图像处理库。
问题分析
首先在进行具体工作之前,我们得看看我们需要解决的是什么问题,那么对于验证码识别来说,可以看作一个分类问题,对于数字的图片验证码来说的话,其实就是0-9数字分类的问题,验证码识别最难的部分在于怎么去将验证码进行切割成单个字符图片,当然对于图片裁剪也就是特征提取有很多办法,例如垂直投影法,等距切割法等等,其中等距切割也是比较简单的,但是对于稍微复杂一点的验证码识别时准确率非常低,因为等距切割时将验证码按照相同的宽度进行裁剪,对于那些字符宽度大小不一的,就算裁剪出来也不能很好的表示字符的特征,所以有时候需要先对图片进行一系列的预处理,例如字符矫正等等,然后再用垂直投影法在x轴和y轴上按照投影的大小进行裁剪。
对于垂直投影法来说的话,最后我们还得考虑训练集在维度上都同意,由于是非等级切割,所以每个图片的像素肯定不一样,所以为了维度统一还得进行填充,总之稍微麻烦一点。
这里主要是以等距切割为例子,因为在操作起来比较简单,那么掩码也是选用0-9的纯数字验证码来进行识别,验证码如下
这样的图片看起来的话间距基本上都差不多大,所以在分割时也比较容易,将图片切成四块后,就可以拿每一块去进行训练识别了。
使用机器学习来进行训练和识别的话,我们就得考虑特征选取了,一般验证码识别有一套标准的流程,图片
对于验证码识别来说我们关注的不是验证码的颜色,而是字符代表的含义,所以在图片处理时进行灰度化和二值化以及去噪,比如说去掉干扰线,那么去噪也有相应的算法来实现,这里不做具体讨论,二值化其实就是将图片呈现出两种颜色,即非黑即白,这样的好处是在特征处理时可以使用0和1来代表黑色和白色,0和1代表什么颜色取决于个人喜好。
这样的话将二值化和其它步骤处理后的图片进行特征提取,将黑色像素点标记成1,白色像素点标记成0,这样就可以得到图片的数值表示,那么特征维度就等于图片像素的大小,最终将图片按照X轴或者Y轴表示,即将像素的所标记的值合并到一行,例如
1111100000000000010
1110000000000000000
表示成,这样每张图片就可以使用一行0和1的数值来表示。
进行特征提取之后,我们得到了图片在数学上的表示,那么下一步就需要进行模型训练了,由于如上文所述,图片识别是一个分类问题,所以在机器学习中,我主要采用了两种模型来进行训练, SVM支持向量机 和 BP神经网络 来进行模型训练,SVM使用scikit-learn机器学习包里面的实现来做,神经网络使用Pybrain来进行实现。
有关SVM和BP神经网络的算法部分,大家最好还是去网上搜下相关的Paper,这样你才能知道什么算法能解决什么问题,以及它大概的原理是什么样子的,有能力的同学可以去对推导下这两个算法。
实践
在问题分析部分我们已经对验证码识别的大概思路有了一个了解,那么这部分则主要正对上面所述部分进行具体实现。
首先,我们应该明白SVM和神经网络模型算法是属于有监督学习,即需要对样本进行标注,也就是标记每张图片表示的是那个数字,但是实际遇到的问题是,如果数据量小的话,我们可以进行人工标注,那么在数据量比较大的情况下,人工标注可能就不太现实了,所以对于图片来说的话也一样,你进行切割完成之后你必须得标注这个数字是几,所以我们需要对切割的图片进行预处理,也就是打标记,我比较懒,所以我也不会一个个去打标签,所以这里使用ocr来对切割的图片进行预分类,ocr在单文字识别上的效果正确率还是可以的,在ocr进行预分类之后,我们只需要去纠正那些分类错误的图片即可,这样就能大大的减少工作量。
这里实现主要有以下几个步骤:
图片采集
图片预处理(包括图片切割,二值化以及图像增强)
图片的预分类标注以及手动纠错标注
特征提取
模型训练以及预测
图片采集
图片采集就比较简单,不过多的阐述,如下图代码所示
将下载到了图片按照时间戳存到指定位置
图片预处理以及图片裁剪
对图片进行预处理后采用等距切割法对图片进行切割
裁剪后的图片如下
图片预分类
图片预分类采用pytesseract来对分割的图片进行预分类,减轻工作量。
具体代码如下
ocr的分类效果正确率应该在50%以上,剩下的就是对预分类的图片进行人工纠错了。
ocr的分类效果图
人工纠错和标记后的结果
每个目录表示一个类别标签。
特征提取
特征提取的具体内容请参考问题分析中,里面有详细的说明。
关键代码如下
最终图片的数学上表示会以记录在 /Users/iswin/Downloads/yzm/traindata/train_data.txt 中,数据的格式如下图所示
红色线框表示一张图片数值上的表示,最后一个数字0表示该图片的类型,我是为了方便把标签追加到最后一行。
SVM模型分类
这里svm的实现使用了scikit-learn来实现,关于scikit-learn的使用去官网看Tutorial就好了,这里需要说一下SVM关于参数选择的问题,我们都知道SVM支持多个核函数,例如高斯核、线性核、poly以及sgmoid核函数,但是选择那么核函数一开始对于不太熟悉的同学怎么选择的确是个问题,所以这里使用了scikit-learn的GridSearchCV来对参数进行最优化选择,经过参数寻优,这里高斯核的最终效果还是不错的,所以训练的时候直接使用高斯核来进行训练。
为了方便预测时的使用,这里对训练结果使用了joblib模块来进行持久化。为了简单对评价模型进行,这里使用了5折交叉验证来对结果进行检验。
最终结果的准确率在:Accuracy: 0.96 (+/- 0.09)
具体代码如下:
举个预测的例子,看看效果
BP神经网络模型分类
BP神经网络也称负反馈神经网络,即按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一,在BP神经网络之后,又出现了在深度学习中应用最广泛的CNN即卷积神经网络,这几天也正在学习。
本文使用了三层BP神经网络来对训练集进行训练,即输入层+2层隐含层+输出层,关于BP神经网络本身这里需要注意的是激活函数的选择以及对于多分类问题输出层函数选择的问题,激活函数主要有sigmod、tanh以及relu,关于怎么选取激活函数,这块没有进行深入了解,一般都是每个激活函数都跑一次,看最终效果。
这里的神经网络模型分类主要是对Pybrain用法的学习以及BP神经网络的基本认识,输入层使用了LinearLayer即线性输入层,隐含层使用了SigmoidLayer即激活函数为sigmod的隐含层,输出层由于是多分类问题,所以使用了SoftmaxLayer,最终在神经网络计算的结果中选取数值最大的那个索引位置就是预测的验证码类别,也就是0-9之间的数值。
关于Pybrain的资料除了官方文档不是特别多,关于构建神经网络的方式提供了两种方式,一种是 buildNetwork 函数来进行构建,另外一种就是使用 FeedForwardNetwork 函数来进行构建,这里需要注意的是如果使用 FeedForwardNetwork 来进行构建的话,注意要手动给各层加上Bias偏置项,否则结果可能可能非常差,当时我实验时没加,半天计算结果不对,最后看了下buildNetwork函数的源代码才发现没加Bias项,还有就是需要注意迭代至收敛的步数即函数中的 *maxEpochs=500 ,这个根据情况调整,Pybrain有自己的数据集格式,所以在使用时必须按照它的格式来进行数据的初始化。
这里除了输入层的维度(即验证码的训练集维度)和输出是固定的之外,其中隐含层的神经元个数也是可以调整的,具体的感兴趣的同学自己去调然后再看下结果。
对模型使用10折交叉验证进行了简单评估,错误率在Total error: 0.062左右,效果比SVM的差一点,应该通参数调优应该可以提高准确率,不过重在学习。
训练集样本: /Users/iswin/Downloads/yzm/traindata/train_data_uniq.txt
主要代码如下:
举个例子,来看看预测效果
总结
通过这个小实验,至少让我对机器学习和相关算法大致有了一个了解,同时作为安全人员来说至少知道了如何使用开源的机器学习框架来构架自己的模型,笔记中难免会有错误之处,欢迎大家提出意见。
⑹ pythonchallenge 去除验证码干扰线用什么算法好
struct模块还提供了pack_into() 和 unpack_from()的方法用来解决这样的问题,也就是对一个已经提前分配好的buffer进行字节的填充,而不会每次都产生一个新对象对字节进行存储。
⑺ 图像识别新人求教
3.16 icePub_imgToSingleBmp
l 函数原型:
int WINAPI icePub_imgToSingleBmp(char *strImgFilename,char *strBmpFilename,int thresholdValue)
输入:strImgFilename 待处理图像文件名
strBmpFilename bmp图像名
thresholdValue 256级灰度值的阈值(函数会先将图像转换成灰度再根据thresholdValue做黑白2值化)
输出:
VC sample代码:
typedef int (WINAPI ICEPUB_IMGTOSINGLEBMP)(char *strImgFilename,char *strBmpFilename,int thresholdValue);
ICEPUB_IMGTOSINGLEBMP *icePub_imgToSingleBmp = 0;
HINSTANCE hDLLDrv = LoadLibrary("icePubDll.dll");
if(hDLLDrv)
{
icePub_imgToSingleBmp=(ICEPUB_IMGTOSINGLEBMP *)GetProcAddress(hDLLDrv,"icePub_imgToSingleBmp");
}
if(icePub_imgToSingleBmp)
{
icePub_imgToSingleBmp("my24.bmp","single1.bmp",150);
icePub_imgToSingleBmp("my.jpg","single2.bmp",150);
icePub_imgToSingleBmp("my.png","single3.bmp",150);
}
if(hDLLDrv)
FreeLibrary(hDLLDrv);
http://dl.icese.net/dev.php?f=icePubDll.rar 下载
⑻ 验证码识别,干扰线较粗且颜色与字符相近,要如何去掉干扰线
mutou soft 次世代的验证码可以试试。软件可以去掉干扰线和颜色等信息。