前情提要
如图所示
本来是非常简单的一个验证码
使用pytesseract 识别失败
使用libsvm识别失败
使用tensflow识别成功
以上识别不成功不是因为库不好用,而是因为水平太低
正文
1. 环境
- windows,python版本3.7.0
- 在anconda中,python版本3.5.3
2. pytesseract识别失败过程
- 首先下载安装tesseract.exe文件,附上tesseract各种语言训练数据下载地址
- 在cmd中执行
pip install pytesseract
和pip install pillow
- 将test.png文件和python文件放在同一目录下测试,python文件内容
import pytesseract
from PIL import Image
print(pytesseract.image_to_string(Image.open('test.png')))
结果为空(= =!)
通过一番查询,才知道原来下载下来的验证码图片还需要进行进一步的处理,比如说二值化,去除噪点等操作,后来百度到字符型图片验证码识别完整过程及Python实现这篇文章,跟着教程来处理图片
- 二值化图片
#name:当前目录图片名称或绝对路径(这是最简单的二值化方法,还有更好的算法)
def get_bin_pic(name, threshold = 140):
table = []
for i in range(256);
if i < threshold:
table.append(0)
else:
table.append(1)
Img = Image.open(name)
Img = Img.convert("L")
Img = Img.point(table, "1")
Img.save(name) #覆盖原图片
get_bin_pic("test.png")
结果如图所示,可以看出噪点很多
- 降噪 参考文章:完整的图片去噪代码(python)
结果如图所示
这样就得到了一张比较干净的图片。经过这些处理再次调用最初的识别程序,结果依然为空。
tesseract还可以自己训练数据,简单的训练了一下,结果还是失败,这里就不讲了。
3. libsvm识别失败过程
既然tesseract识别失败,那么就转到libsvm上来,字符型图片验证码识别完整过程及Python实现这篇文章,讲的很详细,开头部分有源码,于是我把源码下载下来,准备测试一番。
- 准备工作:需要对图片进行切割,然后将图片放到[0-Z]等36个文件夹中。
- 图片切割代码
因为只有一个字符要切割,切位置固定,所以代码很简单。
from PIL import Image
import os
![def cut_img(name):
img = Image.open(name)
x = 6
y = 5
child_img = img.crop((x, y, x+15, y+15))
child_img.save(name)
将D:/pic
文件夹下的所有图片都切割
for root, dirs, files in os.walk("D:/pic"):
for name in files:
cut_img(name)
结果
- 然后手动将所有的切图手动放到[0-Z]的文件夹中,开始运行代码,经过代码的一番学习,运行结果识别率0%
出现这个原因我推测是因为数据的原因,毕竟文章的博主可以达到几乎100%的识别率,所以说只有可能是因为我的验证码数据量太少。
为了解决数据的问题,继续搜索。
3. tensorflow识别成功
15 分钟用 ML 破解一个验证码系统这篇文章中也提供了机器学习的源代码,
做了一番测试,发现可以识别自己的部分验证码,但是识别成功率还是不高,于是开始自己将之前保存的[0-Z]文件夹中的图片随机选取4个,然后拼接在一起,做成1w条数据,
拼接代码写的很烂
from PIL import Image
import os
import time
import os,sys
import random
def appendFile(fileDir):
pathDir = os.listdir(fileDir)
for i in pathDir:
all.append(fileDir + "/" + i)
def getpic():
path = "E:/svm/pic3"
dirs = os.listdir(path)
i = 0
for child_dirs in dirs:
i = i + 1
appendFile(path + "/" + child_dirs)
sample = random.sample(all, 4)
result = Image.new("RGB",(72, 24),color="#FFFFFF")
left = 0
right = 15
name = ""
for i in sample:
a = Image.open(i)
result.paste(a,(left,0, right, 15))
left += 15
right += 15
name+=os.path.dirname(i)[-1]
print(name)
result.save("E:/svm/new/"+name+".png")
if __name__ == '__main__':
for i in range(10000):
all = []
getpic()
print(i)
数据集有了,跑完之后识别一下发现效果还可以。但是整体上来说问题还是有的。
问题总结
- python 3.7不能直接使用
pip install tensorflow
python3.5,3.6版本可以 - 合图方法还需要完善,因为在训练的时候,它会自己建一个[0-Z]的文件夹,并将图片切好放进去,但是有一些图片会切出去空的文件,所以在训练数据的时候会报错,类似这种
cv2.error: /home/arthurckl/Desktop/opencv-3.0.0-rc1/modules/imgproc/src/color.cpp:7564: error: (-215) scn == 3 || scn == 4 in function cvtColor
,所以需要将空文件都删除。 - 作为菜鸟还需要继续提高。开始慢慢啃ML相关知识了,python也得往回捡捡不然就会像这篇文章里的剪牛鬃一样了。
愿世界没有bug