最近在使用Python识别PNG图像中包含的文字时遇到一个问题。解决过程记录如下。

(Python使用tesserocr的安装过程不再描述。)

在使用tesserocr识别PNG图像中的文字时,如果PNG比较“干净”,背景没有噪音时,过程比较简单,代码如下:

from PIL import Image
import tesserocr image = Image.open(r'../data/demo01.png')
print(tesserocr.image_to_text(image))

输出结果为:

This is some text, written in Arial, that will be read by
Tesseract. Here are some symbols: !@#$%"&’()

效果还算可以。

但是如果PNG图片背景有些复杂,在识别之前需要对PNG做一些处理,比如针对下面这幅PNG图片:



这里使用的是简单的阈值过滤,即小于阈值的像素值均设置为黑色(0),大于阈值的像素值设置为白色(255);然后再对处理后的图像进行处理。代码如下:

from PIL import Image
import tesserocr def clear_file(file_path, new_file_path):
image = Image.open(file_path)
# 为图像设置一个阈值过滤器并保存
image = image.point(lambda x: 0 if x < 143 else 255)
image.save(new_file_path) return image image = clear_file(r'..\data\demo02.png', r'..\data\demo02_cleaned.png')
print(tesserocr.image_to_text(image))

本以为会顺利输出结果,但是执行结果却是报了一堆错误:

……
File "E:\PrivatedData\programs\python\wasp\env\lib\site-packages\PIL\Image.py", line 2212, in save
save_handler(self, fp, filename)
File "lib\site-packages\PIL\JpegImagePlugin.py", line 632, in _save
raise OSError(f"cannot write mode {im.mode} as JPEG") from e
OSError: cannot write mode RGBA as JPEG

错误非常奇怪,明明是PNG图像,怎么说要处理JPEG图像呢?

通过跟踪,发现在选择图像文件的处理方法时,有如下代码(在Image.py的save函数中):

        if save_all:
save_handler = SAVE_ALL[format.upper()]
else:
save_handler = SAVE[format.upper()]

代码的主要意图是要根据format的值来选择图片的处理函数,而此时format的值为‘JPEG’,因此Pillow就用JPEG的处理函数来处理PNG图像了,所以会出错。

很奇怪,不是根据扩展名来识别图像格式吗。我从头到尾就没有使用到JPEG图像。我不知道Pillow的Image类在什么时候、用什么方式确定format的值。

想在网上查找tesserocr的API文档,看能不能把这个format传递过去,但是没有找到。

于是尝试自己设置图像的format,看能否通过。于是有了下面的代码:

image = clear_file(r'..\data\demo02.png', r'..\data\demo02_cleaned.png')
image.format = 'PNG'
print(tesserocr.image_to_text(image))

输出结果为:

This Is some text, wntten In Arial, that will be "
Tesseract Here are some symbols: l@#$%"&

这里只是一小段练习代码。如果在正式项目中,可以根据图片文件的扩展名来给image.format赋值。当然能不使用“硬”代码更好,但我一直没有找到相关的文档,不知道问题的根本原因是什么。先把这个记录下来,其他继续研究吧。

Python使用tesserocr识别文字过程中遇到的一个问题的更多相关文章

  1. [SQL]select scope_identity()传回插入相同范围之识别资料行中的最后一个识别值

    传回插入相同范围之识别资料行中的最后一个识别值.范围是一个模组:预存程序.触发程序.函数或批次.因此,如果两个陈述式在相同预存程序.函数或批次中,它们就在相同范围中. 语法: SCOPE_IDENTI ...

  2. 使用ffmpeg视频编码过程中踩的一个坑

           今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果:                   ...

  3. [debug] 解决在C++编写过程中的“找到一个或多个多重定义的符号”

    如下图: 其在 common.h 中定义了一个变量a ,然后在两个 cpp 文件中都是用它. 在这种情况下,链接时就会出现 “找到一个或多个多重定义的符号”. 解决方案: 在某个cpp文件中定义,然后 ...

  4. Python+selenium自动化脚本编辑过程中遇到的问题和小技巧

    应该也不算是问题和技巧,算是实践中学习到的Python,记录下,也不定时更新 1.通过截取url判断 实例: self.assertEqual(self.broswer.current_url[sel ...

  5. VS 2017开发ASP.NET Core Web应用过程中发现的一个重大Bug

    今天试着用VS 2017去开发一个.net core项目,想着看看.net core的开发和MVC5开发有什么区别,然后从中发现了一个VS2017的Bug. 首先,我们新建项目,ASP.NET Cor ...

  6. js:使用js过程中遇到的一个小问题

    在一个作业中使用了js,函数A调用函数B.当A和B中均含有变量i的时候,相关操作结果可能会出错. 将B中的i替换为j(j不存在于A中)后,结果正确. 目前考虑原因是两个变量i有相关性(或者说实际上就是 ...

  7. sql2012安装过程中出现个一个问题

    最近安装了一次SQLSERVER2012,遇到了一个小问题,截图如下: 就是上图中状态为失败的项,点开之后,会弹出下面的一个框: 在网上搜了之后,有了这样的答案: http://www.cnblogs ...

  8. thinkphp 使用过程中遇到的一个小函数

    1.实现导出Excel文件,并在导出的文件中显示图片 //导出 public function push(){ $goods_list=M('Dajia')->select(); $data = ...

  9. hive配置过程中出现的一个问题

    执行hive里面的insert语句的时候,报错,执行失败查看hadoop的日志文件之后发现错误的详细信息如下: 把hdfs-site.xml中的hadoop.tmp.dir这个属性添加到core-si ...

随机推荐

  1. osx系统使用技巧集锦

    6.禁用dashboard defaults write com.apple.dashboard mcx-disabled -boolean YES && killall Dock 5 ...

  2. 使用Docker搭建自己的Bitwarden密码管理服务

    相信身为开发者,总会在各种网站中注册账号,为了方面记忆可以使用同一套账号密码进行注册,自从前段时间学习通时间撞库后有些人已经开始疯狂改密码了,可是密码一多就很难记忆,最好找个地方存储账户信息 我曾经使 ...

  3. Python语言之面向对象

    Python语言之面向对象 前言 面向对象 -- Object Oriented 简写:OO 面向对象设计 -- Object Oriented Design 简写:OOD 面向对象编程 -- Obj ...

  4. Markdown扩展语法

    目录 Markdown 语法补充 一.快速生成 HTML 表格代码 在线表格编辑器--TablesGenerator 二. 插入视频.音频或GIF 1. 视频 2. 音频 方法一 方法二 方法三 3. ...

  5. 全网最新的nacos 2.1.0集群多节点部署教程

    原文链接:全网最新的nacos 2.1.0集群多节点部署教程-语雀 基本信息 进度整理中 版本 2.1.0 版本发布日期 2022-04-29 git revision number b5845313 ...

  6. 基于串口校时的数字钟设计(verilog实现)

    任务: 电路图设计: 设计: 模块1:1.先设计一个计数时钟,为了仿真方便,这里把1000ns当作1s. 创建一个计数器second_lim,当计数到1000/20时清零,即1s. 秒显示器secon ...

  7. python 线程理解

    简介 一个应用程序由多个进程组成,一个进程有多个线程,一个线程则是操作系统调度的最小单位,当应用程序运行时,操作系统根据优先级和时间片调度线程(决定此时此刻执行哪个线程). python的线程 pyt ...

  8. YII学习总结6(模板替换和“拼合”)

    controller\helloController.php<?php namespace app\controllers; use yii\web\Controller; class hell ...

  9. 张高兴的 .NET IoT 入门指南:(八)基于 GPS 的 NTP 时间同步服务器

    时间究竟是什么?这既可以是一个哲学问题,也可以是一个物理问题.古人对太阳进行观测,利用太阳的投影发明了日晷,定义了最初的时间.随着科技的发展,天文观测的精度也越来越准确,人们发现地球的自转并不是完全一 ...

  10. Java SE 9 多版本兼容 JAR 包示例

    Java SE 9 多版本兼容 JAR 包示例 作者:Grey 原文地址:Java SE 9 多版本兼容 JAR 包示例 说明 Java 9 版本中增强了Jar 包多版本字节码文件格式支持,也就是说在 ...