OCR with PaddleOCR
概览
PaddleOCR 是一个功能强大的开源 OCR 工具包,支持多语言文本识别、表格识别和文档布局分析。这项技能涵盖了各种文档处理场景的实施模式。
前提条件
- Python 3.8+:PaddlePaddle 和 PaddleOCR 所需的版本
- PaddlePaddle:深度学习框架(CPU 或 GPU 版本)
- OpenCV:用于图像预处理和操作
- NumPy:用于数组操作
- 图像预处理:了解图像增强技术
- 深度学习基础:了解神经网络和模型推理
核心概念
- 检测模型:使用 DBNet 定位图像中的文本区域
- 识别模型:使用 CRNN 识别文本内容
- 方向分类器:确定文本方向(0°, 90°, 180°, 270°)
- 多语言支持:支持 80+ 种语言的特定模型
- 表格识别:专门用于提取结构化表格数据的模型
- 文档布局分析:识别文档结构(标题、段落、表格、图片)
- GPU 加速:CUDA 支持更快的推理
- 模型量化:INT8 量化,用于在边缘设备上部署
实施指南
安装
# CPU 版本
pip install paddlepaddle paddleocr
# GPU 版本(CUDA 11.2)
pip install paddlepaddle-gpu paddleocr
# GPU 版本(CUDA 11.8)
pip install paddlepaddle-gpu==2.5.2.post118 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
基本文本识别
from paddleocr import PaddleOCR
import cv2
# 初始化 PaddleOCR
ocr = PaddleOCR(use_angle_cls=True, lang='en')
# 读取图像
image_path = 'document.png'
image = cv2.imread(image_path)
# 执行 OCR
result = ocr.ocr(image, cls=True)
# 提取文本
for idx in range(len(result)):
res = result[idx]
for line in res:
print(line[1][0]) # 文本内容
多语言 OCR
from paddleocr import PaddleOCR
# 支持的语言:'ch', 'en', 'korean', 'japan', 'chinese_cht', 'ta', 'te', 'ka', 'ca', 'hi'
# 英语
ocr_en = PaddleOCR(use_angle_cls=True, lang='en')
# 中文
ocr_ch = PaddleOCR(use_angle_cls=True, lang='ch')
# 泰语
ocr_th = PaddleOCR(use_angle_cls=True, lang='th')
# 韩语
ocr_kr = PaddleOCR(use_angle_cls=True, lang='korean')
# 自定义语言模型
ocr_custom = PaddleOCR(
use_angle_cls=True,
lang='en',
det_model_dir='./custom_det/',
rec_model_dir='./custom_rec/',
cls_model_dir='./custom_cls/'
)
表格识别
from paddleocr import PaddleOCR
import cv2
# 初始化表格识别
ocr = PaddleOCR(
use_angle_cls=True,
lang='en',
table=True, # 启用表格识别
show_log=True
)
# 读取包含表格的图像
image = cv2.imread('table.png')
# 执行表格 OCR
result = ocr.ocr(image, cls=True)
# 提取表格数据
for idx in range(len(result)):
res = result[idx]
for line in res:
bbox, (text, confidence) = line
print(f"Text: {text}, Confidence: {confidence:.2f}")
文档布局分析
from paddleocr import PPStructure
# 初始化结构分析
table_engine = PPStructure(show_log=True)
# 分析文档布局
image_path = 'document.png'
result = table_engine(image_path)
# 处理布局结果
for region in result:
print(f"Type: {region['type']}")
print(f"Confidence: {region['score']:.2f}")
if region['type'] == 'table':
# 提取表格 HTML
html = region['res']['html']
print(f"Table HTML: {html}")
elif region['type'] == 'text':
# 提取文本
for text_line in region['res']:
print(f"Text: {text_line['text']}")
批量处理
from paddleocr import PaddleOCR
import os
import glob
# 初始化 OCR
ocr = PaddleOCR(use_angle_cls=True, lang='en')
# 处理多个图像
image_dir = 'documents/'
image_files = glob.glob(os.path.join(image_dir, '*.png'))
results = []
for image_file in image_files:
image = cv2.imread(image_file)
result = ocr.ocr(image, cls=True)
results.append({
'file': image_file,
'result': result
})
# 保存结果
import json
with open('ocr_results.json', 'w', encoding='utf-8') as f:
json.dump(results, f, ensure_ascii=False, indent=2)
GPU 加速
from paddleocr import PaddleOCR
# 初始化 GPU 支持
ocr = PaddleOCR(
use_angle_cls=True,
lang='en',
use_gpu=True, # 启用 GPU
gpu_mem=500, # GPU 内存以 MB 为单位
enable_mkldnn=True # 启用 MKLDNN 加速
)
自定义模型训练
# 准备训练数据
# 数据格式:image_path, text_content
# 训练自定义检测模型
!python tools/train.py -c configs/det/ch_PP-OCRv4/ch_PP-OCRv4_det.yml -o Global.pretrained_model=./your_model/best_accuracy
# 训练自定义识别模型
!python tools/train.py -c configs/rec/ch_PP-OCRv4/ch_PP-OCRv4_rec.yml -o Global.pretrained_model=./your_model/best_accuracy
# 导出模型进行推理
!python tools/export_model.py -c configs/det/ch_PP-OCRv4/ch_PP-OCRv4_det.yml -o Global.pretrained_model=./your_model/best_accuracy Global.save_inference_dir=./inference/det
结果处理
from paddleocr import PaddleOCR
import cv2
ocr = PaddleOCR(use_angle_cls=True, lang='en')
image = cv2.imread('document.png')
result = ocr.ocr(image, cls=True)
# 提取结构化结果
def extract_text_results(result):
"""提取并结构化 OCR 结果"""
extracted = []
for idx in range(len(result)):
res = result[idx]
for line in res:
bbox, (text, confidence) = line
# 计算边界框
x1 = min([point[0] for point in bbox])
y1 = min([point[1] for point in bbox])
x2 = max([point[0] for point in bbox])
y2 = max([point[1] for point in bbox])
extracted.append({
'text': text,
'confidence': confidence,
'bbox': {
'x1': x1,
'y1': y1,
'x2': x2,
'y2': y2
},
'points': bbox
})
return extracted
# 获取结构化结果
structured_results = extract_text_results(result)
# 按 Y 位置排序(从上到下)
sorted_results = sorted(structured_results, key=lambda x: x['bbox']['y1'])
# 打印结果
for item in sorted_results:
print(f"{item['text']} (confidence: {item['confidence']:.2f})")
可视化
import cv2
import numpy as np
from paddleocr import PaddleOCR
ocr = PaddleOCR(use_angle_cls=True, lang='en')
image = cv2.imread('document.png')
result = ocr.ocr(image, cls=True)
# 绘制边界框
def draw_ocr_results(image, result):
"""在图像上绘制 OCR 结果"""
image_copy = image.copy()
for idx in range(len(result)):
res = result[idx]
for line in res:
bbox, (text, confidence) = line
# 转换为 numpy 数组
points = np.array(bbox, dtype=np.int32)
# 绘制边界框
color = (0, 255, 0) if confidence > 0.9 else (0, 165, 255)
cv2.polylines(image_copy, [points], True, color, 2)
# 绘制文本
x, y = bbox[0]
cv2.putText(
image_copy,
f"{text} ({confidence:.2f})",
(int(x), int(y - 10)),
cv2.FONT_HERSHEY_SIMPLEX,
0.5,
color,
1
)
return image_copy
# 可视化
result_image = draw_ocr_results(image, result)
cv2.imwrite('ocr_result.png', result_image)
最佳实践
性能优化
# 使用适当的模型大小
# PP-OCRv4:最佳准确度,速度较慢
# PP-OCRv4-mobile:良好准确度,速度较快
# PP-OCRv4-server:服务器部署的最佳准确度
ocr = PaddleOCR(
use_angle_cls=True,
lang='en',
det_algorithm='DB', # 检测算法
rec_algorithm='CRNN', # 识别算法
use_tensorrt=True, # 启用 TensorRT 以加快推理速度
precision='fp16' # 使用 FP16 以加快推理速度
)
图像预处理
import cv2
import numpy as np
from paddleocr import PaddleOCR
def preprocess_image(image_path):
"""预处理图像以获得更好的 OCR 结果"""
image = cv2.imread(image_path)
# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 应用去噪
denoised = cv2.fastNlMeansDenoising(gray, None, 10, 7, 21)
# 应用自适应阈值处理
binary = cv2.adaptiveThreshold(
denoised, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2
)
return binary
# 使用预处理后的图像
ocr = PaddleOCR(use_angle_cls=True, lang='en')
processed_image = preprocess_image('document.png')
result = ocr.ocr(processed_image, cls=True)
错误处理
from paddleocr import PaddleOCR
import cv2
def safe_ocr(image_path, ocr):
"""安全 OCR 与错误处理"""
try:
image = cv2.imread(image_path)
if image is None:
raise ValueError(f"Failed to load image: {image_path}")
result = ocr.ocr(image, cls=True)
return result
except Exception as e:
print(f"OCR error: {e}")
return None
# 初始化 OCR
ocr = PaddleOCR(use_angle_cls=True, lang='en')
# 处理错误处理
result = safe_ocr('document.png', ocr)
if result:
# 处理结果
pass
置信度阈值
def filter_by_confidence(result, threshold=0.8):
"""通过置信度阈值过滤 OCR 结果"""
filtered = []
for idx in range(len(result)):
res = result[idx]
for line in res:
bbox, (text, confidence) = line
if confidence >= threshold:
filtered.append({
'text': text,
'confidence': confidence,
'bbox': bbox
})
return filtered
# 过滤低置信度结果
high_confidence_results = filter_by_confidence(result, threshold=0.8)
相关技能
- 图像预处理 - 为了提高 OCR 准确度的图像增强
- 文档解析 - 从文档中提取结构化数据
- OCR with Tesseract - 替代的 OCR 引擎
- PDF 处理 - 特定于 PDF 的处理技术
- 文档摄取流程 - 文档加载工作流