Python用KNN算法实现验证码识别

更新时间:2023-11-22 18:53:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Python用KNN算法实现验证码识别

作为一名爬虫爱好者,把互联网作为数据库的同时总会遇到很多坑,其中一个就是验证码,设置验证码一大理由就是为了限制你乱爬,不过对于很多简单的验证码,破解还是相当容易的。比如类似下面这种。最简单的办法是直接用pytesseract库,具体方法请自行搜索。当然如果不想用它,自己来写一个识别算法也并不难。可以用机器学习里面比较基础的KNN算法。

先来介绍一下这个KNN算法,他全称叫K最近邻(kNN,k-NearestNeighbor),所谓K最近邻,就是离谁最近,是谁的可能性就更大。什么意思,举个例子就明白了。 我现在已经统计了一组手机数据,方便起见,假设只有高端机和低端机两个分类,如下:此时如果有一个新手机T(1500元,15小时),该怎么判断是什么手机呢?我把它们放到同一个坐标系中去比较一下。它并不能很好地跟已知数据完全重合,但不要紧,可以算一下它与其他手机的距离。经过计算,与T的距离D就是这么简单。当然了,这里面只是举个例子所以数据量比较小,当数据量足够大时,比如有200台低端机和300台高端机,选出最接近的200个数据,其中哪种机器多就归到哪种,得出的结论就会比较准确。这就是最简单的KNN算法,离哪个近,就把它归类为哪个种类。这

是二维,还可以再加个“像素”属性,变为三维,仍然可以求最近距离。拓展到N个属性也是一样的道理。基本原理就是这样,下面来介绍如何识别验证码,以下代码基于Python3 还是这张验证码,我们把它放大一点可以看到,其实他就是一个一个的像素点构成的。

里面颜色太多不好操作,首先把这张图变成黑白的from PIL import Image#引入Image类

im = Image.open('图片路径')#打开图片

im=im.convert('1')#原来图片是彩色的,这里把图片转换成模式'1',即黑白的 im.show()#显示图片

于是我们就得到了这么一张图

可以把每个点的颜色转变成0和1,并打印出来for i in range(im.size[1]): temp=[]

for j in range(im.size[0]): pos=(j,i)

col=im.getpixel(pos)

#获取某坐标的点的颜色,黑色为0,白色为255,为了显示规程,把它转变成1了 if col==255: col=1

temp.append(col) print(temp)

可以从打印出来的字符中隐约看到这几个数字

然后处理一下这串字符,把不连续的点,即上下左右都没有同色的点去掉 im2 = im

for i in range(im.size[1]): for j in range(im.size[0]): #pos=(j,i) #print(pos)

if i==0 or j==0 or i==im.size[1]-1 or j==im.size[0]-1:

im2.putpixel((j,i),255)#图片最外面一周都换成白点

elif im.getpixel((j,i))!=im.getpixel((j-1,i)) and im.getpixel((j,i))!=im.getpixel((j+1,i)) and im.getpixel((j,i-1))!=im.getpixel((j,i)) and im.getpixel((j,i+1))!=im.getpixel((j,i)):

im2.putpixel((j,i),255)#不连续点也都换成白点

然后开始切割图片 inletter = False

foundletter = False start = 0 end = 0

letters = []#用来记录每个数字的起始位置

for x in range(im2.size[0]): for y in range(im2.size[1]): pix = im2.getpixel((x, y)) if pix != 255:

inletter = True#如果不是白色,这说明已经开始接触到数字了

if foundletter == False and inletter == True: foundletter = True start = x#数字的起始坐标

if foundletter == True and inletter == False: foundletter = False end = x-1#数字的结束位置 letters.append((start, end))

inletter = False

letters的值为[(7,

14), (20, 27), (33, 40), (46, 54)],就是每个数字的起始X坐标,同样道理获得每个数字的起始Y坐标,然后切割开来。region = (起始X值,起始Y值,结束X值,结束Y值) #裁切图片

im3 = im2.crop(region)#im3就是这个区域内的图形,也就是提取的数字 #im3.show()

于是得出了四个切割好的数字

这个时候怎么做呢,我们把第一个数字9用0和1来打印看看。[1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0,

0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1,

1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1,

1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0,

0, 1, 1, 0, 0, 1, 0, 1]总大小7*14,总共98个点 到这里差不多就出来了,把每个点看成一个属性,问题就转化成了:已知一个数有98个属性,也知道他的种类是9,同样,还有很多很多这样的数,知道属性+种类。然后要做的,就是拿N个样本作为标准集合,有新的数要识别的时候,选出最接近

的K个,这K个里面,数量最多的就是这个数的值。

本文来源:https://www.bwwdw.com/article/6zgv.html

微信扫码分享

《Python用KNN算法实现验证码识别.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档
下载全文
范文搜索
下载文档
Top