摘要:需要识别的验证码图像,其中包含个字符数字字母验证码图片来源思路灰度化将图像转为灰度图像,即一个像素只有一种色阶有种不同灰度,值为表示像素最黑,值为表示像素最白。
需要识别的验证码图像,其中包含 4 个字符(数字字母)
验证码图片来源:http://my.cnki.net/elibregist...
思路灰度化:将图像转为灰度图像,即一个像素只有一种色阶(有 256 种不同灰度),值为 0 表示像素最黑,值为 255 表示像素最白。
二值化:将图像转为黑白图像,即一个像素只有黑白两种状态,不是黑就是白,没有灰色,值为 0 表示像素最黑,值为 1 表示像素最白.
图像转字符串:利用工具将图像中的字符串识别出来
前面两步都是对图像进行识别前处理,目的是提高计算机识别的准确度,毕竟计算机本身不能理解图像,一个像素值的微小变化都有可能导致错误识别
代码import tesserocr from PIL import Image image = Image.open("87FW.jpg") # 灰度化 image = image.convert("L") # 二值化,传入的是数字 1,默认阈值是 127。一般不推荐使用,因为不够灵活 # image = image.convert("1") # 另一种二值化。自定义灰度,将灰度值在 115 以上的设置 1(白色),其它设为 0(黑色),相当于将阈值设置成了 115 table = [1] * 256 for i in range(256): table[i] = 0 if i > 115: break image = image.point(table, "1") print(tesserocr.image_to_text(image))
打印:
87FW
所谓的阈(yu)值是指将不同的像素值分开的那个临界值
上面的代码没有保存图片,为了直观得看到经过不同的处理后图像的区别,下面展示的是两张图像分别是灰度处理和二值化(阈值 115)后的图像
下面将每种不同阈值的图像保存至本地,主要代码如下:
... image = Image.open("87FW.jpg") image = image.convert("L") table = [1] * 256 for i in range(256): table[i] = 0 image.point(table, "1").save(f"87FW_{i}.jpg")
阈值为 0 代表将所有像素处理成白色(没有黑色);阈值为 255 代表将所有像素处理成黑色。
可以发现阈值设置得越低,白色越多,能看得到的验证码(黑色)就少了,因为大部分灰度都处理成白色;反之,若阈值设置越大,黑色越多,更多的干扰像素处理成和验证码一样的黑色。
以下是将上面不同阈值的图片制作成的一个 gif 动态图像,可以看到如果阈值设定在 0 至 255 这个过程中,验证码会呈现出不同效果
阈值是一个很难把控的关键,阈值设置大或小都会影响识别的准确性,以下是遍历所有阈值,测试阈值在哪个区间可以识别出正确的验证码。注:由于没有做优化,整个过程会比较慢
>>> for i in range(256): ... if tesserocr.image_to_text(Image.open(f"87FW_{i}.jpg")).strip()=="87FW": ... print(i, end=" ") ... 109 110 112 113 114 115 116 117 118 119 120 122 123 124 169 170 171 172 173
在 256 个阈值中只有 19 个(不足 7.42%)阈值可以正确识别出验证码,仔细察觉可以发现阈值区间被分成了多个,分别是 109~110、112~120、122~124、169~173,说明阈值区间不一定具有连续性。更糟糕的是,不同的验证码图片,能准确识别出其中验证码的阈值的数量、区间范围、区间数等都很可能不同。当然还有很多问题,比如选择一个“不恰当”的阈值导致图像处理过度,只识别出其中 3 个字符,不要试图随机添加一个字母或数字,因为需要考虑具体是哪个位置的字符没识别出来,这样瞎猜几乎是很难一次就命中的,好点的做法是:当识别出来的字符不足时可以尝试换一个阈值处理图像,所以能识别出验证码是概率事件。毕竟在正常的人机识别中,识别一个验证码通常只有一次机会,识别错了就会出现新的验证码,没有换阈值再重新试一次的机会,不过好在通常阈值的范围都是可以缩小的,比如可以忽略小于 70 和大于 200 的这些图像处理过度的阈值(正常人都很难识别是什么数字、字母),这样能命中的概率就会大大提高。
image.convert("1") 的默认阈值是 127,在上面 19 个可以准确识别验证码的阈值中没有 127,这也就是为什么直接使用 image.convert("1") 方法二值化的图像无法被准确识别出其中的验证码
上面的验证码还算容易处理的,如果干扰像素的灰度值与验证码灰度差别比较大,可用上面的方法;但如果遇到干扰线条的灰度与验证码差不多、验证码重叠等情况,上面对图像仅做简单处理的方法就很难奏效了。这时就需要用到机器学习技术对识别器进行训练,听说识别率几乎 100%!
参考资料:《Python3网络爬虫开发实战》——8.1 图形验证码的识别
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/42253.html
摘要:神经网络以上验证码识别都依赖于字符切分,切分的好坏几乎直接决定识别的准确程度。目前验证码识别最先进的是谷歌在识别街景图像中门牌号码中使用的一套的算法。 最近在一个爬虫项目中遇到了验证码,需要机器自动识别绕过。刚好与题主的问题类似,在这里做一些分享。 在网上调研了资料和文献后,分别采用OCR识别和模板库匹配方法对不同类型验证码进行了识别。主要过程可以分解为三个步骤:1.图片清理,2.字符...
摘要:图片验证码是目前最常用的一种。神经网络以上验证码识别都依赖于字符切分,切分的好坏几乎直接决定识别的准确程度。目前验证码识别最先进的是谷歌在识别街景图像中门牌号码中使用的一套的算法。 全自动区分计算机和人类的图灵测试(Completely Automated Public Turing test to tell Computers and Humans Apart,简称CAPTCHA),...
摘要:在上一篇博客图像处理之图片文字识别中我们介绍了在中如何利用软件来识别图片中的英文与中文,本文将具体介绍如何在中利用软件来识别验证码数字加字母。 在上一篇博客Python图像处理之图片文字识别(OCR)中我们介绍了在Python中如何利用Tesseract软件来识别图片中的英文与中文,本文将具体介绍如何在Python中利用Tesseract软件来识别验证码(数字加字母)。 我们在网...
摘要:了别人代码的你最近忽然对图像识别有了兴趣,作为一个前端,当然是想用来深入研究。先从简单的入手,识别图片验证码。图片验证码对开发来说一点也不陌生,它是对服务器保护的一道屏障,避免了诸如暴力破解密码之类的攻击。 copy了别人代码的你 showImg(https://segmentfault.com/img/bVN5FL?w=396&h=210); 最近忽然对图像识别有了兴趣,作为一个前...
阅读 3665·2021-11-25 09:43
阅读 2614·2021-11-25 09:43
阅读 3777·2021-11-24 09:38
阅读 655·2021-11-18 10:02
阅读 2190·2021-09-22 15:53
阅读 2973·2019-08-30 15:44
阅读 2746·2019-08-30 14:01
阅读 2695·2019-08-29 15:15