影响pytesseract识别结果的几项设定

pytesseract中PSM(Possible modes for page layout analysis)不同的设置对识别结果有怎样的影响?pytesseract中黑白名单如何设置?tesseract输入图像是否需要二值化?本文主要记录这三个问题的一些个人见解,请各位读者谨慎参考并不吝赐教。

环境说明

python3.6 + Tesseract4.0 + win10
本文代码运行的前提是已设置Tesseract及tessdata的环境变量,设置方法请参考pytesseract image_to_data检测并定位图片中的文字。若未设置环境变量,则需要在python代码中添加指定Tesseract与tessdata路径的代码,具体如下:

PSM in pytesseract

PSM的全称是Possible modes for page layout analysis,默认设定值为PSM_SINGLE_BLOCK(Assume a single uniform block of text)。PSM定义可以在include/tesseract/publictypes.h查看,如下所示:

接下来我们用一张仓库货架的图片来进行测试,用tesseract来定位并识别货架中货物的编号。代码如下,测试时我们会更改PSM不同设置值的来观察其差异:

第1~4行导入所需库文件;

第6行读取与当前py文件相同路径的示例图像;

第10行对opencv读取的图像进行转换。因opencv读取图像的默认格式为BGR,但Tesseract需要RGB的彩色图像,因此这里需要进行转换。

第12行调用pytesseract的image_to_data()函数获取识别结果,输出格式为”Output.DICT”,这样我们可以根据其输出结果绘制出文字块以及识别结果。

这里我们用到了config, PSM在此进行设置,whitelist后的字符串可以指定识别字符的范围。tesseract中还有blacklist,顾名思义,它的作用是排除识别字符的范围,设置方法相同。

第14~26行取出识别结果中文字块的相关信息,据此信息在原图中将文字用矩形框出,并将识别结果绘制在图像中;

第28行用到了imutils.resize,该函数课指定宽度并按照原图比例进行缩放。本文示例的图像太宽,缩小后便于观察。

通过更改pytesseract.image_to_data中的config的设定,我分别测试了如下几种组合:

RGB, PSM=12,No whitelist, conf>50, 其意义为: config=’–psm 12’,第 24行代码if条件处再加上conf>50;

RGB, PSM=12,With whitelist,其意义为:config=’-c tessedit_char_whitelist=0123456789 –psm 12′;

RGB, PSM=11,With whitelist,其意义为:config=’-c tessedit_char_whitelist=0123456789 –psm 12′;

GRAY, PSM=12,With whitelist,其意义为: config=’-c tessedit_char_whitelist=0123456789 –psm 12’。该项测试需要将第10行代码中的cv2.COLOR_BGR2RGB更改为cv2.COLOR_BGR2GRAY进行测试。

测试结果如下动图所示:

tesseract psm setting

由以上示例可知,PSM的设定值对总体识别结果有明显影响,我们在使用的时候需要根据实际情况进行调整。

上述动图中原图及tessract识别效果最好的图片如下:

items number on shelfPSM=12 with whitelist

本小节标题虽然是PSM in pytesseract,实际上只要是tesseract,在C++或者命令行中使用tesseract.exe,PSM均有类似的影响。


tesseract的输入图像是否需要二值化

一直以来,我都认为tesseract最佳的输入图像是干净清晰的二值化图像,直到最近开始测试pytesseract。
pytesseract image_to_osd文字方向与文字编码检测pytesseract image_to_data检测并定位图片中的文字中,opencv读取图像后,将图像由BGR转换为RGB,即输入至pytesseract,并没有进行二值化。

pytesseract中是否有对RGB格式的图像进一步处理呢?查阅其源代码即可知道pytesseract与命令行中(cmd.exe)使用tesseract.exe一样,将RGB格式的图像作为tesseract.exe的输入,并没有进一步对图像进行灰度化或者二值化。

关于tesseract的最佳输入图像,到底是二值化图像,RGB彩色图像,还是灰度图像?Tesseract并没有比较正式的文档来说明。不过在 RFC: allow flexible or better binarization #3083这个链接中,有tesseract的多位开发者对这个问题进行了一些讨论。

这里记录一下我个人对该链接的理解(仅适用于tesseract4.0及以上版本):

1. 从tesseract4.0开始,通常情况下,文字识别使用RGB格式图像的灰度图,若输入RGB格式的图像,tesseract会有自己的算法将其灰度化,并不使用其二值化图像。
2. 输入二值化图像,tesseract也可以工作,但其文字识别结果可能不佳(LSTM的训练模型更多地基于灰度图)。

3. tesseract在对图像布局进行分析和分割图像时,使用的仍是二值化图像。若输入RGB彩色图像或灰度图,tesseract会使用自己内部的二值化算法来进行二值化后用于图像分割和布局分析,而这个二值化方法效果比较一般。

针对上述链接的讨论,我尝试用opencv对BGR图片灰度化后作为tesseract输入进行测试,测试结果如下:

grayInput whitelist

对于本文的测试图像而言,从第一小节的测试动图来看,输入RGB彩色图像,使用Tesseract内部灰度化的效果是较好的。

总的来说,对于tesseract4.0而言,其输入图像并没有一个最佳定论,大家需要根据自己的需求和以上讨论进行选择或搭配。例如,若图像布局复杂,我们可以输入质量较高的二值化图像,对图像进行分割;根据图像分割的坐标将灰度图进行分割,将分割后的灰度图作为输入进行文字识别。当然也希望下一版本的Tesseract能针对这个问题给出更好的解决方案。

本文到此结束,感谢阅读,欢迎关注。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

Fork me on GitHub