使用Python实现高效自动化图片组在线/离线识别(转文字)
图片识别转文字的两种方式:
在线识别
优点: 在线识别在初次进行文字识别的时候,准确率非常高。比如对聊天截图中的识别准确率就高达99%。因为在线识别使用了人工智能领域的深度学习算法和文字识别相结合的技术,能够把图片转换成文字后,还能在语义上把相近的字进行二次纠正。 比如说,被识别的内容包含英文单词“Hello”,一旦它的字母“o”被识别成数字“0”,在 线识别软件就会根据上下文语境把这类错误纠正回来,而这种二次纠正的功能在离线识别软 件中是没有的。
缺点:
- 识别文字的过程需要在公有云的服务器上完成。也 就是说需要通过互联网把图片上传到服务器,那么一旦图片过大,或者图片数量比较多,就会导致上传时间过长。对于一些大批量文字识别场景/实时性要求很高的场景,在线识别不能满足要求
- 图片需要经过互联网传输,识别以后的图片该怎么保存,怎么销毁,是不是会被其他 人得到,这些都是安全风险。总之,信息泄露的风险比较大。所以像公司的合同、财务资料 等涉密程度比较高的扫描件,很少使用在线识别。
离线识别
这种方式在识别过程中不需要连接网络,节省了在线传输图片的时间,适合那些对实时性要 求比较高或网络信号比较差的场景。
离线识别方式的问题就在于,初次识别文字的准确率比较低,识别完之后必须要经过人 工二次纠正才行。所以在前期人工校对,花费的时间相对来说会比较长。
在线识别
在线文字识别方式,识别的主要功能的需要放在公有云的服务器中才能实现,所以在代码实 现中就要考虑用户验证和图片加密传输问题。
用户验证能确保识别的结果交还给你本人,图片加密传输能确保图片上的信息不会被其他人 窃取到。这些功能,各个公有云的AI产品都考虑得非常周全,一般会提供给用户一个扩展 库。你要做的,就是安装这些扩展库。
以百度Ai图片转文字识别产品为例
pip install baidu-aip
1 | from aip import AipOcr |
当把这三个变量传入AipOcr函数,使用AipOcr函数通过互联网交互后,就可以用来识别用户 是不是被授权使用相应的产品,之后就可以把图片加密发送到AI产品的服务器上了。
离线识别(pytesseract)
1 | import pytesseract |
遇到问题
TesseractNotFoundError: tesseract is not installed or it’s not in your PATH. See README file for more information.
原因:
pytesseract是依赖c++编写的tesseract工具才能正常工作的,需要先安装teseract
解决:
对图片文字离线识别的一般过程如下:
- 图像输入
- 前期处理,比如二值化,图像降噪,倾斜纠正
- 文字检测,比如版面分析,字符分割
- 文本识别,比如字符识别,后期纠正(影响准确率最大)
- 输出文本
离线识别训练样本较小,正确率相较于在线识别是不高的。具体的解决方案有以下两种
通过人工纠正,形成新的训练模型(不断增加算法模型中标本的数量)
像身份证识别、票据识别、聊天截图等大部分文字识别场景,这些待识别图片采用了印刷体,每个字的间隔都是固定的,所以我们要想提升准确率,通常的做法是对每个字都进行人 工纠错。
所以整个过程你可以理解成三个步骤: 第一步,人工观察; 第二步,对比原始图像; 第三步,把错误的文字手工纠正为正确的汉字。 比如截图中的“某”字,多次识别错误,当我们人工把这些文字改为正确的“某”字之后, 就可以生成一个训练文件,再把训练文件和文字识别的算法合并成新的识别模型。等下次再 识别发票的时候,就可以采用新的模型进行识别。所以再次出 现“某”字,就可以正确识别了。
这种文字标注对于单一场景非常有效,比如名片、火车票、飞机票、发票、车牌的识别场 景,经过手工标注,不断增加样本数量之后,能够让正确率呈对数级别增加。
使用在线识别软件来优化离线识别软件
识别成功后的文字处理工作
下图为在线识别的结果
为了能够提取文本内容,去掉记录分段信息的”word”和 “{ }”,需要对这段文字再加工处理。
仔细观察的话,就会发现这段文字是有一定规律的,它的写法就是Python的基本数据类型“字典”,字典类型会强调一对或多对数据之间的映射关系。为了将识别的文字结果进行保存,我们还会使用另一个基本数据类型“列表”,一般用来表示多段文字的并列关系, 为了提取文本内容,我接下来把字典转换成列表就可以实现内容的提取了。 从字典到列表转换的功能怎么实现呢?首先来看一下两种数据类型的定义
观察这两个数据类型不难发现,把字典的VALUE存放到列表里就能实现内容的提取了,如果 字典里有多个值,可以使用for循环进行遍历,然后批量提取。对于识别的结果,我们可以采 用一段代码进行从字典到列表的转换。代码如下:
1 | info = [] |
处理好的内容如下