OCR 文字识别管线设计
图片和 PDF 的 OCR 文字识别:技术选型(pytesseract/PaddleOCR/VLM)、图像预处理、结构化提取、准确率与局限。
#type / concept
#status / growing
#tech / ai
#resource / python
[!info] related notes
- 相关: 光学字符识别 OCR, deepseek-ocr
OCR 文字识别管线设计
技术选型
| 方案 | 优点 | 缺点 | 适用 |
|---|---|---|---|
| pytesseract | 轻量、离线 | 中文准确率一般 | MVP、印刷体 |
| PaddleOCR | 中文识别好 | 依赖大 | 中文场景 |
| DeepSeek-OCR / VLM | 理解结构 | 需要 API、成本高 | 复杂文档 |
| 云服务(阿里/腾讯) | 准确率最高 | 有成本 | 生产环境 |
处理流程
文件上传 → 判断类型(图片/PDF)
→ 图片:预处理 → OCR
→ PDF:提取文本(有则直接用)→ 渲染为图片 → OCR
→ 纯文本 → 结构化提取(正则或 LLM)
图像预处理
def preprocess(img):
img = img.convert("L") # 灰度
img = img.point(lambda x: 0 if x < 128 else 255) # 二值化
img = img.filter(ImageFilter.MedianFilter(3)) # 去噪
if img.width < 1000:
ratio = 1000 / img.width
img = img.resize((int(img.width*ratio), int(img.height*ratio))) # 放大
return img
PDF 两种类型
- 文本 PDF:
page.get_text()直接提取(快、准) - 扫描件 PDF:渲染为图片再 OCR(慢、需要高 DPI)
结构化提取
OCR 输出纯文本,需要进一步提取结构化信息。简单场景用正则:
bmi = re.search(r'BMI[::\s]*(\d+\.?\d*)', text)
复杂场景交给 LLM:把 OCR 文本作为 prompt 的一部分,让 LLM 提取结构化数据。
准确率
| 场景 | pytesseract | PaddleOCR |
|---|---|---|
| 印刷体中文 | 高 | 高 |
| 手写 | 低 | 中 |
| 表格 | 中 | 中 |
| 模糊图片 | 低 | 中 |
设计要点
- OCR 是降级方案 — 能让用户直接输入就不要依赖 OCR
- 预处理比模型更重要 — 灰度、二值化、放大对准确率影响很大
- 纯文本 PDF 不需要 OCR — 先检查能不能直接提取文字
- 结构化提取用 LLM — 正则只适合简单模式,复杂的交给 LLM