需要识别的验证码图像,其中包含 4 个字符(数字字母)

思路

灰度化:将图像转为灰度图像,即一个像素只有一种色阶(有 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 图形验证码的识别

python数字字母识别_字符图像识别——数字字母混合相关推荐

  1. python怎么识别字母数字的_python判断字符是否为字母和数字

    在使用python语言中的字符串方法时,可以使用它们判断字符串中是否有字母或数字或其他的构成.下面利用几个实例说明字符串方法的用法,操作如下: str_1 = "123" str_ ...

  2. python判断是不是字母_python判断字符是否为字母和数字

    在使用python语言中的字符串方法时,可以使用它们判断字符串中是否有字母或数字或其他的构成.下面利用几个实例说明字符串方法的用法,操作如下:python学习网,大量的免费python视频教程,欢迎在 ...

  3. python判断字符是否是数字和字母_python判断字符是否为字母和数字

    在使用python语言中的字符串方法时,可以使用它们判断字符串中是否有字母或数字或其他的构成.下面利用几个实例说明字符串方法的用法,操作如下:云海天教程网,大量的免费python教程,欢迎在线学习!s ...

  4. Python实现手写体数字图片识别+GUI界面+画板数字识别

    __pycache__文件夹是Python自动生成的,详细了解https://blog.csdn.net/yitiaodashu/article/details/79023987 其他各个文件在之后部 ...

  5. Python+TensorFlow+PyQt实现手写体数字图片识别+GUI界面+画板数字识别

    __pycache__文件夹是Python自动生成的,详细了解https://blog.csdn.net/yitiaodashu/article/details/79023987 其他各个文件在之后部 ...

  6. 卷积神经网络算法python实现车牌识别_车牌识别算法之CNN卷积神经网络

    原标题:车牌识别算法之CNN卷积神经网络 随着我国经济的发展,汽车,特别是小轿车的数量越来越多,智能交通管理系统应运而生.车牌智能自动识别作为智能交通管理系统中的重要组成部分,在智能交通管理中发挥着越 ...

  7. mysql c语言数字转字符串函数_C++_c语言标准库中字符转换函数和数字转换函数,字符转换为数字: #includest - phpStudy...

    c语言标准库中字符转换函数和数字转换函数 字符转换为数字: #include atoi();将字符转换为整型   例:char ch1;int i=atoi(ch1); atol();将字符转化为长整 ...

  8. 数字孪生营销_如何通过数字营销增加您的自由职业收入

    数字孪生营销 There are a lot of ways we could go with this topic as it's a huge one, but I just want to co ...

  9. 数字旅游解决方案_什么是数字标牌?

    随着数字标牌越来越多地影响着我们的生活并为商业世界带来机遇,它的功能也从被动式的系统发展到将内容推送到更高级的系统,该系统可以实时地连接,交互和从各种来源获取内容. 那么什么是数字标牌呢? 维基百科写 ...

  10. java验证字符是否为字母_Java程序检查字符是否为字母

    Java程序检查字符是否为字母 在此程序中,您将学习检查给定字符是否为字母.这是使用Java中的if...else语句或三元运算符完成的. 示例1:使用if...else语句检查字母的Java程序 p ...

最新文章

  1. 一张图,一棵大树,六种人, 六载人生 ~
  2. python读取mtcars数据集并实现以下操作_Python可视化43 | plotnine≈R语言ggplot2,43plotnineR...
  3. Vue中使用el-popover实现悬浮弹窗显示图片预览
  4. Kafka消息序列化和反序列化(上)
  5. apple mac 下使用机械键盘的办法,键盘映射工具软件,apple mac Mechanical keyboard
  6. LINUX矩阵键盘简单介绍,stm32矩阵键盘原理图及程序介绍
  7. 【转】SSH中 整合spring和proxool 连接池
  8. java指定存入arraylist值_Java高效打印出0000-9999之间所有的值存到arraylist集合中
  9. mysql relay log 配置_mysql relay log参数汇总
  10. sql-server 不允许保存更改,解决办法
  11. 打印机扫描无法连接到计算机名,网络打印机无法扫描到电脑怎么处理
  12. 如何查计算机的开机启动程序,Win7系统电脑如何查看开机启动项?
  13. 简单的Java 16方格排序游戏
  14. redis+Python实现小型动态IP池的搭建,仅需90行代码
  15. Jetbot小车系列文章学习
  16. Android studio 多渠道打包(包括不同的包使用不同的资源文件、不同的包写不同的代码,包名等等)
  17. 艾默生质量流量计调试
  18. 成为或不成为开发者的拥护者
  19. 短文本匹配模型-ESIM
  20. 【Java】 8.7 使用红-黄-红色渐变来绘制一个填充矩形

热门文章

  1. epoll监听文件_Go 文件监控怎么实现?
  2. 金蝶K3案例教程库存报表
  3. 升级MacOS Big Sur之后VMware Fusion各种问题解决
  4. 如鹏网.Net三层架构第二章登录和会员管理
  5. 【建议收藏】产品经理面试题合集
  6. hadoop系列-hadoop版本选择
  7. AutoRunner 功能自动化测试项目实训之AutoRunner产品设计目标(三)
  8. 开放平台介绍以及目前国内主要的开放平台
  9. Java Web Spring框架学习(一)
  10. DTCC技术大会来了