【PaddleOCR教程01】PP-OCRv5 全面指南:从模型架构到实战部署
导语
PaddleOCR 3.5.0 默认已经悄悄切到了 PP-OCRv5,但官方文档散落在各个角落,模型命名也改了好几轮。很多人还在用 use_angle_cls=True 这种 2.x 遗留参数,不知道它在 3.x 里到底映射到了什么。
这篇文章把 PP-OCRv5 的模型体系、API 参数、多语言配置、GPU 加速、自定义模型路径这些内容一次性讲清楚。不是翻译文档------每个知识点都带可运行的代码,踩过的坑也会标出来。文末附一个真实项目(手机号 OCR 提取)的完整实战案例,你可以直接抄过去改改就能用。
前置条件:会 Python,知道什么是 OCR,没用过 PaddleOCR 也没关系。本文以 PaddleOCR 3.5.0 + PaddlePaddle 3.1.0 为准。
一、PP-OCRv5 到底是什么?
一句话:PP-OCRv5 是 PaddleOCR 的第五代文字识别模型,包含检测(det)、识别(rec)、方向分类(cls/doc_ori)、去扭曲(unwarp)四类子模型,覆盖 80+ 语言。
跟 PP-OCRv4 的区别主要在两点:
- det 和 rec 模型精度大幅提升------server 版 det 的 Hmean 从 69.2% 涨到 83.8%,rec 从 85.19% 涨到 86.38%
- 模型命名和加载方式统一了 ------不再有
ch_PP-OCRv4_det这种带语言前缀的命名,det/rec 模型名直接就是PP-OCRv5_server_det、PP-OCRv5_server_rec
本章小结
| 维度 | PP-OCRv4 | PP-OCRv5 |
|---|---|---|
| 默认版本 | 3.x 以前默认 | PaddleOCR 3.5.0 默认(lang="ch" 自动选择) |
| det 精度 | 69.2% (server) | 83.8% (server) |
| rec 精度 | 85.19% (server) | 86.38% (server) |
| 模型命名 | ch_PP-OCRv4_det |
PP-OCRv5_server_det |
| 多语言 | 每种语言独立模型名 | 语言前缀 + 统一后缀(如 en_PP-OCRv5_mobile_rec) |
二、环境搭建
2.1 安装依赖
bash
pip install paddlepaddle==3.1.0 paddleocr==3.5.0
⚠️ 避坑提醒 :paddlepaddle 和 paddleocr 的版本要对应。3.5.0 的 paddleocr 推荐搭配 3.1.0 的 paddlepaddle,版本不匹配可能导致模型加载失败。别问我怎么知道的。
2.2 最快验证方式
一行命令搞定,不需要写 Python:
bash
paddleocr ocr -i https://paddle-model-ecology.bj.bcebos.com/paddlex/imgs/demo_image/general_ocr_002.png \
--use_doc_orientation_classify False \
--use_doc_unwarping False \
--save_path ./output
✅ 成功标志 :output/ 目录下生成标注了文字框的图片和 JSON 结果文件。
2.3 Python 最小示例
python
from paddleocr import PaddleOCR
ocr = PaddleOCR(lang="ch")
result = ocr.predict("./test.png")
for res in result:
res.print()
就这么三行。lang="ch" 会自动加载 PP-OCRv5 的中文 server 模型(det + rec),首次运行会自动下载模型文件。
三、PP-OCRv5 模型全景
这一章把所有模型列清楚,搞明白每个模型是干什么的,后面配参数才不会懵。
3.1 文本检测模型(det)
负责定位图片中"哪里有文字",输出文字区域的多边形坐标。
| 模型名 | 大小 | 精度 (Hmean) | 适用场景 |
|---|---|---|---|
PP-OCRv5_server_det |
84.3 MB | 83.8% | 服务端部署,精度优先 |
PP-OCRv5_mobile_det |
4.7 MB | 79.0% | 端侧/嵌入式,速度优先 |
3.2 文本识别模型(rec)
负责把检测到的文字区域"读出来",输出文字内容和置信度。
| 模型名 | 大小 | 精度 | 适用场景 |
|---|---|---|---|
PP-OCRv5_server_rec |
81 MB | 86.38% | 中/繁/日文,服务端 |
PP-OCRv5_mobile_rec |
16 MB | 81.29% | 中/繁/日文,端侧 |
en_PP-OCRv5_mobile_rec |
7.5 MB | 85.25% | 英文专用 |
latin_PP-OCRv5_mobile_rec |
14 MB | 84.7% | 拉丁文系 |
korean_PP-OCRv5_mobile_rec |
14 MB | 88.0% | 韩文专用 |
arabic_PP-OCRv5_mobile_rec |
7.6 MB | 81.27% | 阿拉伯文专用 |
cyrillic_PP-OCRv5_mobile_rec |
7.7 MB | 80.27% | 斯拉夫字母 |
devanagari_PP-OCRv5_mobile_rec |
7.5 MB | 84.96% | 天城文(印地语等) |
te_PP-OCRv5_mobile_rec |
7.5 MB | 87.65% | 泰卢固文 |
ta_PP-OCRv5_mobile_rec |
7.5 MB | 94.2% | 泰米尔文 |
th_PP-OCRv5_mobile_rec |
7.5 MB | 82.68% | 泰文 |
el_PP-OCRv5_mobile_rec |
7.5 MB | 89.28% | 希腊文 |
🔴 重点 :lang="ch" 时默认用的是 PP-OCRv5_server_rec(server 版),不是 mobile 版。想用轻量模型要手动指定。
3.3 辅助模型
这些模型不直接做 OCR,但负责"预处理"------让 det 和 rec 在更干净的输入上工作。
| 模型名 | 大小 | 作用 | 默认启用? |
|---|---|---|---|
PP-LCNet_x1_0_doc_ori |
7 MB | 文档图像方向分类(0°/90°/180°/270°) | 否 |
PP-LCNet_x0_25_textline_ori |
0.96 MB | 文本行方向分类(0°/180°) | 否 |
PP-LCNet_x1_0_textline_ori |
6.5 MB | 文本行方向分类(高精度版) | 否 |
UVDoc |
--- | 文档去扭曲(弯曲矫正) | 否 |
⚠️ 注意 :use_angle_cls=True 是 PaddleOCR 2.x 的遗留参数,在 3.x 里会自动映射为 use_textline_orientation=True,对应模型是 PP-LCNet_x0_25_textline_ori。很多人以为它对应的是某个独立的 "cls" 模型,其实不是。
四、核心 API 参数详解
4.1 基础参数
python
from paddleocr import PaddleOCR
ocr = PaddleOCR(
lang="ch", # 语言,默认 "ch"
ocr_version="PP-OCRv5", # OCR 版本,默认 "PP-OCRv5"(lang="ch" 时自动选择)
device="cpu", # 推理设备,支持 "cpu"、"gpu:0" 等
)
lang 和 ocr_version 的关系:如果只指定 lang,系统会自动选择对应的 ocr_version。lang="ch" 时默认用 PP-OCRv5。
4.2 检测参数调优
python
ocr = PaddleOCR(
lang="ch",
text_det_limit_side_len=960, # 检测时图片长边限制,默认 960
text_det_limit_type="max", # "max" 按最大边限制,"min" 按最小边限制
text_det_thresh=0.3, # 像素级检测阈值,默认 0.3。越低越灵敏
text_det_box_thresh=0.5, # 检测框置信度阈值,默认 0.6
text_det_unclip_ratio=2.0, # 文本区域扩展系数,默认 2.0
)
说直白点:
text_det_thresh:控制"什么像素算文字"。0.3 意味着概率 > 30% 的像素就算文字,适合模糊/低对比度场景。调到 0.5 会更严格,但可能漏检text_det_box_thresh:控制"什么框算有效"。框内像素平均分要超过这个值才保留。0.5 比默认 0.6 更宽松text_det_limit_side_len:图片太大会很慢,这个参数控制缩放。960 是个平衡点
4.3 识别参数
python
ocr = PaddleOCR(
lang="ch",
text_rec_score_thresh=0.0, # 识别分数阈值,默认 0.0(不过滤)
text_recognition_batch_size=1, # 识别批大小,默认 1
)
text_rec_score_thresh=0.0 意味着所有识别结果都保留,不管置信度多低。如果你的场景对准确率要求高,可以调到 0.3~0.5 过滤低置信度结果。
4.4 方向分类与去扭曲
python
ocr = PaddleOCR(
lang="ch",
use_doc_orientation_classify=True, # 启用文档方向分类(横屏/倒置检测)
use_doc_unwarping=True, # 启用文档去扭曲(弯曲矫正)
use_textline_orientation=True, # 启用文本行方向分类(180° 翻转检测)
)
这三个参数默认都是 None(由系统决定是否启用)。在大多数场景下,禁用它们能显著提升速度,因为少跑三个模型。只有当你的输入图片确实存在方向问题时才需要打开。
本章小结
| 参数 | 默认值 | 调大效果 | 调小效果 |
|---|---|---|---|
text_det_thresh |
0.3 | 更严格,漏检增加 | 更灵敏,噪声增加 |
text_det_box_thresh |
0.6 | 更严格,框更少 | 更宽松,框更多 |
text_det_limit_side_len |
960 | 更清晰,更慢 | 更快,可能漏检小字 |
text_rec_score_thresh |
0.0 | 过滤低置信度结果 | 保留更多结果 |
text_det_unclip_ratio |
2.0 | 框更大,覆盖更多 | 框更紧凑 |
五、实战场景
5.1 多语言 OCR
PaddleOCR 3.x 的语言配置非常统一,切换语言只需要改 lang 参数:
python
# 英文
ocr_en = PaddleOCR(lang="en")
# 日文
ocr_ja = PaddleOCR(lang="japan")
# 繁体中文
ocr_cht = PaddleOCR(lang="chinese_cht")
# 法文
ocr_fr = PaddleOCR(lang="fr")
# 韩文
ocr_kr = PaddleOCR(lang="korean")
支持 80+ 种语言,完整列表见 PaddleOCR 官方文档。
5.2 切换 server/mobile 模型
默认用的是 server 模型(精度高但体积大)。如果部署在边缘设备或对速度敏感,切到 mobile 版:
python
# 使用移动端轻量模型(det 4.7MB + rec 16MB)
ocr_mobile = PaddleOCR(
text_detection_model_name="PP-OCRv5_mobile_det",
text_recognition_model_name="PP-OCRv5_mobile_rec",
use_doc_orientation_classify=False,
use_doc_unwarping=False,
use_textline_orientation=False,
)
5.3 回退到 PP-OCRv4
如果 PP-OCRv5 在你的场景下效果不好,可以显式回退:
python
ocr_v4 = PaddleOCR(ocr_version="PP-OCRv4", lang="ch")
PP-OCRv4 中文模型组合:PP-OCRv4_mobile_det + PP-OCRv4_mobile_rec。
5.4 GPU 加速
python
# 使用第一块 GPU
ocr_gpu = PaddleOCR(device="gpu:0")
⚠️ 注意 :GPU 推理需要安装对应的 PaddlePaddle GPU 版本(paddlepaddle-gpu),光装 paddlepaddle 是不行的。
5.5 自定义模型路径
如果你微调了模型,或者网络环境差需要离线部署:
python
# 指定检测模型路径
ocr = PaddleOCR(
text_detection_model_dir="./my_finetuned_det",
text_detection_model_name="PP-OCRv5_server_det", # 如果模型名不是默认的,需要显式指定
)
⚠️ 避坑提醒 :text_detection_model_name 和 text_detection_model_dir 要一起用。如果你的模型文件名不是默认的,必须告诉系统你用的是哪个模型。
5.6 程序化获取结果
predict() 返回的结果不只是打印用的,可以直接提取结构化数据:
python
from paddleocr import PaddleOCR
ocr = PaddleOCR(lang="ch")
result = ocr.predict("./document.png")
for res in result:
json_result = res.json
# 识别出的所有文本
texts = json_result["rec_texts"]
# 每个文本的置信度
scores = json_result["rec_scores"]
# 每个文本的多边形坐标
polys = json_result["rec_polys"]
for text, score in zip(texts, scores):
print(f"{text} (置信度: {score:.2f})")
六、踩坑记录
坑 1:use_angle_cls 到底对应哪个模型?
现象 :代码里写了 use_angle_cls=True,但不确定它在 3.x 里映射到了什么。
原因 :PaddleOCR 3.x 为了兼容 2.x 的接口,保留了 use_angle_cls 参数,但内部做了映射:
python
# 2.x 写法
ocr = PaddleOCR(use_angle_cls=True)
# 3.x 等价写法
ocr = PaddleOCR(use_textline_orientation=True)
对应模型是 PP-LCNet_x0_25_textline_ori(0.96 MB),不是某个叫 "cls" 的独立模型。
验证方式 :看源码 paddleocr/_pipelines/ocr.py 第 46 行:
python
_DEPRECATED_PARAM_NAME_MAPPING = {
"use_angle_cls": "use_textline_orientation",
...
}
坑 2:首次运行巨慢,以为卡死了
现象 :第一次 PaddleOCR(lang="ch") 跑了两三分钟才出结果。
原因:首次运行会自动下载模型文件(det 84MB + rec 81MB + 辅助模型),总下载量约 170MB。后续运行就快了(模型缓存在本地)。
解决方案:
- 预下载模型:首次运行时耐心等
- 离线部署:把模型文件放到指定目录,用
text_detection_model_dir参数指向 - Docker 部署:用命名卷持久化模型目录,避免容器重建时重复下载
坑 3:lang="ch" 默认用的是 PP-OCRv5,不是 PP-OCRv4
现象:以为默认是 PP-OCRv4,结果发现行为跟文档描述的 v4 不一致。
原因 :PaddleOCR 3.5.0 中,lang="ch" 时 ppocr_version 默认为 "PP-OCRv5"(源码 _pipelines/ocr.py 第 446 行)。只有显式指定 ocr_version="PP-OCRv4" 才会用 v4。
验证方式:
python
# 显式用 PP-OCRv4
ocr = PaddleOCR(lang="ch", ocr_version="PP-OCRv4")
坑 4:GPU 推理报错 CUDA error
现象 :PaddleOCR(device="gpu:0") 报 CUDA 相关错误。
原因:装的是 CPU 版的 PaddlePaddle,不支持 GPU 推理。
解决方案:
bash
pip install paddlepaddle-gpu==3.1.0
安装前确认你的 CUDA 版本和 PaddlePaddle 支持的版本匹配。
七、实战案例:手机号 OCR 提取
这是一个真实项目的完整实现。需求:从手机截图中自动提取 11 位脱敏手机号(如 138****8888)。
7.1 为什么需要"双轨 OCR"?
实际场景中的截图五花八门:竖屏、横屏、倾斜、反光。单个 OCR 配置很难通吃。所以维护两个实例:
| 实例 | 配置 | 适用场景 |
|---|---|---|
_OCR_NO_DOC |
禁用文档预处理,检测参数调优 | 绝大多数竖屏截图 |
_OCR_WITH_DOC |
启用方向分类 + 角度校正 | 横屏、倾斜截图 |
7.2 两个 OCR 实例的配置
python
from paddleocr import PaddleOCR
# 实例 1:禁用文档预处理,针对竖屏截图调优
ocr_no_doc = PaddleOCR(
use_textline_orientation=False,
use_doc_orientation_classify=False,
use_doc_unwarping=False,
lang="ch",
text_det_limit_side_len=960, # 长边限制 960px
text_det_limit_type="max", # 按最大边限制
text_det_thresh=0.3, # 低阈值,检测更多文字区域
text_det_box_thresh=0.5, # 降低框阈值,保留更多框
text_rec_score_thresh=0.0, # 不过滤任何识别结果
)
# 实例 2:启用文档预处理,适配横屏/倾斜场景
ocr_with_doc = PaddleOCR(
use_doc_orientation_classify=True,
use_angle_cls=True, # 2.x 遗留参数,映射为 use_textline_orientation
lang="ch",
)
7.3 四层递进识别策略
每一层只要识别到手机号就立即返回,不继续往下走:
python
import cv2
def extract_phone(img_path: str) -> str | None:
# 策略 1:禁用预处理 + 原图(竖屏截图首选)
texts = predict(ocr_no_doc, img_path)
phone = match_phone(texts)
if phone:
return phone
# 策略 2:启用预处理 + 原图(横屏/倾斜兜底)
texts = predict(ocr_with_doc, img_path)
phone = match_phone(texts)
if phone:
return phone
# 策略 3:禁用预处理 + 裁剪顶部区域(聚焦手机号)
phone = try_crop(ocr_no_doc, img_path)
if phone:
return phone
# 策略 4:启用预处理 + 裁剪顶部区域(最后兜底)
phone = try_crop(ocr_with_doc, img_path)
return phone
裁剪逻辑也很有意思------竖图裁顶部 40%,横图因为不知道用户往哪边转的手机,左右各试一次:
python
def try_crop(ocr, img_path: str) -> str | None:
img = cv2.imread(img_path)
if img is None:
return None
h, w = img.shape[:2]
if h >= w:
# 竖图:切顶部 40%,保留全宽
crop = img[0:int(h * 0.4), 0:w]
return match_phone(predict(ocr, crop))
else:
# 横图:左右各试一次
crop_left = img[0:h, 0:int(w * 0.4)]
phone = match_phone(predict(ocr, crop_left))
if phone:
return phone
crop_right = img[0:h, int(w * 0.6):w]
return match_phone(predict(ocr, crop_right))
7.4 使用模型清单
这个项目一共用了 4 个模型:
| 模型名 | 作用 | 哪个实例用 |
|---|---|---|
PP-OCRv5_server_det |
文本检测 | 两个都用 |
PP-OCRv5_server_rec |
文本识别 | 两个都用 |
PP-LCNet_x1_0_doc_ori |
文档方向分类 | 仅 ocr_with_doc |
PP-LCNet_x0_25_textline_ori |
文本行方向分类 | 仅 ocr_with_doc |
7.5 Docker 部署要点
模型文件很大,容器重建时重复下载很浪费。用命名卷持久化:
yaml
# docker-compose.yml
services:
phone-ocr:
image: phone-ocr
volumes:
- paddleocr-models:/app/.paddleocr
volumes:
paddleocr-models:
环境变量指定模型缓存目录:
dockerfile
ENV PADDLEOCR_HOME=/app/.paddleocr
八、总结:你真正需要记住的 8 件事
lang="ch"默认用 PP-OCRv5 ,不是 PP-OCRv4。想用旧版要显式指定ocr_version="PP-OCRv4"use_angle_cls是 2.x 遗留参数 ,3.x 里映射为use_textline_orientation,对应模型PP-LCNet_x0_25_textline_ori- server 模型精度高但体积大 ,mobile 模型适合端侧部署。
lang="ch"默认用 server 版 - 三个辅助模型默认不启用 :
use_doc_orientation_classify、use_doc_unwarping、use_textline_orientation都需要手动开启 - 检测参数
text_det_thresh和text_det_box_thresh是调优关键:模糊/低对比度场景调低,噪声多的场景调高 - 首次运行会自动下载模型,总约 170MB。Docker 部署用命名卷持久化
- GPU 推理需要
paddlepaddle-gpu,光装paddlepaddle不行 text_rec_score_thresh=0.0不过滤任何结果,适合"宁可多识别也不漏"的场景
验证清单
- ⭐
pip install paddlepaddle==3.1.0 paddleocr==3.5.0安装成功 - ⭐
paddleocr ocr -i test.png --save_path ./output命令行运行正常 - ⭐ Python 三行代码能识别出图片中的文字
- ⭐ 明确自己用的是 PP-OCRv5 还是 PP-OCRv4(用
ocr_version参数确认) - ⭐
use_angle_cls替换为use_textline_orientation(3.x 推荐写法) - ⭐ 模型文件缓存在本地(第二次运行不再下载)