OCRwithPaddleOCR OCRwithPaddleOCR

PaddleOCR是一个强大的开源OCR工具包,支持多语言文本识别、表格识别和文档布局分析,适用于各种文档处理场景。

计算机视觉 0 次安装 0 次浏览 更新于 3/5/2026

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)

相关技能

额外资源