Python爬虫Pytesseract图像识别与文字处理
前言
机器视觉是人工智能领域一个正在快速发展的分支,简单来说,机器视觉就是用机器代替人眼来做测量和判断。从Gogle研究的无人驾驶到能识别假钞的自动售卖机,机器视觉一直是一个应用广泛且具有深远影响的领域。
在机器视觉领域,字符识别扮演着重要的角色,它可以利用计算机自动识别字符。对于图像中的字符,人类能够轻松阅读,然而机器阅读起来却非常的困难。验证码(CAPTCHA)技术就是基于这种人类能正常阅读而机器无法读取的图片。当网络爬虫一旦遇到验证码,就无法提取里面的字符信息。为了解决将图像翻译成字符的问题,Python中引入了光学字符识别(Optical Character Recognition,OCR)技术,Tesseract是目前公认最优秀和最精确的开源OCR系统。
OCR系统概述
OCR光学字符识别(Optical Character Recognition)是指对包含文本资料的图像文件进行分析识别处理,获取文字及版面信息的技术。一般包括以下几个过程:
- 图像输入
针对不同格式的图像,有着不同的存储格式和压缩方式。目前,用于存储图像的开源项目有OpenCV和Cxlmage等。- 预处理
预处理包括二值化、噪声去除和倾斜校正。具体内容如下:
1)二值化:大多数情况下,使用摄像头拍摄的图像都是彩色图像,彩色图像包含的信息量非常丰富,需要进行简化。可以将图像的内容简单地分为前景和背景,为了让计算机更快更好地识别文字,需要先对彩色图像进行处理,使图像只剩下前景和背景信息,即简单地定义前景信息为黑色,背景信息为白色,这就是二值化图。彩色图像和二值化图像前后对比如图:
3)噪声清除:对于不同的文档,噪声的定义可以不同。根据噪声的特征进行消除处理,叫做噪声去除。
4)倾斜校正:通常情况下,用户拍摄的照片比较随意,拍照文档很有可能会产生倾斜。这时,需要使用文字识别软件进行校正。- 版面分析
将文档图片分段落、分行的过程叫作版面分析。由于实际文档的复杂多样,目前没有一个固定的、最好的切割模型。- 字符切割
由于拍照条件的限制,经常会造成字粘连、断笔等情况,因此极大地限制了识别系统地性能。此时就需要文字识别软件具备字符切割功能。- 字符识别
很早的时候就有模板匹配,后来是以特征提取为主。由于文字的位移、笔画的粗细、断笔、粘连、旋转等因素影响,极大地增加了提取的难度。- 版面恢复
通常 ,人类希望识别后的文字,仍然按照原文档图片那样排列着,保持段落不变、位置不变、顺序不变,之后输出到Word文档或PDF文档,这个过程叫作版面恢复。- 后处理、核对
不同的语言环境中,语言的逻辑顺序是不同的。因此,需要根据语言特征的上下文,对识别到后的结果进行校正,这个过程就是后处理。
Tesseract引擎安装与配置
Tesseract支持60中以上语言,他提供了一个引擎和命令行工具。要想在Windows系统环境下使用Tesseract,需要先安装Tesseract-OCR引擎。
Tesseract引擎安装与配置可以参考我的另一篇博客
Tesseract引擎安装与配置
因为他是个命令行工具,安装后只能通过tesseract命令在Python外部运行,而不能通过import导包进行使用。为了解决上述问题,Python提供了支持Tesseract-OCR引擎的Python版本库pytesseract.
pytesseract和PIL库概述
安装pytesseract需要遵守如下要求:
- Python的版本必须是Python2.5以上的
- 安装Python的图像处理库PIL(注意这里是安装Pillow)
- 安装谷歌的OCR识别引擎Tesseract-OCR
pytesseract是对Tesseract-OCR的一层封装,同时也可以单独作为Tesseract引擎的调用脚本,支持使用PIL库读取各种图片文件类型,包括jpeg、png、gif、bmp、tiff等格式。作为脚本使用时,pytesseract将打印识别出的文字,而不是将其写入文件。
pytesseract库中,提供了如下函数将图像转换成字符串:
image_to_string(image,lang=None,config='',nice=0,output_type='string',timeout=0,)
上述函数用于在指定的图像上运行tesseract,首先将图像写入磁盘,然后在图像上运行tesseract命令进行识别读取,最后删除临时文件。其中image表示图像,lang表示语言,默认使用英文。
图像处理是一门应用非常广泛的技术,拥有非常丰富的第三方扩展库的Python语言也具有此项功能。其中PIL(Python Imaging Library)是Python最常用的图像处理库,它不仅提供了广泛的文件格式支持,而且具有强大的图像处理功能。
PIL库中一个非常重要的类是Image类,该类定义在与它的同名的模板中。创建Image类对象的方法有很多种,包括从文件中读取得到,或从其他图像经过处理得到,或者创建全新的。下面对PIL库的一些常用函数和方法进行简单介绍:
1)new()函数
用于创建一个新图像
# mode表示模式,size表示大小
# 当创建单通道图像时,color是单个值;当创建多通道图像时,color是一个元组
# 若省略了color参数,则图像被填充成全黑;
# 若color参数的值为None,则图像不被初始化
Image.new(mode,size,color=0)
2)open()函数
用于打开并识别给定的图像文件
# fp表示字符串形式的文件名称
# mode参数可以省略,但只能设置为"r"
# 如果载入文件失败,则会引起一个IOError异常,否则返回一个Image类对象
open(fp,mode="r")
此函数会被延迟操作,实际的图像数据并不会马上从文件中读取,而是等到需要处理这些数据时才会被读取。这时,可以调用load()函数进行强制加载。创建图像对象后,可以通过Image类提供的方法处理这些图像。常用的有save()和point() 两种方法。
1)save()方法
以特定的图片格式保存图片,大多数情况下,可以省略图片的格式,这时该方法会根据文件的扩展名来选择相应的图片格式
image = Image.open(r'D:\图片\保存的图片\微信图片_20221130162734.jpg')
# format表示文件的输出格式
image.save(self,fp,format=None,**params)
2)point()方法
可以对图像的像素值进行变换
image = Image.open(r'D:\图片\保存的图片\微信图片_20221130162734.jpg')
image.point(self,lut,mode=None)
大多数时候,可以使用函数(带一个参数)作为参数传递给point()方法,图像中的每个像素都会使这个函数进行变换。示例:
# 每个像素乘以1.2
image = Image.open(r'D:\图片\保存的图片\微信图片_20221130162734.jpg')
out = image.point(lambda i:i*1.2)
需要注意的是,如果图像的模式为"l"(整数)或"F"(浮点型),则必须使用函数,且具有以下格式:argument(参数) * scale(倍率) + offset(偏移量)
例如映射浮点图像的示例如下:
image = Image.open(r'D:\图片\保存的图片\微信图片_20221130162734.jpg')
out = image.point(lambda i:i*1.2 + 10)
处理规范格式的文字
图像中的文字最好比较干净,且格式规范。通常,格式规范的文字具有以下几个特点:
1)使用一种标准的字体,不包含手写字体、章书,或者十分花哨的字体。
2)经过复印或拍照,字体仍然很清晰,没有多余的痕迹或污点。
3)排列整齐,没有歪歪斜斜的文字。
4)文字没有超出图片的范围,没有残缺不全或者紧紧地贴在图片的边缘。
1)读取图像中格式规范的文字
对于图像中那些格式非常符合规范的文本而言,通过pytesseract识别且处理以后,读取到的文字跟图像中的文字基本一致,可识别的精准度很高,可以达到90%以上。例如:
具体代码如下:
import pytesseract
from PIL import Image
# 打开要识别的图片
image = Image.open(r'D:\图片\素材图\微信图片_20230406172552.png')
# 使用pytesseract调用image_to_string方法进行识别,传入要识别的图片,lang='chi_sim'是设置为中文识别,
text = pytesseract.image_to_string(image)
print(text)
输出代码如下:
2)对图片进行阈值过滤和降噪处理
前面所介绍的图像比较接近于理想图像,文字极易被识别与处理。但是,大多数情况下,网络上看到的图片是带有背景颜色的。例如:
遇到带有背景色的图片,我们可以预先过滤掉图片中的背景色,从而增加图像的清晰度,便于文本的识别与读取。
from pytesseract import *
from PIL import Image
def clean_file(file,newfile):
'''
将图片经过过滤后进行识别
:param file: 图片文件的路径
:param newfile: 处理后图片的路径
'''
image = Image.open(file)
# 对图片进行阈值过滤(低于143的置为黑色,否则为白色)
image = image.point(lambda x: 0 if x < 143 else 255)
# 重新保存图片
image.save(newfile)
text = pytesseract.image_to_string(image)
print(text)
if __name__ == '__main__':
clean_file(r'D:\图片\素材图\微信图片_20230406174344.png',r'D:\图片\素材图\微信图片_20230406174343.png')
处理完之后返回的图片
3)识别图像的中文字符
除了英文字符外,pytesseract还支持识别中文字符。默认情况下,pytesseract只能识别英文字符,为了让其支持中文,需要显示地指明使用中文字库。因此,在调用image_to_strings()函数时需要指明语言,即将参数的值设为chi_sim。例如:
具体代码如下:
from pytesseract import *
from PIL import Image
# 打开并识别指定的图片
data = Image.open(r"D:\图片\素材图\微信图片_20230406182735.png")
# 将图像以中文的形式进行转换
text = image_to_string(data,lang="chi_sim")
data.save(r"D:\图片\素材图\微信图片_20230406182736.png")
print(text)
运行结果