一. 前言
近期在研究 ocr 的一些工具 ,想着先试试本地识别 , 后面再尝试一下 ai 的效率,最后选出一个好点的 。
这一篇主要是了解了一下 paddleocr 的使用。
二. 安装启动
官方使用文档 :github.com/paddlepaddle/paddleocr/blob/main/readme_cn.md
环境准备
我这里使用的是 anaconda 建的虚拟环境 ,以下可以跳过
conda create --prefix "d:\code\python\enviroment\pdf_env" python=3.11.9
conda activate "d:\code\python\enviroment\pdf_env"
anaconda
# 安装基础组件 pip install pyqt6 pip install pyqt6-webengine pip install pyqt6-frameless-window pip install pyqt6-fluent-widgets -i https://pypi.org/simple/ # 安装 paddleocr pip install paddleocr # 安装 paddlepaddle (这里为了避免性能要求高,所以采用cpu 版本) # 另外还有性能更好的 gpu 版本 -> https://www.paddlepaddle.org.cn/install/quick python -m pip install paddlepaddle==3.1.0 -i https://www.paddlepaddle.org.cn/packages/stable/cpu/ # 安装 pymupdf 用于处理 pdf pip install pymupdf
运行项目 (cpu )


结果是出来了 ,但是这性能太吓人了 ,我这 cpu 也不算差呀
换个 gpu 试试
python -m pip uninstall paddlepaddle
查看自己的版本(windows 版本)
nvidia-smi
安装对应版本
python -m pip install paddlepaddle-gpu==3.1.0 -i https://www.paddlepaddle.org.cn/packages/stable/cu126/


三. 核心代码
import os
import fitz # pymupdf
from paddleocr import paddleocr
import time
from datetime import datetime
from prettytable import prettytable
import csv
import traceback
import logging
import json
# 配置日志
logging.basicconfig(
level=logging.info,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.filehandler("ocr_service.log"),
logging.streamhandler()
]
)
logger = logging.getlogger("ocr_service")
def ocr_pdf_pages(pdf_path: str, page_numbers: list[int], output_dir: str = none):
"""
使用 paddleocr 对 pdf 文件的指定页面进行 ocr,并将结构化结果统一导出到 csv。
args:
pdf_path (str): pdf 文件的路径。
page_numbers (list[int]): 需要读取的页码列表 (例如 [1, 3, 5])。
output_dir (str, optional): 输出结果的目录。如果指定,将保存图片、json 和汇总的 csv 文件。
"""
start_time = time.time()
start_datetime = datetime.now().strftime("%y-%m-%d %h:%m:%s")
logger.info(f"开始处理时间: {start_datetime}")
if not os.path.exists(pdf_path):
logger.error(f"错误:找不到 pdf 文件 '{pdf_path}'")
return
# 初始化 paddleocr 引擎
logger.info("正在初始化 paddleocr 引擎,这可能需要一些时间...")
ocr_start_time = time.time()
ocr = paddleocr(
# --- 核心功能与模型设置 ---
lang="ch", # 1. 语言:指定为中文模型('ch' 支持中英文和数字)
ocr_version="pp-ocrv5", # 2. 模型版本:使用先进的pp-ocrv5
use_angle_cls=false, # 3. 方向矫正:自动检测文字方向并旋转图片
# device="gpu:0", # (新版推荐) 这是更现代的写法,指定使用0号gpu
use_tensorrt=false, # 5. tensorrt加速:在nvidia gpu上获得极致性能 (需提前安装tensorrt)
precision='fp16', # 6. 精度:使用半精度(fp16),速度更快,显存占用更低 (需要gpu支持)
# --- 性能与设备优化 (cpu用户) ---
enable_mkldnn=true, # 7. mkldnn加速:若在cpu上运行,此选项可提升intel cpu的性能
cpu_threads=6, # 8. cpu线程数:在cpu模式下运行时使用的核心数
# --- 效果微调 ---
text_rec_score_thresh=0.5, # 9. 识别阈值:只返回置信度高于 0.5 的识别结果,过滤掉模糊的猜测
)
ocr_end_time = time.time()
logger.info(f"引擎初始化完成。耗时: {ocr_end_time - ocr_start_time:.2f} 秒")
# 如果指定了输出目录,确保它存在
if output_dir:
os.makedirs(output_dir, exist_ok=true)
# 初始化列表以保存所有页面的数据,用于最后统一导出
all_csv_rows = []
csv_header = ['page', 'text', 'score', 'x_min', 'y_min', 'x_max', 'y_max']
try:
# 打开 pdf 文件
doc = fitz.open(pdf_path)
# 遍历指定的页码
for page_num in page_numbers:
page_start_time = time.time()
# 验证页码是否在有效范围内 (fitz 从 0 开始索引, 用户输入从 1 开始)
if not (1 <= page_num <= doc.page_count):
logger.warning(f"警告:页码 {page_num} 超出范围 (总页数: {doc.page_count})。已跳过。")
continue
logger.info(f"\n--- 正在处理第 {page_num} 页 ---")
# 加载页面并转换为高分辨率图像
page = doc.load_page(page_num - 1)
pix = page.get_pixmap(dpi=300)
temp_img_path = f"temp_page_{page_num}.png"
pix.save(temp_img_path)
# 进行 ocr 识别
predict_start_time = time.time()
result = ocr.predict(input=temp_img_path)
predict_end_time = time.time()
logger.info(f"ocr 识别耗时: {predict_end_time - predict_start_time:.2f} 秒")
# 处理单页的识别结果
# predict 返回一个列表,对于单个图像,我们只关心第一个元素
page_result_obj = result[0] if result else none
if page_result_obj:
# 你原来的代码
page_result_obj.print()
page_result_obj.save_to_img("output")
page_result_obj.save_to_json("output")
# --- 新增代码 ---
# 1. 使用点号(.)直接获取 rec_texts 属性的值,并存入新变量 all_texts
all_texts = page_result_obj['rec_texts']
# 2. (可选) 打印这个新变量,验证结果
print("成功提取的文本内容:", all_texts)
# 现在 all_texts 就是一个列表,包含了所有识别出的文本
# 你可以对它进行任何操作,比如遍历
for text_item in all_texts:
print(f"识别到的单项文本: {text_item}")
else:
logger.info(f"--- 第 {page_num} 页未识别到文本 ---")
# 删除临时图像文件
if os.path.exists(temp_img_path):
os.remove(temp_img_path)
page_end_time = time.time()
logger.info(f"第 {page_num} 页处理完成,耗时: {page_end_time - page_start_time:.2f} 秒")
doc.close()
except exception as e:
# 使用 traceback.format_exc() 获取完整的异常栈字符串
error_stack = traceback.format_exc()
# 将其与您的自定义信息一起打印出来
logger.error(f"处理 pdf 时发生严重错误:\n{error_stack}")
# 在所有页面处理完毕后,将收集到的数据写入一个 csv 文件
if output_dir and all_csv_rows:
csv_path = os.path.join(output_dir, "structured_ocr_results.csv")
logger.info(f"\n正在将所有结果汇总到: {csv_path}")
try:
with open(csv_path, 'w', newline='', encoding='utf-8-sig') as f:
writer = csv.writer(f)
writer.writerow(csv_header)
writer.writerows(all_csv_rows)
logger.info(f"✅ 汇总 csv 文件已成功保存!")
except ioerror as e:
logger.error(f"❌ 汇总导出 csv 文件失败: {e}")
end_time = time.time()
end_datetime = datetime.now().strftime("%y-%m-%d %h:%m:%s")
total_time = end_time - start_time
logger.info(f"\n处理结束时间: {end_datetime}")
logger.info(f"总处理时间: {total_time:.2f} 秒 ({total_time/60:.2f} 分钟)")
使用效果 :


四. 使用时的一些注意事项
paddleocr 对象的准备



关于请求参数的作用
def predict(
self,
# 待识别的图片,可以是路径、url或图片数据
input,
# 是否自动旋转图片方向
use_doc_orientation_classify=none,
# 是否自动校正弯曲图片
use_doc_unwarping=none,
# 是否自动判断文本行方向
use_textline_orientation=none,
# 临时修改文本检测模型的最长边限制
text_det_limit_side_len=none,
# 临时修改文本检测的最长边限制类型
text_det_limit_type=none,
# 临时修改文本检测的二值化阈值
text_det_thresh=none,
# 临时修改文本检测的检测框得分阈值
text_det_box_thresh=none,
# 临时修改文本检测的文本框扩大比例
text_det_unclip_ratio=none,
# 临时修改文本识别的置信度阈值
text_rec_score_thresh=none,
# 结果保存格式 (txt, json, pdf, pdf_searchable)
save_format=none,
# 结果保存路径
save_path=none,
# 结果可视化或生成pdf时使用的字体路径
font_path=none,
):
# ... 函数的具体实现逻辑 ...
pass
result 结果

源码 @ gitee.com/antblack/ant-tools/tree/tools-pdf
以上就是python调用paddleocr编写一个桌面端pdf识别工具的详细内容,更多关于python paddleocr识别pdf的资料请关注代码网其它相关文章!
发表评论