博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Python进行验证码识别
阅读量:4149 次
发布时间:2019-05-25

本文共 3722 字,大约阅读时间需要 12 分钟。

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

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

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

pic

pic1

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

  1.       im = Image.open(image_name)
  2.           im = im.filter(ImageFilter.MedianFilter())
  3.           enhancer = ImageEnhance.Contrast(im)
  4.           im = enhancer.enhance(2)
  5.           im = im.convert('1')
  6.           im.show()
接下来就是提取这些数字的字模,使用shell脚本下载100幅图片,抽出三张图片获取字模:

  1.       #!/usr/bin/env python
  2.       #encoding=utf-8
  3.       import Image,ImageEnhance,ImageFilter
  4.       import sys
  5.       image_name = "./images/81.jpeg"
  6.       im = Image.open(image_name)
  7.       im = im.filter(ImageFilter.MedianFilter())
  8.       enhancer = ImageEnhance.Contrast(im)
  9.       im = enhancer.enhance(2)
  10.       im = im.convert('1')
  11.       #im.show()
  12.                       #all by pixel
  13.       s = 12          #start postion of first number
  14.       w = 10          #width of each number
  15.       h = 15          #end postion from top
  16.       t = 2           #start postion of top
  17.       im_new = []
  18.       #split four numbers in the picture
  19.       for i in range(4):
  20.           im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
  21.           im_new.append(im1)
  22.       f = file("data.txt","a")
  23.       for k in range(4):
  24.           l = []
  25.           #im_new[k].show()
  26.           for i in range(13):
  27.               for j in range(10):
  28.                   if (im_new[k].getpixel((j,i)) == 255):
  29.                       l.append(0)
  30.                   else:
  31.                       l.append(1)
  32.           f.write("l=[")
  33.           n = 0
  34.           for i in l:
  35.               if (n%10==0):
  36.                   f.write("/n")
  37.               f.write(str(i)+",")
  38.               n+=1
  39.           f.write("]/n")

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

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

  1.       #!/usr/bin/env python
  2.       #encoding=utf-8
  3.       import Image,ImageEnhance,ImageFilter
  4.       import Data
  5.       DEBUG = False
  6.       def d_print(*msg):
  7.           global DEBUG
  8.           if DEBUG:
  9.               for i in msg:
  10.                   print i,
  11.               print
  12.           else:
  13.               pass
  14.       def Get_Num(l=[]):
  15.           min1 = []
  16.           min2 = []
  17.           for n in Data.N:
  18.               count1=count2=count3=count4=0
  19.               if (len(l) != len(n)):
  20.                   print "Wrong pic"
  21.                   exit()
  22.               for i in range(len(l)):
  23.                   if (l[i] == 1):
  24.                       count1+=1
  25.                       if (n[i] == 1):
  26.                           count2+=1
  27.               for i in range(len(l)):
  28.                   if (n[i] == 1):
  29.                       count3+=1
  30.                       if (l[i] == 1):
  31.                           count4+=1
  32.               d_print(count1,count2,count3,count4)
  33.               min1.append(count1-count2)
  34.               min2.append(count3-count4)
  35.           d_print(min1,"/n",min2)
  36.           for i in range(10):
  37.               if (min1[i] <= 2 or min2[i] <= 2):
  38.                   if ((abs(min1[i] - min2[i])) <10):
  39.                       return i
  40.           for i in range(10):            
  41.               if (min1[i] <= 4 or min2[i] <= 4):
  42.                   if (abs(min1[i] - min2[i]) <= 2):
  43.                       return i
  44.           for i in range(10):
  45.               flag = False
  46.               if (min1[i] <= 3 or min2[i] <= 3):
  47.                   for j in range(10):
  48.                       if (j != i and (min1[j] <5 or min2[j] <5)):
  49.                           flag = True
  50.                       else:
  51.                           pass
  52.                   if (not flag):
  53.                       return i
  54.           for i in range(10):            
  55.               if (min1[i] <= 5 or min2[i] <= 5):
  56.                   if (abs(min1[i] - min2[i]) <= 10):
  57.                       return i
  58.           for i in range(10):
  59.               if (min1[i] <= 10 or min2[i] <= 10):
  60.                   if (abs(min1[i] - min2[i]) <= 3):
  61.                       return i
  62.       #end of function Get_Num
  63.       def Pic_Reg(image_name=None):
  64.           im = Image.open(image_name)
  65.           im = im.filter(ImageFilter.MedianFilter())
  66.           enhancer = ImageEnhance.Contrast(im)
  67.           im = enhancer.enhance(2)
  68.           im = im.convert('1')
  69.           im.show()
  70.                           #all by pixel
  71.           s = 12          #start postion of first number
  72.           w = 10          #width of each number
  73.           h = 15          #end postion from top
  74.           t = 2           #start postion of top
  75.           im_new = []
  76.           #split four numbers in the picture
  77.           for i in range(4):
  78.               im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
  79.               im_new.append(im1)
  80.           s = ""
  81.           for k in range(4):
  82.               l = []
  83.               #im_new[k].show()
  84.               for i in range(13):
  85.                   for j in range(10):
  86.                       if (im_new[k].getpixel((j,i)) == 255):
  87.                           l.append(0)
  88.                       else:
  89.                           l.append(1)
  90.               s+=str(Get_Num(l))
  91.           return s
  92.       print Pic_Reg("./images/22.jpeg")
这里再提一下验证码识别的基本方法:截图,二值化、中值滤波去噪、分割、紧缩重排(让高矮统一)、字库特征匹配识别。
这里只是针对一般的验证码,高级验证码的识别
文章原帖:
http://www.17lamp.net/forum/lamp/20081116092405

转载地址:http://aesti.baihongyu.com/

你可能感兴趣的文章
3.5 YOLO9000: Better,Faster,Stronger(YOLO9000:更好,更快,更强)
查看>>
iOS菜鸟学习--如何避免两个按钮同时响应
查看>>
iOS菜鸟学习—— NSSortDescriptor的使用
查看>>
CORBA links
查看>>
如何使用BBC英语学习频道
查看>>
初识xsd
查看>>
java 设计模式-职责型模式
查看>>
构造型模式
查看>>
svn out of date 无法更新到最新版本
查看>>
java杂记
查看>>
RunTime.getRuntime().exec()
查看>>
Oracle 分组排序函数
查看>>
删除weblogic 域
查看>>
VMware Workstation 14中文破解版下载(附密钥)(笔记)
查看>>
日志框架学习
查看>>
日志框架学习2
查看>>
SVN-无法查看log,提示Want to go offline,时间显示1970问题,error主要是 url中 有一层的中文进行了2次encode
查看>>
NGINX
查看>>
Qt文件夹选择对话框
查看>>
DeepLearning tutorial(5)CNN卷积神经网络应用于人脸识别(详细流程+代码实现)
查看>>