PaddleOCR 與 PaddleX 調試
- 1.安裝
- 1.1 環境準備
- 1.2用Conda創建虛擬環境
- 2.測試
- 2.1發票測試
- 2.2 手寫漢字識別
- 3.PaddleOCR 與 PaddleX 對比
- 3.1 基于 PaddleX 部署 OCR 服務
1.安裝
PP OCR 文檔
1.1 環境準備
根據自己操作系統按網上指導安裝 ccache
ccache --version
是否已安裝 ccache 測試
設置 Paddlex 環境變量 PADDLE_PDX_CACHE_HOME
以 Windows 為例
1.2用Conda創建虛擬環境
## 創建
conda create -n env-ocr python=3.10
## 激活
conda activate env-ocr
## 精簡安裝
pip install paddlepaddle==3.1.0
pip install paddleocr==3.1.0
非精簡安裝
## 下載源碼
git clone https://github.com/PaddlePaddle/PaddleOCR.git
## 進入源碼目錄,并激活虛擬環境
conda activate env-ocr
## 安裝
pip install -e . --no-deps
2.測試
使用 Git 提供的用例代碼
from paddleocr import PaddleOCR
# Initialize PaddleOCR instance
ocr = PaddleOCR(use_doc_orientation_classify=False,use_doc_unwarping=False,use_textline_orientation=False)# Run OCR inference on a sample image
result = ocr.predict(input="invoice.jpg")# Visualize the results and save the JSON results
for res in result:res.print()res.save_to_img("output")res.save_to_json("output")
首次執行會自動下載模型依賴
2.1發票測試
結果
2.2 手寫漢字識別
結果(部分識別不準確)
3.PaddleOCR 與 PaddleX 對比
維度?? | ?PaddleOCR ?? | PaddleX |
---|---|---|
核心目標?? | 專用OCR算法庫 | 深度學習全流程工具鏈 |
??使用場景?? | 需精細調優OCR模型時 | 快速集成OCR到完整應用(含其他AI任務) |
??部署靈活性 | 支持 Python/C++ 等原生部署 | 提供 HTTP 服務、Docker 等標準化部署方案 |
??開發復雜度?? | 需直接處理OCR技術細節 | 低代碼調用,簡化流程 |
3.1 基于 PaddleX 部署 OCR 服務
## 安裝服務插件
paddlex --install serving
## 以 API 服務形式啟動(服務部署可以改成后臺進程形式啟動)
paddlex --serve --pipeline OCR --port 8800
查看接口文檔:http://127.0.0.1:8800/docs
測試用腳本
import base64
import requests
import json
import os
import argparse
from typing import List, Dict, Any, Tupleclass PaddleXOCRApiClient:"""PaddleX OCR 服務的客戶端類"""def __init__(self, host: str = "localhost", port: int = 8800) -> None:"""初始化 OCR 客戶端Args:host: 服務主機地址port: 服務端口"""self.base_url = f"http://{host}:{port}"self.ocr_url = f"{self.base_url}/ocr"def recognize_text(self, image_path: str) -> Dict[str, Any]:"""從單張圖像中識別文本Args:image_path: 圖像文件路徑Returns:包含識別結果的字典"""if not os.path.exists(image_path):raise FileNotFoundError(f"文件不存在: {image_path}")try:with open(image_path, "rb") as f:base64_data = base64.b64encode(f.read()).decode("utf-8")payload = {"file": base64_data,"fileType": 1# "useDocOrientationClassify": true,# "useDocUnwarping": true,# "useTextlineOrientation": true,# "textDetLimitSideLen": 0,# "textDetLimitType": "string",# "textDetThresh": 0,# "textDetBoxThresh": 0,# "textDetUnclipRatio": 0,# "textRecScoreThresh": 0,# "visualize": true}# print(payload)response = requests.post(self.ocr_url, json=payload,headers={"Accept": "application/json"})if response.status_code == 200:return response.json()else:raise Exception(f"請求失敗,狀態碼: {response.status_code}, 錯誤信息: {response.text}")except Exception as e:print(f"識別過程發生錯誤: {str(e)}")return {"error": str(e), "results": []}def recognize_text_from_dir(self, dir_path: str) -> Dict[str, Dict[str, Any]]:"""從目錄中的所有圖像文件識別文本Args:dir_path: 圖像目錄路徑Returns:包含所有圖像識別結果的字典"""if not os.path.isdir(dir_path):raise NotADirectoryError(f"不是有效目錄: {dir_path}")supported_extensions = {".jpg", ".jpeg", ".png", ".bmp", ".webp"}results = {}for filename in os.listdir(dir_path):ext = os.path.splitext(filename)[1].lower()if ext in supported_extensions:file_path = os.path.join(dir_path, filename)results[filename] = self.recognize_text(file_path)return resultsdef format_results(self, results: Dict[str, Any]) -> str:"""格式化識別結果為易讀的文本Args:results: 識別結果字典Returns:格式化后的文本"""formatted_text = ""if results["errorCode"] != 0:formatted_text += f"錯誤: {results['errorMsg']}\n"return formatted_textresult = results['result']['ocrResults'][0]for text in result['prunedResult']['rec_texts']:formatted_text += text + "\n"return formatted_text if formatted_text else "未檢測到文本"def main():parser = argparse.ArgumentParser(description="PaddleX OCR 服務客戶端")parser.add_argument("--host", default="localhost", help="OCR 服務主機")parser.add_argument("--port", type=int, default=8800, help="OCR 服務端口")parser.add_argument("--image", help="待識別的圖像文件路徑")parser.add_argument("--dir", help="待識別的圖像目錄路徑")parser.add_argument("--output", help="輸出結果的 JSON 文件路徑")parser.add_argument("--verbose", action="store_true", help="顯示詳細的識別結果")args = parser.parse_args()# 驗證輸入參數if not args.image and not args.dir:parser.error("請指定 --image 或 --dir 參數")if args.image and args.dir:parser.error("--image 和 --dir 參數不能同時使用")try:client = PaddleXOCRApiClient(args.host, args.port)if args.image:# 處理單張圖像results = client.recognize_text(args.image)if args.verbose:print(f"圖像: {args.image}")print(client.format_results(results))if args.output:with open(args.output, "w", encoding="utf-8") as f:json.dump(results, f, ensure_ascii=False, indent=2)print(f"結果已保存到: {args.output}")elif args.dir:# 處理目錄中的所有圖像all_results = client.recognize_text_from_dir(args.dir)if args.verbose:for filename, results in all_results.items():print(f"\n圖像: {filename}")print(client.format_results(results))if args.output:with open(args.output, "w", encoding="utf-8") as f:json.dump(all_results, f, ensure_ascii=False, indent=2)print(f"所有結果已保存到: {args.output}")except Exception as e:print(f"執行過程中發生錯誤: {str(e)}")if __name__ == "__main__":main()
Test 圖片
Test-Hand
驗證
## 打印字體
python test.py --image test.jpg --verbose --output result.json
## 手寫字體
python test.py --image test-hand.jpg --verbose --output result.json
??