使用PaddleOCR读取PDF内容并输出为TXT文本,可以通过以下步骤实现。PaddleOCR是一个基于PaddlePaddle的OCR工具,支持多种语言的文本识别。
一、安装依赖
确保已安装PaddleOCR和相关的依赖库。
以下是代码中涉及的依赖库及其功能说明:
-
os
- 所属语言:Python 内置标准库
- 功能:提供操作系统相关功能,如文件路径操作、目录管理等。
- 示例用途:在处理文件时获取路径、创建目录等。
-
fitz (PyMuPDF)
- 安装命令:
pip install pymupdf
- 功能:PDF 处理库,支持 PDF 解析、文本提取、图像渲染等。
- 示例用途:
doc = fitz.open("example.pdf") # 打开PDF文件 page = doc[0] # 获取第一页 pix = page.get_pixmap() # 渲染为图像
- 安装命令:
-
PIL (Pillow)
- 安装命令:
pip install pillow
- 功能:Python 图像处理库,支持图像读取、编辑、转换等。
- 示例用途:
from PIL import Image img = Image.open("image.jpg") # 打开图像 img = img.resize((500, 300)) # 调整尺寸
- 安装命令:
-
paddleocr
- 安装命令:
pip install paddlepaddle-gpu # GPU版本(需CUDA支持) pip install paddleocr
- 功能:基于百度飞桨框架的 OCR 库,支持多语言文字识别。
- 示例用途:
ocr = PaddleOCR(use_angle_cls=True, lang="ch") # 初始化OCR模型 result = ocr.ocr("image.jpg", cls=True) # 识别图像中的文字
- 安装命令:
依赖关系总结
- 核心功能:PDF 解析(PyMuPDF)→ 图像提取(Pillow)→ 文字识别(PaddleOCR)。
- 注意事项:
- PaddleOCR 依赖飞桨框架(
paddlepaddle
),需根据环境选择 CPU/GPU 版本。 - PyMuPDF 在部分系统上可能需要额外安装依赖(如 Linux 需安装
libmupdf-dev
)。
- PaddleOCR 依赖飞桨框架(
二、将PDF转换为图像
PaddleOCR需要图像作为输入,因此需要将PDF文件转换为图像。
def pdf_to_images(pdf_path, image_dir):
pdf_doc = fitz.open(pdf_path)
for page_index in range(len(pdf_doc)):
page = pdf_doc[page_index]
img = page.get_pixmap(alpha=False) # 获取页面的图像
img_path = f"{image_dir}/page_{page_index + 1}.jpg"
Image.frombytes("RGB", [img.width, img.height], img.samples).save(img_path) # 保存为JPEG图像
三、使用PaddleOCR识别文本
将转换后的图像传递给PaddleOCR进行文本识别,并将结果保存到TXT文件中:
# 定义函数,参数为图片文件名
def extract_text_from_image(img_path, det_model_dir=None, rec_model_dir=None, cls_model_dir=None):
# 初始化 PaddleOCR,手动指定模型路径
ocr = PaddleOCR(
use_gpu=False, # 不启用 GPU
use_angle_cls=True,
lang='ch',
det_model_dir=det_model_dir, # 指定检测模型路径
rec_model_dir=rec_model_dir, # 指定识别模型路径
cls_model_dir=cls_model_dir, # 指定分类模型路径(可选)
use_space_char=True, # 启用空格识别
det_db_score_mode='fast', # 检测得分模式(fast 或 slow)
det_db_unclip_ratio=2.0 # 提高检测框扩展比例,减少漏检
)
# 读取图片并进行文字识别
result = ocr.ocr(img_path, cls=True)
# PaddleOCR 返回的 result 是一个列表,格式为 [[bbox, (text, prob)], ...]
# 提取文本和边界框
text_list = []
bbox_list = []
for line in result[0]: # result[0] 是第一个(也是唯一)图片的结果
bbox, (txt, prob) = line
text_list.append(txt)
bbox_list.append(bbox)
# 合并文本(按 y 坐标合并相邻行)
merged_text = []
current_line = ""
last_y = None
y_threshold = 20 # 假设 y 坐标差小于 20 像素为同一行
# 按 y 坐标排序结果(PaddleOCR 的 bbox 格式为 [[x1, y1], [x2, y2], [x3, y3], [x4, y4]])
sorted_result = sorted(zip(bbox_list, text_list), key=lambda x: x[0][0][1]) # 按左上角 y 坐标排序
for bbox, txt in sorted_result:
current_y = bbox[0][1] # 左上角 y 坐标
if last_y is None or abs(current_y - last_y) < y_threshold:
current_line += txt
else:
if current_line:
merged_text.append(current_line)
current_line = txt
last_y = current_y
if current_line:
merged_text.append(current_line)
# 返回提取的文本列表
return merged_text
完整代码示例
以下是完整的代码示例:
import os
import fitz # PyMuPDF库
from PIL import Image
from paddleocr import PaddleOCR
#一、将pdf每页的内容转换为每张图片
def pdf_to_images(pdf_path, image_dir):
pdf_doc = fitz.open(pdf_path)
for page_index in range(len(pdf_doc)):
page = pdf_doc[page_index]
img = page.get_pixmap(alpha=False) # 获取页面的图像
img_path = f"{image_dir}/page_{page_index + 1}.jpg"
Image.frombytes("RGB", [img.width, img.height], img.samples).save(img_path) # 保存为JPEG图像
#二、读取图片目录下的图片,提取图片内容并写入txt文本
def ocr_images(image_dir):
results=[]
for img_name in os.listdir(image_dir):
if img_name.endswith(".jpg"): # 只处理JPEG图像
img_path = f"{image_dir}/{img_name}"
# 调用函数提取文本
extracted_text = extract_text_from_image(
img_path,
det_model_dir=det_model_path,
rec_model_dir=rec_model_path,
cls_model_dir=cls_model_path
)
# 返回提取的文本列表
# return extracted_text
# result = ocr.ocr(img_path, cls=True) # 进行OCR识别
results.append(extracted_text) # 保存识别结果
return results
# 定义函数,参数为图片文件名
def extract_text_from_image(img_path, det_model_dir=None, rec_model_dir=None, cls_model_dir=None):
# 初始化 PaddleOCR,手动指定模型路径
ocr = PaddleOCR(
use_gpu=False, # 不启用 GPU
use_angle_cls=True,
lang='ch',
det_model_dir=det_model_dir, # 指定检测模型路径
rec_model_dir=rec_model_dir, # 指定识别模型路径
cls_model_dir=cls_model_dir, # 指定分类模型路径(可选)
use_space_char=True, # 启用空格识别
det_db_score_mode='fast', # 检测得分模式(fast 或 slow)
det_db_unclip_ratio=2.0 # 提高检测框扩展比例,减少漏检
)
# 读取图片并进行文字识别
result = ocr.ocr(img_path, cls=True)
# PaddleOCR 返回的 result 是一个列表,格式为 [[bbox, (text, prob)], ...]
# 提取文本和边界框
text_list = []
bbox_list = []
for line in result[0]: # result[0] 是第一个(也是唯一)图片的结果
bbox, (txt, prob) = line
text_list.append(txt)
bbox_list.append(bbox)
# 合并文本(按 y 坐标合并相邻行)
merged_text = []
current_line = ""
last_y = None
y_threshold = 20 # 假设 y 坐标差小于 20 像素为同一行
# 按 y 坐标排序结果(PaddleOCR 的 bbox 格式为 [[x1, y1], [x2, y2], [x3, y3], [x4, y4]])
sorted_result = sorted(zip(bbox_list, text_list), key=lambda x: x[0][0][1]) # 按左上角 y 坐标排序
for bbox, txt in sorted_result:
current_y = bbox[0][1] # 左上角 y 坐标
if last_y is None or abs(current_y - last_y) < y_threshold:
current_line += txt
else:
if current_line:
merged_text.append(current_line)
current_line = txt
last_y = current_y
if current_line:
merged_text.append(current_line)
# 返回提取的文本列表
return merged_text
#定义函数 将数组内容提取出每行,换行
def write_array_to_txt(data, file_path):
"""
将多维数组内容写入txt文件,每个数组元素占一行
Args:
data: 多维数组数据
file_path: 输出文件路径
"""
try:
with open(file_path, 'w', encoding='utf-8') as file:
# 遍历每个子数组
for sub_array in data:
# 将子数组中的元素用空格连接成字符串
line = '\n'.join(map(str, sub_array))
# 写入文件并添加换行符
file.write(line + '\n')
print(f"成功将数据写入文件:{file_path}")
except Exception as e:
print(f"写入文件时出错:{e}")
# 主程序:调用函数并处理结果
if __name__ == "__main__":
# 用户传入图片文件名
# image_path = './images/img02.jpg'
# 将PDF转换为图像
pdf_to_images('./pdf/testpdf01.pdf', './images')
# 指定模型路径(替换为你下载并解压后的模型路径)
det_model_path = './models/ch_PP-OCRv4_det_server_infer.tar' # 检测模型路径
rec_model_path = './models/ch_PP-OCRv4_rec_server_infer.tar' # 识别模型路径
cls_model_path = './models/ch_ppocr_mobile_v2.0_cls_slim_infer.tar' # 分类模型路径(可选)
# 调用函数提取文本
print("Loading PaddleOCR model...")
extracted_text = ocr_images(
'./images'
)
print("Model loaded and text extracted successfully.")
# 打印提取的文本
print("\n提取的所有文本:")
print(extracted_text)
# for text in extracted_text:
# print(text)
# 保存到文件
# with open('./result/result.txt', 'w', encoding='utf-8') as f:
# for text in extracted_text:
# f.write(text + '\n')
# 指定输出文件路径
output_file = 'testpdf01.txt'
# 调用函数写入文件
write_array_to_txt(extracted_text, output_file)
注意事项
- 确保PDF文件路径正确。
- 如果PDF文件包含多页,`会将每一页转换为一个图像。
- PaddleOCR支持多种语言,可以根据需要设置
lang
参数。
通过以上步骤,可以将PDF文件中的内容提取并保存为TXT文本。