使用Pillow对CAPTCHA图像进行处理
作为一个练习,我正在尝试破解以下的验证码:
看起来破解这个验证码并不太难,因为边缘看起来比较清晰,噪点应该也比较容易去掉。问题是,我对图像处理的经验很少。目前我正在使用Python和Pillow库来处理这个验证码图像,处理完后会把它传给Tesseract进行文字识别。
在下面的代码中,我尝试通过锐化图像来突出边缘,然后把图像转换成黑白色:
from PIL import Image, ImageFilter
try:
img = Image.open("Captcha.jpg")
except:
print("Can't load captcha.")
exit()
# Bring out the edges by sharpening.
out = img.filter(ImageFilter.SHARPEN)
out = out.convert("L")
out = out.point(lambda x: 0 if x<136 else 255, "1")
width, height = out.size
out = out.resize((width*5, height*5), Image.NEAREST)
out.save("captcha_modified.png")
此时我看到的结果是:
不过,Tesseract还是无法识别这些字符。作为实验,我用老掉牙的画图工具手动修改了图像,直到它可以被Tesseract识别:
所以如果我能把图像处理到那个程度,我觉得Tesseract会比较好地识别字符。因此我现在的想法是需要增强边缘并减少图像中的噪点。此外,我想如果字母是填充的而不是轮廓的话,Tesseract识别字母会更容易,但我不知道该怎么做。
有没有什么建议可以帮助我?有没有更好的方法来处理这些图像?
1 个回答
我时间有限,所以这个回答可能不是特别有用,但我会简单介绍我自己的两个算法。代码不多,主要是一些方法推荐。用代码来处理问题比用MS Paint要好得多。其实,破解验证码并达到超过50%的成功率是相对简单的。行为识别可能是更好的安全机制,或者可以作为一种额外的手段。
A. 边缘检测方法:
其实边缘检测并不是必须的。在这种情况下,只需要使用getpixel((x,y))函数,填充边界线之间的区域,记得在1、3、5等行填充,然后在2、4、6等行交叉时停止填充。幸运的是,你选择了一个简单的验证码,所以边缘检测在不需要清理、旋转和重新对齐的情况下是个不错的解决方案。
B. 操作方法:
我使用的另一种方法也利用了OpenCV和Pillow。我现在很忙,但稍后会在druid5.wordpress.com/上发布一篇博客文章,其中会包含这个方法的代码示例。听说通过验证码并不违法,所以我常常使用我将要发布的方法来收集数据。主要是用Pillow处理对比度和细节,进行一些基本的杂乱清理,使用基本的深度优先搜索(DFS)进行重新对齐,以及旋转(可以用OpenCV或简单的内核来实现)。Tesseract是一个不错的开源选择,但用OpenCV创建一个OCR也并不难。
这个练习是一个不错的OpenCV、PIL(Pillow)、数学图像处理以及其他一些有助于从机器人到人工智能的内容的入门介绍。
使用流程控制来找到失败的条件并尝试不同的路径可能是必要的,但目标应该始终是一个通用的解决方案。