OCR 这类工具最容易被误用:看起来只要把图片丢进去就能得到文字,但真正放到项目里时,还会遇到图片质量、方向、字体、语言、速度、批量处理和错误纠正等问题。本文以一个最小的 RapidOCR 英文识别项目为例,整理它适合做什么、怎么跑起来、怎么做常规测评,以及使用时需要注意哪些细节。

本文不是完整排行榜式横向评测,而是偏工程落地的使用说明:先让脚本能稳定运行,再用一组可复现的指标判断它是否满足当前业务。

RapidOCR 是什么#

RapidOCR 可以理解为一个轻量级 OCR 推理方案。当前示例项目使用的是 rapidocr-onnxruntime==1.2.3,底层通过 ONNX Runtime 执行 OCR 模型推理,典型链路包括:

  1. 文本检测:先在图片中找出可能包含文字的区域。
  2. 方向分类:判断文本是否需要旋转或方向修正。
  3. 文本识别:对检测出来的文字区域逐行识别。
  4. 结果整理:输出文本框、文字内容和置信度等结果。

在这个项目里,我们只保留最常用的输出:把图片中的文字逐行打印出来。它适合做轻量脚本、批处理、小工具、后台任务,也适合在正式接入大系统前做 OCR 方案验证。

适用场景#

RapidOCR 更适合这些场景:

  • 识别清晰图片里的英文、数字、短标签、票据字段、车牌周边信息等。
  • 在本地或服务器上离线运行,不想依赖外部 OCR API。
  • 希望用 Python 快速接入,先验证效果,再决定是否封装成服务。
  • 对部署体积、调用方式、推理依赖有一定要求,希望用 ONNX Runtime 这类通用推理后端。

它不太适合直接裸用在这些场景:

  • 图片严重模糊、过曝、反光、压缩严重。
  • 版面复杂,需要结构化还原表格、段落、字段层级。
  • 需要极高准确率的财务、证件、合同等强校验场景。
  • 需要直接理解语义,而不只是把图片转成文字。

这些场景不是不能做,而是要加预处理、后处理、规则校验,甚至引入专门模型或人工复核流程。

最小项目结构#

当前项目可以保持很简单:

rapidOCR/
├── README.md
├── ocr.py
├── IMG_20260506_110642.jpg
├── IMG_20260506_110656.jpg
└── venv/

核心脚本 ocr.py 的职责很清楚:接收一张图片路径,调用 RapidOCR,然后把识别出的每行文字打印出来。

import argparse
from rapidocr_onnxruntime import RapidOCR


def main():
    parser = argparse.ArgumentParser(description="OCR text recognition using RapidOCR")
    parser.add_argument("--input", required=True, help="Path to input image file")
    args = parser.parse_args()

    engine = RapidOCR()
    result, _ = engine(args.input)

    if not result:
        print("No text detected.")
        return

    for line in result:
        print(line[1])


if __name__ == "__main__":
    main()

这里的 result 通常包含文本框坐标、识别文本、置信度等信息。示例脚本只打印 line[1],也就是文字内容。如果后续要做测评或业务校验,建议保留完整结果,不要过早只取纯文本。

安装与运行流程#

建议先创建独立虚拟环境,避免把 OCR 依赖污染到系统 Python。

python3 -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
python -m pip install rapidocr-onnxruntime

如果需要固定版本,可以写成:

python -m pip install rapidocr-onnxruntime==1.2.3

运行单张图片:

python3 ocr.py --input ./test.jpg

当前脚本的输出是逐行文本,例如:

E18254
Lynch
Silver/GreenC4

如果没有检测到文字,会输出:

No text detected.

常规测评应该看什么#

OCR 测评不要只看“有没有识别出来”,至少要拆成准确率、速度、稳定性和可维护性四类。

1. 准确率#

最直接的方式是准备一批标注好的图片,每张图片对应人工确认的正确文本,然后比较 OCR 输出。

常用指标可以分三层:

  • 字符级准确率:适合车牌号、编号、英文短文本。
  • 行级准确率:适合标签、截图、简单票据。
  • 字段级准确率:适合业务系统,比如姓名、金额、日期、编号。

如果只是英文和数字短文本,建议重点看这些错误:

  • 0O 混淆。
  • 1Il 混淆。
  • 空格丢失或多出空格。
  • 符号识别错误,比如 /-.
  • 多行文本顺序不符合业务预期。

2. 速度#

速度要分冷启动和热运行。

冷启动包含模型加载时间,第一次调用通常更慢;热运行更接近批量任务中的单张处理耗时。本文示例在本机用两张约 300 多万像素的图片单次运行,命令总耗时大约在 9 秒级。这个数字只能作为当前机器、当前图片、当前脚本的观察值,不能直接代表 RapidOCR 的通用性能。

做正式测评时,建议记录:

图片数量:100 张
图片分辨率:例如 1280x720、1920x1080、手机原图
运行环境:CPU 型号、内存、Python 版本、onnxruntime 版本
统计方式:去掉第一次冷启动,取平均值、P50、P95
输出内容:总耗时、单张平均耗时、失败图片数量

3. 稳定性#

稳定性主要看它在“脏数据”上是否会崩,或者输出明显异常。

建议准备这些测试图片:

  • 正常清晰图片。
  • 倾斜图片。
  • 低光、过曝、反光图片。
  • 远距离拍摄的小字。
  • 背景复杂的图片。
  • 没有文字的图片。
  • 文件损坏或路径不存在的输入。

当前脚本已经处理了“没有识别结果”的情况,但还没有专门处理“文件不存在”“图片无法读取”“批量任务中某张失败”等异常。正式使用时应该补上。

4. 后处理成本#

OCR 的原始输出往往不是业务最终结果。比如识别出来 Silver/GreenC4,人能看懂,但系统可能需要拆成颜色、型号、字段编号。这个时候后处理成本就很重要。

可以按业务规则加几层处理:

  • 去掉首尾空格。
  • 合并被拆开的行。
  • 对编号做正则校验。
  • 对颜色、日期、金额等字段做字典匹配。
  • 对低置信度结果进入人工复核。

一个简单的测评脚本思路#

如果后续要做批量测评,可以把完整结果保存成 JSONL,方便复查。

import json
import time
from pathlib import Path
from rapidocr_onnxruntime import RapidOCR

engine = RapidOCR()

for image_path in Path("samples").glob("*.jpg"):
    started = time.perf_counter()
    result, _ = engine(str(image_path))
    elapsed = time.perf_counter() - started

    texts = []
    if result:
        texts = [line[1] for line in result]

    print(json.dumps({
        "image": str(image_path),
        "elapsed_seconds": round(elapsed, 3),
        "texts": texts,
    }, ensure_ascii=False))

运行方式:

python bench_ocr.py > rapidocr-result.jsonl

这样做的好处是:后续可以人工抽查、写脚本统计,也可以把结果喂给规则校验程序。

使用注意事项#

图片预处理很关键#

OCR 效果很大程度取决于输入质量。拍照类图片尤其要注意:

  • 尽量保证文字区域清晰、无遮挡。
  • 避免强反光和过曝。
  • 尽量让文字区域占据足够像素,不要把小字拍得太远。
  • 对明显倾斜的图片先做旋转或透视矫正。
  • 对超大图片可以先压缩到合理尺寸,但不要把文字压糊。

不要只保存纯文本#

示例脚本为了简单,只打印文字内容。实际项目里建议保存完整 OCR 结果,至少包括:

  • 文本内容。
  • 文本框坐标。
  • 置信度。
  • 原图路径。
  • 处理耗时。
  • 模型和依赖版本。

这些信息对排查误识别非常有用。

注意 Python 和依赖版本#

OCR 依赖通常包含 numpyopencv-pythononnxruntime 等包,不同 Python 版本、CPU 架构、系统平台可能影响安装体验。建议在项目里固化依赖:

python -m pip freeze > requirements.txt

部署时使用:

python -m pip install -r requirements.txt

如果是生产环境,最好再记录操作系统、CPU 架构和 Python 小版本,避免“开发机能跑,服务器不能跑”。

批量处理要复用引擎#

不要每处理一张图片都重新 RapidOCR()。模型初始化有成本,批量任务应该先初始化一次,然后循环处理图片。

推荐:

engine = RapidOCR()
for image in images:
    result, _ = engine(image)

不推荐:

for image in images:
    engine = RapidOCR()
    result, _ = engine(image)

低置信度不要直接入库#

如果业务允许,可以设置置信度阈值。低于阈值的结果不要直接作为最终结果,可以进入人工确认、重新拍照、或者二次校验流程。

尤其是编号、金额、证件号这类字段,错一个字符就可能造成业务错误,不能只凭 OCR 输出直接通过。

英文短文本要做规则校验#

英文、数字、符号混合的短文本最常见的问题不是完全识别失败,而是“看起来差不多”。比如多一个空格、漏一个 /、把 O 识别成 0。如果业务字段有固定格式,应该用正则或白名单校验。

示例:

import re

plate_like = re.compile(r"^[A-Z0-9-]{4,12}$")

if not plate_like.match(text.replace(" ", "")):
    mark_as_review(text)

总结#

RapidOCR 的价值在于接入简单、可以本地运行、适合快速构建 OCR 原型和轻量批处理。当前这个最小项目已经能完成英文图片识别的主流程:创建虚拟环境、安装 rapidocr-onnxruntime、运行 ocr.py --input,然后输出识别文本。

真正落地时,重点不只是“能不能识别”,而是要把图片质量、批量速度、错误样本、置信度、字段规则和人工复核流程一起考虑。对英文短文本来说,建议先用 50 到 100 张真实样本做小规模测评,确认准确率和后处理成本,再决定是否封装成 API 或接入业务系统。