Python調(diào)用paddleocr編寫一個桌面端PDF識別工具
一. 前言
近期在研究 OCR 的一些工具 ,想著先試試本地識別 , 后面再嘗試一下 AI 的效率,最后選出一個好點的 。
這一篇主要是了解了一下 paddleocr 的使用。
二. 安裝啟動
官方使用文檔 :github.com/PaddlePaddle/PaddleOCR/blob/main/README_cn.md
環(huán)境準備
我這里使用的是 Anaconda 建的虛擬環(huán)境 ,以下可以跳過
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,并將結構化結果統(tǒng)一導出到 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' 支持中英文和數(shù)字)
ocr_version="PP-OCRv5", # 2. 模型版本:使用先進的PP-OCRv5
use_angle_cls=False, # 3. 方向矯正:自動檢測文字方向并旋轉(zhuǎn)圖片
# device="gpu:0", # (新版推薦) 這是更現(xiàn)代的寫法,指定使用0號GPU
use_tensorrt=False, # 5. TensorRT加速:在NVIDIA GPU上獲得極致性能 (需提前安裝TensorRT)
precision='fp16', # 6. 精度:使用半精度(fp16),速度更快,顯存占用更低 (需要GPU支持)
# --- 性能與設備優(yōu)化 (CPU用戶) ---
enable_mkldnn=True, # 7. MKLDNN加速:若在CPU上運行,此選項可提升Intel CPU的性能
cpu_threads=6, # 8. CPU線程數(shù):在CPU模式下運行時使用的核心數(shù)
# --- 效果微調(diào) ---
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)
# 初始化列表以保存所有頁面的數(shù)據(jù),用于最后統(tǒng)一導出
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()
# 驗證頁碼是否在有效范圍內(nèi) (fitz 從 0 開始索引, 用戶輸入從 1 開始)
if not (1 <= page_num <= doc.page_count):
logger.warning(f"警告:頁碼 {page_num} 超出范圍 (總頁數(shù): {doc.page_count})。已跳過。")
continue
logger.info(f"\n--- 正在處理第 {page_num} 頁 ---")
# 加載頁面并轉(zhuǎn)換為高分辨率圖像
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("成功提取的文本內(nèi)容:", all_texts)
# 現(xiàn)在 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 時發(fā)生嚴重錯誤:\n{error_stack}")
# 在所有頁面處理完畢后,將收集到的數(shù)據(jù)寫入一個 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 對象的準備



關于請求參數(shù)的作用
def predict(
self,
# 待識別的圖片,可以是路徑、URL或圖片數(shù)據(jù)
input,
# 是否自動旋轉(zhuǎn)圖片方向
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,
):
# ... 函數(shù)的具體實現(xiàn)邏輯 ...
pass
Result 結果

源碼 @ gitee.com/antblack/ant-tools/tree/Tools-PDF
以上就是Python調(diào)用paddleocr編寫一個桌面端PDF識別工具的詳細內(nèi)容,更多關于Python paddleocr識別PDF的資料請關注腳本之家其它相關文章!
相關文章
python中@property的作用和getter setter的解釋
這篇文章主要介紹了python中@property的作用和getter setter的解釋,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
解決運行django程序出錯問題 ''str''object has no attribute''_meta''
這篇文章主要介紹了解決運行django程序出錯問題 'str'object has no attribute'_meta',具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
從入門到驗證碼識別詳解Python OCR技術實戰(zhàn)指南
本文將深入淺出地講解如何利用Python中的pytesseract和PIL(Pillow)庫,實現(xiàn)圖片和截圖中文字的識別,并探索在簡單場景下如何處理驗證碼,感興趣的小伙伴可以了解下2026-03-03
Python如何利用pandas讀取csv數(shù)據(jù)并繪圖
這篇文章主要介紹了Python如何利用pandas讀取csv數(shù)據(jù)并繪圖,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07

