背景:朋友在为"关山口男子职业技术学校"写一款校园应用,于是找MoonXue写一个学生选课系统的登录接口.为了搞定这个接口,不得不先搞定这个系统的验证码.

验证码大概是这个样子如何用python搞定验证码中的噪点

看上去不怎么难,没有干扰线没有粘连没有扭曲.但还是没能用pytesser直接将它识别出来,因为当中有噪点和其他背景噪声的存在.MoonXue的工作就是去掉这些讨厌的东西

先介绍一下,我们的工具:

1.Pytesser  它是基于一个c语言实现名为tesser的识别工具的python封装.可惜比较笨,只能做最简单的识别而且不认识汉字

2.Requests  它是我们喜欢写爬虫的孩子的最爱,提供人性化的接口,代价是失去了一点效率(写python就别考虑效率啦)

3.BeautifulSoup  它和Requests是一对好机油,让提取文档中所需的内容变成一件简单的事情

4.PIL      它是今天的主角,PIL是专门用作图像处理的库,很好很强大.熟练的人甚至可以用它来P图

如何写爬虫去实现模拟登录此处不细说,下面说说怎么解决验证码识别

解决思路如下:

1.先用PIL对图像做一次图像增强,因为原图中数字的边缘和背景中的噪声并不是太分明,做了增强之后能将两者分离.如果不分离,可能会在去噪点的时候导致数字中有部分会缺失

im = Image.open("randomimage/randomImage11.jpg")
im = ImageEnhance.Sharpness(im).enhance(3)

参数为3是经过实验之后感觉比较理想的值,太强不好,太弱也不好

2.做完预处理之后,就是去背景噪声了.背景噪声指的是背景中各种明暗变换的色块,肉眼也许不会注意到这个.但是它的存在会给识别带来影响.我最初的做法是将图像转换为只有黑白两色,这样自然就将噪声转换成了噪点.

效果如图如何用python搞定验证码中的噪点

但我希望能去掉噪点,成为这样如何用python搞定验证码中的噪点

 

 

最先想到的是种子染色法 ,什么是种子染色法请参看这个链接

为了防止坏链,此处做部分转载

种子染色法英文叫做Flood Fill ,实际上Flood Fill这个名称更贴切一点,因为这个方法作用在一个图的结点上时恰似洪水一样“淹没”与之相连的其他结点并以相同的方式蔓延出去,这个方法通常用于计算一个图的极大连通子图(这里的“图”是图论的概念)。设想一个无向图,我们从这个图中一个未标号(“标号”可以理解为“染色”)的结点开始,将此结点和从这个结点出发可达的所有结点都赋予相同的标号(染上相同的颜色),那么我们就得到了这些被标号的结点所组成的一个极大连通子图,搜索下一个未标号的结点并重复上述过程我们便可以找到所有的极大连通子图。“染色”的过程可以用DFS或者BFS实现,如果结点数为V,边数为E,因为我们在Flood Fill过程中“造访”每个结点两次,“造访”每条边两次,所以得到所有极大连通子图的时间复杂度为o(V+E) 。

来自Wikipedia的一个示例:

如何用python搞定验证码中的噪点

想象每个白色方块为图中的结点,相邻的方块(上下左右)有边相连,那么这个图就有三个极大连通子图,这演示了Flood Fill查找其中一个极大连通子图的过程。

在这是借要用种子染色法计算每块的面积,然后把小体积的块当作噪点去除.

代码在这

def check(j,i):
    try:
        if pix[j,i] == 0 and matrix[j][i] != -1:
            return True
        else:
            return False
    except:
        return False
                
def juli(r,s):
    return abs(r[0]-s[0])+abs(r[1]-s[1])+abs(r[2]-s[2])
    
for i in range(w):
    for j in range(h):
        r = [0,0,0]
        s = [0,0,0]
        if pix[j,i] == 0:
            if check(j-1,i):
                r[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j-1,i))
                print r
                print s
                print "-"*55
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j-1][i]
                    maps[str(matrix[j][i])]+=1
            elif check(j-1,i-1):
                r[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j-1,i-1))
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j-1][i-1]
                    maps[str(matrix[j][i])]+=1
            elif check(j,i-1):
                r[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j-1,i))
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j][i-1]
                    maps[str(matrix[j][i])]+=1
            elif check(j+1,i+1):
                r[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j+1,i+1))
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j+1][i+1]
                    maps[str(matrix[j][i])]+=1
            elif check(j,i+1):
                r[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j,i+1))
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j][i+1]
                    maps[str(matrix[j][i])]+=1
            elif check(j-1,i+1):
                pr[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j-1,i+1))
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j-1][i+1]
                    maps[str(matrix[j][i])]+=1
            elif check(j+1,i-1):
                r[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j+1,i-1))
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j+1][i-1]
                    maps[str(matrix[j][i])]+=1
            elif check(j+1,i):
                r[0],r[1],r[2] = im2.getpixel((j,i)) 
                s[0],s[1],s[2] = im2.getpixel((j+1,i))
                if juli(r,s) <=l:
                    matrix[j][i] = matrix[j+1][i]
                    maps[str(matrix[j][i])]+=1
            else:
                n+=1
                maps[str(n)]=1
                matrix[j][i] = n

for i in range(w):
    for j in range(h):
        if matrix[j][i]!=-1 and maps[str(matrix[j][i])]<=2:
            im.putpixel((j,i),255)
View Code

相关文章:

  • 2021-05-01
  • 2021-04-03
  • 2022-12-23
  • 2021-08-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-11-16
  • 2022-01-03
  • 2021-12-14
相关资源
相似解决方案