使用PaddleOCR读取pdf内容,输出txt文本

使用PaddleOCR读取PDF内容并输出为TXT文本,可以通过以下步骤实现。PaddleOCR是一个基于PaddlePaddle的OCR工具,支持多种语言的文本识别。

一、安装依赖

确保已安装PaddleOCR和相关的依赖库。

以下是代码中涉及的依赖库及其功能说明:

  1. os

    • 所属语言:Python 内置标准库
    • 功能:提供操作系统相关功能,如文件路径操作、目录管理等。
    • 示例用途:在处理文件时获取路径、创建目录等。
  2. fitz (PyMuPDF)

    • 安装命令pip install pymupdf
    • 功能:PDF 处理库,支持 PDF 解析、文本提取、图像渲染等。
    • 示例用途
      doc = fitz.open("example.pdf")  # 打开PDF文件
      page = doc[0]  # 获取第一页
      pix = page.get_pixmap()  # 渲染为图像
      
  3. PIL (Pillow)

    • 安装命令pip install pillow
    • 功能:Python 图像处理库,支持图像读取、编辑、转换等。
    • 示例用途
      from PIL import Image
      img = Image.open("image.jpg")  # 打开图像
      img = img.resize((500, 300))  # 调整尺寸
      
  4. 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)。

二、将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文本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值