使用easyocr、PyPDF2对图像及PDF文档进行识别

一、概述

本 Python 脚本的主要功能是对当前目录及其子目录下的图片和 PDF 文件进行光学字符识别(OCR)处理。它使用 easyocr 库处理图片中的文字,使用 PyPDF2 库提取 PDF 文件中的文本,并将处理结果保存为文本文件。同时,脚本会记录详细的处理日志,方便用户跟踪处理过程和排查问题。

二、环境要求

  • Python 版本:建议使用 Python 3.6 及以上版本。
  • 依赖库
    • easyocr:用于图片的 OCR 识别。
    • PyPDF2:用于读取 PDF 文件并提取文本。
    • PillowPIL):虽然脚本中未直接使用,但 easyocr 处理图像时可能依赖。

你可以使用以下命令安装这些依赖库:

收起

bash

pip install easyocr PyPDF2 Pillow

三、脚本结构与功能模块

1. 导入必要的库

收起

python

import os
import time
import easyocr
from PyPDF2 import PdfReader
from PIL import Image

导入了处理文件系统、时间、OCR 识别、PDF 读取和图像处理所需的库。

2. 设置模型下载路径

收起

python

model_storage_directory = './easyocr_models'
os.makedirs(model_storage_directory, exist_ok=True)

定义了 easyocr 模型的存储目录,并确保该目录存在。

3. 检查网络连接

收起

python

def check_network():try:import urllib.requesturllib.request.urlopen('https://www.baidu.com', timeout=5)return Trueexcept:return False

该函数尝试访问百度网站,以检查网络连接是否正常。如果能成功访问,则返回 True,否则返回 False

4. 初始化 EasyOCR reader

收起

python

try:print("Initializing EasyOCR...")print(f"Model storage directory: {os.path.abspath(model_storage_directory)}")if not check_network():print("Network connection failed. Please check your internet connection.")exit(1)print("Downloading models (this may take several minutes)...")reader = easyocr.Reader(['ch_sim', 'en'],model_storage_directory=model_storage_directory,download_enabled=True,verbose=True)print("EasyOCR initialized successfully")
except Exception as e:print(f"Failed to initialize EasyOCR: {str(e)}")exit(1)

  • 打印初始化信息和模型存储目录的绝对路径。
  • 检查网络连接,若网络异常则输出错误信息并退出程序。
  • 下载 easyocr 所需的模型,支持中文(简体)和英文识别。
  • 若初始化成功,打印成功信息;若出现异常,打印错误信息并退出程序。

5. 处理图片文件

收起

python

def process_image(image_path):"""处理图片文件"""try:result = reader.readtext(image_path)text = '\n'.join([item[1] for item in result])return textexcept Exception as e:print(f"Error processing image {image_path}: {str(e)}")return ""

  • 接受图片文件路径作为参数。
  • 使用 easyocr 对图片进行 OCR 识别,提取识别结果中的文本并拼接成字符串返回。
  • 若处理过程中出现异常,打印错误信息并返回空字符串。

6. 处理 PDF 文件

收起

python

def process_pdf(pdf_path):"""处理PDF文件"""try:text = ""reader = PdfReader(pdf_path)for page in reader.pages:text += page.extract_text()return textexcept Exception as e:print(f"Error processing PDF {pdf_path}: {str(e)}")return ""

  • 接受 PDF 文件路径作为参数。
  • 使用 PyPDF2 读取 PDF 文件的每一页,并提取文本拼接成字符串返回。
  • 若处理过程中出现异常,打印错误信息并返回空字符串。

7. 保存提取的文本

收起

python

def save_text(text, output_path):"""保存提取的文本"""with open(output_path, 'w', encoding='utf-8') as f:f.write(text)

  • 接受文本内容和输出文件路径作为参数。
  • 将文本内容以 UTF-8 编码写入指定的输出文件。

8. 主函数 main

收起

python

def main():# 尝试多个可能的输出目录位置output_folders = ['./output_text',  # 当前目录os.path.expanduser('~/ocr_output'),  # 用户主目录os.path.join(os.getcwd(), 'ocr_output')  # 当前工作目录]output_folder = Nonefor folder in output_folders:try:os.makedirs(folder, exist_ok=True)output_folder = folderprint(f"Using output directory: {os.path.abspath(output_folder)}")breakexcept Exception as e:print(f"Failed to create output directory {folder}: {str(e)}")if output_folder is None:print("Error: Could not create any output directory")exit(1)# 初始化日志log_file = os.path.join(output_folder, 'ocr_log.txt')# 重定向标准输出到日志文件import sysclass Logger(object):def __init__(self, filename):self.terminal = sys.stdoutself.log = open(filename, "a", encoding='utf-8')def write(self, message):self.terminal.write(message)self.log.write(message)def flush(self):passsys.stdout = Logger(log_file)print("OCR Processing Log\n")print(f"Starting OCR processing at {time.strftime('%Y-%m-%d %H:%M:%S')}")# 支持的图片格式image_extensions = ['.bmp', '.jpg', '.jpeg', '.png', '.tiff', '.gif']# 遍历当前目录及子目录for root, dirs, files in os.walk('.'):for file in files:file_path = os.path.join(root, file)base_name, ext = os.path.splitext(file)try:# 处理图片文件if ext.lower() in image_extensions:print(f"Processing image: {file_path}")text = process_image(file_path)output_path = os.path.join(output_folder, f"{base_name}.txt")save_text(text, output_path)print(f"Successfully processed image: {file_path} -> {output_path}")with open(log_file, 'a') as f:f.write(f"Success: {file_path} -> {output_path}\n")# 处理PDF文件elif ext.lower() == '.pdf':print(f"Processing PDF: {file_path}")text = process_pdf(file_path)output_path = os.path.join(output_folder, f"{base_name}.txt")save_text(text, output_path)print(f"Successfully processed PDF: {file_path} -> {output_path}")with open(log_file, 'a') as f:f.write(f"Success: {file_path} -> {output_path}\n")except Exception as e:error_msg = f"Error processing {file_path}: {str(e)}"print(error_msg)with open(log_file, 'a') as f:f.write(error_msg + "\n")

  • 输出目录处理:尝试在多个预设位置创建输出目录,若创建成功则使用该目录,若所有尝试均失败则输出错误信息并退出程序。
  • 日志初始化:在输出目录下创建 ocr_log.txt 日志文件,将标准输出重定向到该日志文件,同时保留在终端的输出。记录日志头部信息和处理开始时间。
  • 文件遍历与处理:遍历当前目录及其子目录下的所有文件,对图片文件调用 process_image 函数处理,对 PDF 文件调用 process_pdf 函数处理。将处理结果保存为文本文件,并在日志中记录成功或失败信息。

9. 程序入口

收起

python

if __name__ == "__main__":main()

当脚本作为主程序运行时,调用 main 函数开始执行。

四、使用方法

  1. 将脚本保存为一个 Python 文件(例如 ocr_process.py)。
  2. 确保所需的依赖库已安装。
  3. 打开终端或命令提示符,进入脚本所在的目录。
  4. 运行脚本:

收起

bash

python ocr_process.py
  1. 脚本会自动处理当前目录及其子目录下的图片和 PDF 文件,并将处理结果保存到指定的输出目录中,同时生成处理日志。

五、注意事项

  • 由于 easyocr 模型下载可能需要一定时间,首次运行脚本时请确保网络连接稳定,耐心等待模型下载完成。
  • 对于 PDF 文件,PyPDF2 只能提取文本内容,若 PDF 为扫描版或加密文件,可能无法正常提取文本。
  • 若处理过程中出现错误,请查看日志文件 ocr_log.txt 以获取详细的错误信息。

完成代码

import os
import time
import easyocr
from PyPDF2 import PdfReader
from PIL import Image# 设置模型下载路径
model_storage_directory = './easyocr_models'
os.makedirs(model_storage_directory, exist_ok=True)# 检查网络连接
def check_network():try:import urllib.requesturllib.request.urlopen('https://www.baidu.com', timeout=5)return Trueexcept:return False# 初始化EasyOCR reader
try:print("Initializing EasyOCR...")print(f"Model storage directory: {os.path.abspath(model_storage_directory)}")if not check_network():print("Network connection failed. Please check your internet connection.")exit(1)print("Downloading models (this may take several minutes)...")reader = easyocr.Reader(['ch_sim', 'en'],model_storage_directory=model_storage_directory,download_enabled=True,verbose=True)print("EasyOCR initialized successfully")
except Exception as e:print(f"Failed to initialize EasyOCR: {str(e)}")exit(1)def process_image(image_path):"""处理图片文件"""try:# 使用EasyOCR提取文本result = reader.readtext(image_path)# 合并所有识别结果text = '\n'.join([item[1] for item in result])return textexcept Exception as e:print(f"Error processing image {image_path}: {str(e)}")return ""def process_pdf(pdf_path):"""处理PDF文件"""try:text = ""reader = PdfReader(pdf_path)for page in reader.pages:text += page.extract_text()return textexcept Exception as e:print(f"Error processing PDF {pdf_path}: {str(e)}")return ""def save_text(text, output_path):"""保存提取的文本"""with open(output_path, 'w', encoding='utf-8') as f:f.write(text)def main():# 尝试多个可能的输出目录位置output_folders = ['./output_text',  # 当前目录os.path.expanduser('~/ocr_output'),  # 用户主目录os.path.join(os.getcwd(), 'ocr_output')  # 当前工作目录]output_folder = Nonefor folder in output_folders:try:os.makedirs(folder, exist_ok=True)output_folder = folderprint(f"Using output directory: {os.path.abspath(output_folder)}")breakexcept Exception as e:print(f"Failed to create output directory {folder}: {str(e)}")if output_folder is None:print("Error: Could not create any output directory")exit(1)# 初始化日志log_file = os.path.join(output_folder, 'ocr_log.txt')# 重定向标准输出到日志文件import sysclass Logger(object):def __init__(self, filename):self.terminal = sys.stdoutself.log = open(filename, "a", encoding='utf-8')def write(self, message):self.terminal.write(message)self.log.write(message)def flush(self):passsys.stdout = Logger(log_file)print("OCR Processing Log\n")print(f"Starting OCR processing at {time.strftime('%Y-%m-%d %H:%M:%S')}")# 支持的图片格式image_extensions = ['.bmp', '.jpg', '.jpeg', '.png', '.tiff', '.gif']# 遍历当前目录及子目录for root, dirs, files in os.walk('.'):for file in files:file_path = os.path.join(root, file)base_name, ext = os.path.splitext(file)try:# 处理图片文件if ext.lower() in image_extensions:print(f"Processing image: {file_path}")text = process_image(file_path)output_path = os.path.join(output_folder, f"{base_name}.txt")save_text(text, output_path)print(f"Successfully processed image: {file_path} -> {output_path}")with open(log_file, 'a') as f:f.write(f"Success: {file_path} -> {output_path}\n")# 处理PDF文件elif ext.lower() == '.pdf':print(f"Processing PDF: {file_path}")text = process_pdf(file_path)output_path = os.path.join(output_folder, f"{base_name}.txt")save_text(text, output_path)print(f"Successfully processed PDF: {file_path} -> {output_path}")with open(log_file, 'a') as f:f.write(f"Success: {file_path} -> {output_path}\n")except Exception as e:error_msg = f"Error processing {file_path}: {str(e)}"print(error_msg)with open(log_file, 'a') as f:f.write(error_msg + "\n")if __name__ == "__main__":main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2000-2020年各省地方财政一般预算支出数据

2000-2020年各省地方财政一般预算支出数据 1、时间:2000-2020年 2、来源:国家统计局、统计年鉴 3、指标;行政区划代码、地区、年份、地方财政一般预算支出(亿元) 4、范围:31省 5、指标解释:一般预算支出是国家对集中的预算收…

k8s 中各种发布方式介绍以及对比

前言 在 Kubernetes(K8s)中,不同的发布策略(如金丝雀发布、灰度发布、蓝绿发布等)各有其适用场景和优缺点。 1. 滚动发布(Rolling Update) 核心原理:逐步替换旧版本 Pod 为新版本&…

力扣HOT100之哈希:1. 两数之和

这道题之前刷代码随想录的时候已经刷过好几遍了&#xff0c;看到就直接秒了。这道题主要是通过unordered_map<int, int>来建立哈希表&#xff0c;其中键用来保存向量中的元素&#xff0c;而对应的值则为元素的下标。遍历整个向量&#xff0c;当遍历到nums[i]时&#xff0…

kakfa-3:ISR机制、HWLEO、生产者、消费者、核心参数负载均衡

1. kafka内核原理 1.1 ISR机制 光是依靠多副本机制能保证Kafka的高可用性&#xff0c;但是能保证数据不丢失吗&#xff1f;不行&#xff0c;因为如果leader宕机&#xff0c;但是leader的数据还没同步到follower上去&#xff0c;此时即使选举了follower作为新的leader&#xff…

从小米汽车召回看智驾“命门”:智能化时代 — 时间就是安全

2025年1月&#xff0c;小米因车辆“授时同步异常”召回3万余辆小米SU7&#xff0c;成为其造车历程中的首个重大安全事件。 从小米SU7召回事件剖析&#xff0c;授时同步何以成为智能驾驶的命门&#xff1f; 2024年11月&#xff0c;多名车主反馈SU7标准版的智能泊车辅助功能出现…

FastGPT 引申:如何基于 LLM 判断知识库的好坏

文章目录 如何基于 LLM 判断知识库的好坏方法概述示例 Prompt声明抽取器 Prompt声明检查器 Prompt 判断机制总结 下面介绍如何基于 LLM 判断知识库的好坏&#xff0c;并展示了如何利用声明抽取器和声明检查器这两个 prompt 构建评价体系。 如何基于 LLM 判断知识库的好坏 在知…

【数据挖掘】NumPy的索引与切片(Indexing Slicing)

&#x1f4cc; NumPy ndarray 的索引与切片&#xff08;Indexing & Slicing&#xff09; NumPy 提供 灵活高效 的索引与切片方式&#xff0c;支持 一维、二维、多维数组 的访问与操作。 1️⃣ 索引&#xff08;Indexing&#xff09; 索引用于访问 NumPy 数组中的 单个元素…

AI工具:deepseek+阶跃视频,生成好玩的视频

目标 测试一下&#xff0c;当下好玩的AI工具&#xff0c;缓解一下紧张的AI学习~ 用deepseek生成视频制作提示词&#xff0c;让后把提示词给阶跃视频生成&#xff0c;一个视频就生成了。具体操作如下。 操作过程 在阶跃官网&#xff0c;阶跃AI&#xff0c;注册一个账号&…

利用矩阵相乘手动实现卷积操作

卷积&#xff08;Convolution&#xff09; 是信号处理和图像处理中的一种重要操作&#xff0c;广泛应用于深度学习&#xff08;尤其是卷积神经网络&#xff0c;CNN&#xff09;中。它的核心思想是通过一个卷积核&#xff08;Kernel&#xff09; 或 滤波器&#xff08;Filter&am…

前端面试场景题葵花宝典之四

87.场景面试之大数运算&#xff1a;超过js中number最大值的数怎么处理 在 JavaScript 中&#xff0c;Number.MAX_SAFE_INTEGER&#xff08;即 2^53 - 1&#xff0c;即 9007199254740991&#xff09;是能被安全表示的最大整数。超过此值时&#xff0c;普通的 Number 类型会出现…

Linux中死锁问题的探讨

在 Linux 中&#xff0c;死锁&#xff08;Deadlock&#xff09; 是指多个进程或线程因为竞争资源而相互等待&#xff0c;导致所有相关进程或线程都无法继续执行的状态。死锁是一种严重的系统问题&#xff0c;会导致系统资源浪费&#xff0c;甚至系统崩溃。 死锁的定义 死锁是指…

【基于Mesh组网的UWB技术讨论】

基于Mesh组网的UWB技术讨论 Mesh 组网无线Mesh与无线中继的区别 基于Mesh拓扑的UWB技术可行性星型拓扑 / Mesh拓扑的UWB技术比较 Mesh 组网 Mesh(网格)是一种无中心、自组织的高度业务协同的网络。通常分为无线Mesh和有线Mesh&#xff0c;但在实际应用场景&#xff0c;有线Mes…

Python Cookbook-3.1 计算昨天和明天的日期

任务 获得今天的日期&#xff0c;并以此计算昨天和明天的日期。 解决方案 方案一&#xff1a; 无论何时遇到有关“时间变化”或者“时间差”的问题&#xff0c;先考虑datetime包: import datetime today datetime.date.today() yesterday today - datetime.timedelta(day…

USB 模块 全面解析(二)

本文是我整理的一些 USB 的学习心得&#xff0c;希望能对大家有所帮助。 文章目录 前言&#x1f34d;USB 协议层数据格式&#x1f347;包格式&#x1f353; PID 域&#x1f353; 令牌包&#x1f353; 数据包&#x1f353; 握手包 &#x1f347;传输类型&#x1f353; 批量传输&…

从基础到实践(十):MOS管的全面解析与实际应用

MOS管&#xff08;金属-氧化物半导体场效应晶体管&#xff09;是现代电子技术的基石&#xff0c;凭借高输入阻抗、低功耗和易集成特性&#xff0c;成为数字电路、电源管理和信号处理的核心元件。从微处理器到新能源汽车电驱系统&#xff0c;其高效开关与放大功能支撑了计算机、…

AES/CBC/PKCS5Padding加密

1、加密代码如下 public static String encryptAEs_CBC(String data,String key,byte[] iv) {Cipher cipher = null;try {cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//位数不够,自动补一个长度int blocksize = cipher.getBlockSize();byte[] dataBytes …

指纹细节提取(Matlab实现)

指纹细节提取概述指纹作为人体生物特征识别领域中应用最为广泛的特征之一&#xff0c;具有独特性、稳定性和便利性。指纹细节特征对于指纹识别的准确性和可靠性起着关键作用。指纹细节提取&#xff0c;即从指纹图像中精确地提取出能够表征指纹唯一性的关键特征点&#xff0c;是…

Python 图像处理之 Pillow 库:玩转图片

哈喽,大家好,我是木头左! Pillow 库作为 Python 图像处理的重要工具之一,为提供了便捷且功能丰富的接口,让能够轻松地对图像进行各种操作,从简单的裁剪、旋转到复杂的滤镜应用、图像合成等,几乎无所不能。接下来,就让一起深入探索如何使用 Pillow 库来处理图片,开启一…

Android Flow 示例

在Android开发的世界里&#xff0c;处理异步数据流一直是一个挑战。随着Kotlin的流行&#xff0c;Flow作为Kotlin协程库的一部分&#xff0c;为开发者提供了一种全新的方式来处理这些问题。今天&#xff0c;我将深入探讨Flow的设计理念&#xff0c;并通过具体的例子展示如何在实…

记录uniapp小程序对接腾讯IM即时通讯无ui集成(2)

完成以上步骤之后开始进行登录&#xff0c;登陆就需要账号。这个账号我们可以在腾讯云中创建。 有了账号之后开始去小程序进行登陆操作。腾讯云接口文档 这里除了帐号还需要一个校验值userSig正常项目开发这个字段可以在登陆后让后端返回&#xff0c;现在是测试我们直接去控制…