python验证码去噪
㈠ python抓取网页时是如何处理验证码的
python抓取网页时是如何处理验证码的?下面给大家介绍几种方法:
1、输入式验证码
这种验证码主要是通过用户输入图片中的字母、数字、汉字等进行验证。如下图:
解决思路:这种是最简单的一种,只要识别出里面的内容,然后填入到输入框中即可。这种识别技术叫OCR,这里我们推荐使用Python的第三方库,tesserocr。对于没有什么背影影响的验证码如图2,直接通过这个库来识别就可以。但是对于有嘈杂的背景的验证码这种,直接识别识别率会很低,遇到这种我们就得需要先处理一下图片,先对图片进行灰度化,然后再进行二值化,再去识别,这样识别率会大大提高。
相关推荐:《Python入门教程》
2、滑动式验证码
这种是将备选碎片直线滑动到正确的位置,如下图:
解决思路:对于这种验证码就比较复杂一点,但也是有相应的办法。我们直接想到的就是模拟人去拖动验证码的行为,点击按钮,然后看到了缺口的位置,最后把拼图拖到缺口位置处完成验证。
第一步:点击按钮。然后我们发现,在你没有点击按钮的时候那个缺口和拼图是没有出现的,点击后才出现,这为我们找到缺口的位置提供了灵感。
第二步:拖到缺口位置。
我们知道拼图应该拖到缺口处,但是这个距离如果用数值来表示?
通过我们第一步观察到的现象,我们可以找到缺口的位置。这里我们可以比较两张图的像素,设置一个基准值,如果某个位置的差值超过了基准值,那我们就找到了这两张图片不一样的位置,当然我们是从那块拼图的右侧开始并且从左到右,找到第一个不一样的位置时就结束,这是的位置应该是缺口的left,所以我们使用selenium拖到这个位置即可。
这里还有个疑问就是如何能自动的保存这两张图?
这里我们可以先找到这个标签,然后获取它的location和size,然后 top,bottom,left,right = location['y'] ,location['y']+size['height']+ location['x'] + size['width'] ,然后截图,最后抠图填入这四个位置就行。
具体的使用可以查看selenium文档,点击按钮前抠张图,点击后再抠张图。最后拖动的时候要需要模拟人的行为,先加速然后减速。因为这种验证码有行为特征检测,人是不可能做到一直匀速的,否则它就判定为是机器在拖动,这样就无法通过验证了。
3、点击式的图文验证和图标选择
图文验证:通过文字提醒用户点击图中相同字的位置进行验证。
图标选择: 给出一组图片,按要求点击其中一张或者多张。借用万物识别的难度阻挡机器。
这两种原理相似,只不过是一个是给出文字,点击图片中的文字,一个是给出图片,点出内容相同的图片。
这两种没有特别好的方法,只能借助第三方识别接口来识别出相同的内容,推荐一个超级鹰,把验证码发过去,会返回相应的点击坐标。
然后再使用selenium模拟点击即可。具体怎么获取图片和上面方法一样。
4、宫格验证码
这种就很棘手,每一次出现的都不一样,但是也会出现一样的。而且拖动顺序都不一样。
但是我们发现不一样的验证码个数是有限的,这里采用模版匹配的方法。我觉得就好像暴力枚举,把所有出现的验证码保存下来,然后挑出不一样的验证码,按照拖动顺序命名,我们从左到右上下到下,设为1,2,3,4。上图的滑动顺序为4,3,2,1,所以我们命名4_3_2_1.png,这里得手动搞。当验证码出现的时候,用我们保存的图片一一枚举,与出现这种比较像素,方法见上面。如果匹配上了,拖动顺序就为4,3,2,1。然后使用selenium模拟即可。
㈡ 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 像素的二值图像是现实中是比较理想的,达到了识别速度快和识别准确率高的较好的平衡点。
三、识别
图像识别包括特征提取、样本训练和识别三大块内容。
验证码识别其中最为关键的就是去噪和分割,这对你的训练和识别的精度都有着很大的影响。这里只讲了大致的流程,其中每个细节都有很多工作要做,这里码字也很难讲清楚,大家可以以这个流程为主线,一步步的实现,最终也就能完成你的需求。
㈢ 验证码识别之模板匹配方法
在写爬虫的时候难免会遇到验证码识别的问题,常见的验证码识别的流程为:
- 图像灰度化
- 图像去噪(如图像二值化)
- 切割图片
- 提取特征
- 训练
但这种方法要切割图片,而且破解验证码的重点和难点就在于 能否成功分割字符 。
本文要介绍的算法 不需要进行图片切割,也不需要进行机器训练 ,这种方法就是模板匹配:将待识别的文字切割成一个个模板,在待识别的图像中去匹配模板。
这篇文章将分为两个部分:
第一部分介绍模板匹配的基本概念以及模板匹配的一种实现算法:快速归一化互相关匹配算法;
第二部分是一个具体实例。
模板匹配是在图像中寻找目标的方法之一,目的就是在一幅图像中寻找和模板图像最相似的区域。
模板匹配的大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。
假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
用某种方法得出临时图像与模板的相似度c,存放到相似度矩阵中(矩阵大小为91 x91);
切割输入图像从(0,1)至(10,11)的临时图像,对比,并记录到相似度矩阵;
重复上述步骤,直到输入图像的右下角。
最终得到一个相似度矩阵,找到矩阵中的最大或最小值,最大值(最小值)对应的临时图像即为与模板最相似的图像。
在步骤b中,求模板与图像的相似度有多种方法,如平均绝对差算法(MAD)、绝对误差和算法(SAD)、误差平方和算法(SSD)、归一化互相关算法(NCC),本文使用的是归一化互相关算法。
什么是归一化互相关?
从几何图形上来看,空间中的两个向量,同方向平行时,归一化互相关系数为1,表示两个向量最相似,反方向平行时归一化互相关系数为-1,垂直时为0,表示最不相似(用互相垂直的三个向量来代表整个空间也是这个道理,垂直的向量之间不包含对方的信息,相关系数为0),存在一定夹角时处于(-1,1),是不是跟余弦函数很像,cos(0)=1,cos(pi/2)=0,cos(pi)=-1。就是这个样子的,相关系数可以看作是两个向量之间夹角的cosine函数。
在数学中是这么计算cosine函数的,假设两个n维向量X,Y,对应的坐标分别为(x1,x2,…xn), (y1,y2,…yn) 则:
(如果想要了解更多,请参考文献【2】)
但这是一维的,在模板匹配中要再加一个维度 (具体算法请参考文献【3】) ,简要说一下文献【3】的内容:如果直接计算二维相似度的话计算复杂度会非常高,文献【3】利用快速傅里叶变换与积分图像快速算法来降低计算复杂度。
接下来让我们看一个具体的应用。
模板匹配识别验证码的具体步骤为:
1. 找出图片中所有可能出现的字符,制作成模板集合
2. 图像灰度化
3. 图片去噪(二值化)
4. 模板匹配
5. 匹配结果优化
要识别的图片如下,以识别图片中的加字为例:
要从image中找到与模板最匹配的部分,Template图像是事先从image图像中截取的一部分。所用的为python模块skimage中的match_template方法,match_template方法使用的是快速归一化互相关算法 【2】 。
遍历模板图像集合,与图像匹配,如果dist大于阈值h,则认为此模板在图像中存在,否则不存在,继续匹配下一个模板,直到遍历完所有模板。
以模板‘加’为例,图像大小为40x260,模板大小27x27,result是一个大小为(14,234)的矩阵,即上文提到的相似度矩阵,矩阵中的数值属于[-1,1],找到result中最大值所处的对应位置即为与模板最匹配的图像位置:x=66,y=11,正好对应模板图像在image中所处的位置。 (更多内容请参阅参考文献【4】)
但这是比较好的情况,因为在匹配时遍历了所有的模板,而一张图片中出现的模板数量是有限的,比如数字’四’在图片中是没有的,这时就要根据某种规则去掉这些在图片中没有出现的模板:程序中使用dist变量来过滤匹配结果,如果dist变量大于某个值则认为此模板在图像中不存在。
最后的result_list中可能仍然存在一些图片中不存在的模板或者匹配不精确的模板,比如数字‘一’在模板中不存在,但仍然可以匹配到,因为数字‘二’中可以匹配到‘一’,需要进一步优化,优化方法有很多,比如当匹配到的两个模板距离过近时,选择较大的那个模板,其余方法留给读者自行考虑吧。
后续将会推出如何使用深度学习识别验证码,敬请期待~
参考文献:
http://www.cnblogs.com/beer/p/5672678.html
http://www.ruanyifeng.com/blog/2013/03/cosine_similarity.html
J. P. Lewis, “Fast Normalized Cross-Correlation”, Instrial Light and Magic.
http://scikit-image.org/docsjinhqin/dev/auto_examples/plot_template.html
本文作者 :李晖(点融黑帮),毕业于电子科技大学,现就职于点融成都Data部门,对一切新鲜事物充满好奇,对跳舞毫无抵抗力的活力女青年一枚。
㈣ 如何用python svd降噪
from recsys.algorithm.factorize import SVD
svd = SVD()
svd.load_data(dataset)
svd.compute(k=100, mean_center=True)
ITEMID1 = 1 # Toy Story
svd.similar(ITEMID1)
# Returns:
# [(1, 1.0), # Toy Story
# (3114, 0.87060391051018071), # Toy Story 2
# (2355, 0.67706936677315799), # A bug's life
# (588, 0.5807351496754426), # Aladdin
# (595, 0.46031829709743477), # Beauty and the Beast
# (1907, 0.44589398718134365), # Mulan
# (364, 0.42908159895574161), # The Lion King
# (2081, 0.42566581277820803), # The Little Mermaid
# (3396, 0.42474056361935913), # The Muppet Movie
# (2761, 0.40439361857585354)] # The Iron Giant
ITEMID2 = 2355 # A bug's life
svd.similarity(ITEMID1, ITEMID2)
# 0.67706936677315799
㈤ 如何利用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机器学习库
准备原始图片素材
图片预处理
图片字符切割
图片尺寸归一化
图片字符标记
字符图片特征提取
生成特征和标记对应的训练数据集
训练特征标记数据生成识别模型
使用识别模型预测新的未知图片集
达到根据“图片”就能返回识别正确的字符集的目标
- def get_feature(img): """
- 获取指定图片的特征值,
- 1. 按照每排的像素点,高度为10,则有10个维度,然后为6列,总共16个维度
- :param img_path:
- :return:一个维度为10(高度)的列表 """
- width, height = img.size
- pixel_cnt_list = []
- height = 10 for y in range(height):
- pix_cnt_x = 0 for x in range(width): if img.getpixel((x, y)) == 0: # 黑色点
- pix_cnt_x += 1
- pixel_cnt_list.append(pix_cnt_x) for x in range(width):
- pix_cnt_y = 0 for y in range(height): if img.getpixel((x, y)) == 0: # 黑色点
- pix_cnt_y += 1
- pixel_cnt_list.append(pix_cnt_y) return pixel_cnt_list
关于环境的安装,不是本文的重点,故略去。
6基本流程
一般情况下,对于字符型验证码的识别流程如下:
7素材准备
7.1素材选择
由于本文是以初级的学习研究目的为主,要求“有代表性,但又不会太难”,所以就直接在网上找个比较有代表性的简单的字符型验证码(感觉像在找漏洞一样)。
最后在一个比较旧的网站(估计是几十年前的网站框架)找到了这个验证码图片。
原始图:
然后就将图片素材特征化,按照libSVM指定的格式生成一组带特征值和标记值的向量文
㈥ 怎样用python实现图像去噪
#coding:utf-8
importsys,os
fromPILimportImage,ImageDraw
#二值数组
t2val={}
deftwoValue(image,G):
foryinxrange(0,image.size[1]):
forxinxrange(0,image.size[0]):
g=image.getpixel((x,y))
ifg>G:
t2val[(x,y)]=1
else:
t2val[(x,y)]=0
#降噪
#根据一个点A的RGB值,与周围的8个点的RBG值比较,设定一个值N(0<N<8),当A的RGB值与周围8个点的RGB相等数小于N时,此点为噪点
#G:Integer图像二值化阀值
#N:Integer降噪率0<N<8
#Z:Integer降噪次数
#输出
#0:降噪成功
#1:降噪失败
defclearNoise(image,N,Z):
foriinxrange(0,Z):
t2val[(0,0)]=1
t2val[(image.size[0]-1,image.size[1]-1)]=1
forxinxrange(1,image.size[0]-1):
foryinxrange(1,image.size[1]-1):
nearDots=0
L=t2val[(x,y)]
ifL==t2val[(x-1,y-1)]:
nearDots+=1
ifL==t2val[(x-1,y)]:
nearDots+=1
ifL==t2val[(x-1,y+1)]:
nearDots+=1
ifL==t2val[(x,y-1)]:
nearDots+=1
ifL==t2val[(x,y+1)]:
nearDots+=1
ifL==t2val[(x+1,y-1)]:
nearDots+=1
ifL==t2val[(x+1,y)]:
nearDots+=1
ifL==t2val[(x+1,y+1)]:
nearDots+=1
ifnearDots<N:
t2val[(x,y)]=1
defsaveImage(filename,size):
image=Image.new("1",size)
draw=ImageDraw.Draw(image)
forxinxrange(0,size[0]):
foryinxrange(0,size[1]):
draw.point((x,y),t2val[(x,y)])
image.save(filename)
image=Image.open("d:/1.jpg").convert("L")
twoValue(image,100)
clearNoise(image,4,1)
saveImage("d:/5.jpg",image.size)