使用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.request
        urllib.request.urlopen('https://www.baidu.com', timeout=5)
        return True
    except:
        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 text
    except 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 text
    except 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 = None
    for folder in output_folders:
        try:
            os.makedirs(folder, exist_ok=True)
            output_folder = folder
            print(f"Using output directory: {os.path.abspath(output_folder)}")
            break
        except 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 sys
    class Logger(object):
        def __init__(self, filename):
            self.terminal = sys.stdout
            self.log = open(filename, "a", encoding='utf-8')

        def write(self, message):
            self.terminal.write(message)
            self.log.write(message)

        def flush(self):
            pass
            
    sys.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.request
        urllib.request.urlopen('https://www.baidu.com', timeout=5)
        return True
    except:
        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 text
    except 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 text
    except 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 = None
    for folder in output_folders:
        try:
            os.makedirs(folder, exist_ok=True)
            output_folder = folder
            print(f"Using output directory: {os.path.abspath(output_folder)}")
            break
        except 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 sys
    class Logger(object):
        def __init__(self, filename):
            self.terminal = sys.stdout
            self.log = open(filename, "a", encoding='utf-8')

        def write(self, message):
            self.terminal.write(message)
            self.log.write(message)

        def flush(self):
            pass
            
    sys.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()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

硬件学习笔记--47 LDO相关基础知识介绍

目录 1.LDO主要功能介绍 2.LDO相关参数介绍 3.使用方法 4.优、缺点 1.LDO主要功能介绍 LDO(Low Dropout Regulator)是一种线性稳压器,用于将输入电压转换为稳定的输出电压。其主要功能包括: 1)稳压功能&#xff1…

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

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

STM32-HAL库初始化时钟

使能和失能外设GPIOA 时钟信号初始化函数 HAL_RCC_OscConfig函数: HAL_StatusTypeDef是该函数的返回值类型,最顶上的那句话只是这个函数的原型 HAL_RCC_ClockConfig函数: 因为FLASH实际上只能支持24MHz的时钟信号所以如果用高于24MHz的信号输入则要用到等…

windows环境执行composer install出错

现在的项目环境都是要求比较新的版本,就比如今天部署测试一个新框架遇到了下面这些问题,报错原因有以下几点: PHP版本低了,现在的新项目都是要求PHP8以上版本;指令废弃,配置文件禁用即可;切换P…

Three.js 入门(光线投射实现3d场景交互事件)

本篇主要学习内容 : 光线投射器交互事件 点赞 关注 收藏 学会了 1.光线投射器 Raycaster 此类旨在协助光线投射。光线投射用于鼠标拾取(确定鼠标在 3D 空间中的哪些对象上)等。 Raycaster( origin : Vector3, direction : Vector3, near : Float,…

蓝桥杯web第三天

展开扇子题目, #box:hover #item1 { transform:rotate(-60deg); } 当悬浮在父盒子,子元素旋转 webkit display: -webkit-box:将元素设置为弹性伸缩盒子模型。-webkit-box-orient: vertical:设置伸缩盒子的子元素排列方…

Unity 使用NGUI制作无限滑动列表

原理: 复用几个子物体,通过子物体的循环移动实现,如下图 在第一个子物体滑动到超出一定数值时,使其放到最下方 --------------------------------------------------------------》 然后不停的循环往复,向下滑动也是这…

网络安全蜜罐产品研究现状

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 一、知识点总结 1、蜜罐(Honeypot):诱捕攻击者的一个陷阱。 2、蜜网(Honeynet):采用了技术…

SpringBoot3—场景整合:环境准备

一、云服务器 阿里云服务器开通安装以下组件 dockerrediskafkaprometheusgrafana 下载windterm:https://github.com/kingToolbox/WindTerm/releases/download/2.5.0/WindTerm_2.5.0_Windows_Portable_x86_64.zip 重要:开通云服务器以后,请一…

Ollama进行DeepSeek本地部署存在安全风险解决方案,nginx反向代理配置

文章目录 概要整体架构流程技术细节**## 1.下载nginx [https://nginx.org/en/download.html](https://nginx.org/en/download.html),推荐Stable version稳定版**2.下载完成解压文件,打开conf文件夹下的nginx.conf,贴上反向代理配置3.然后点击解压文件夹下的nginx.exe,启动成…

【音视频】ffmpeg音视频处理基本流程

一、ffmpeg音视频处理基本流程 首先先看两条命令 ffmpeg -i 1.mp4 -acodec copy -vcodec libx264 -s 1280x720 2.flv ffmpeg -i 1.mp4 -acodec copy -vcodec libx265 -s 1280x720 3.mkv-i :表示输入源,这里是1.mp4,是当前路径下的视频文件-acodec copy…

计算机网络基础:认识网络拓扑结构

计算机网络基础:认识网络拓扑结构 一、前言二、网络拓扑结构的基本概念2.1 定义2.2 作用 三、常见的物理拓扑结构3.1 总线型拓扑结构3.1.1 定义和结构3.1.2 工作原理3.1.3 优点3.1.4 缺点3.1.5 适用场景3.1.6 示例图 3.2 星型拓扑结构3.2.1 定义和结构3.2.2 工作原理…

基于Android平台的SOME/IP测试模块 EPT-ETS

在汽车产业智能化、网联化的时代浪潮中,汽车电子系统正经历着前所未有的变革。SOME/IP(Scalable service-Oriented MiddlewarE over IP)协议作为汽车电子通信领域的关键技术,其稳定性、可靠性与高效性对于整车性能的提升起着至关重…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-2.2.3案例:电商订单日志每秒10万条写入优化

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 Elasticsearch批量写入性能调优实战:2.2.3 案例:电商订单日志每秒10万条写入优化1. 原始架构与瓶颈分析1.1 初始集群配置1.2 性能瓶颈定位 2. 全链路…

解决redis lettuce连接池经常出现连接拒绝(Connection refused)问题

一.软件环境 windows10、11系统、springboot2.x、redis 6 7 linux(centos)系统没有出现这问题,如果你是linux系统碰到的,本文也有一定大参考价值。 根本思路就是:tcp/ip连接的保活(keepalive)。 二.问题描述 在spr…

【开源项目-AI研发】ai-engineer-toolkit

项目地址(Fork: 40, Star: 301) GitHub - break-into-data/ai-engineer-toolkit: Projects & Resources to help you become a better AI Developer. 项目介绍 官方介绍:帮助你成为更好的 AI 开发者的工具和资源 项目本身是个表格&am…

白帽子讲Web安全资源下载

资源简介 本仓库提供《白帽子讲Web安全》一书的资源下载。这本书由阿里巴巴安全专家刺总编写,是网络安全领域的经典之作,对于从事网络安全工作的专业人士来说是必备的参考资料。 资源描述 书名: 白帽子讲Web安全作者: 阿里巴巴刺总适用人群: 网络安全…

深度学习架构Seq2Seq-添加并理解注意力机制(一)

第一章:人工智能之不同数据类型及其特点梳理 第二章:自然语言处理(NLP):文本向量化从文字到数字的原理 第三章:循环神经网络RNN:理解 RNN的工作机制与应用场景(附代码) 第四章:循环神经网络RNN、LSTM以及GR…

基于springboot的丢失儿童的基因比对系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本丢失儿童的基因比对系统采用B/S架构,数据库是MySQL,网站的搭建与开发采用了先进的Java进行编写,使用了Spring Boot框架。该系统从两个对象:由管理员和用户来对系统进行设计构建。用户主要功能包括:用户注册、登…

Mysql面试篇笔记:

优化: 1.如何定位慢查询: 首先压测接口,查看那个接口比较慢,可以通过多种工具,比如Skywaking 可以查看各个接口响应时间,查看接口最慢,然后去跟踪接口,查看详细信息&#…