为什么 OCR 修不好生僻字


最近在做一批广东村志类出版物的目录整理:把每本书目录页上的“镇 → 行政村 → 自然村 → 页码”结构化,方便后面把正文和层级对上。目录页是两栏排版的宋体列表,看起来是 OCR 最擅长的那类版面。实际跑下来,结构和页码都没问题,问题几乎全出在字上。

第一轮人工核对了三卷、986 行,找出 30 处真错,几乎全是同一类:粤语地名里的生僻字。更麻烦的是,其中很多错误的置信度是 1.0,靠置信度阈值抓不住。

三个根因 §

字典上限。 我用的 OCR 引擎(PP-OCRv5)是一个固定字表的分类器,字表 18,383 个字。㘵、乪、揾、𣿀 都不在里面。不在字表里的字,它输出的概率是精确的零,放大图像、调参数都没用,永远不可能认对。

低频字被先验吃掉。 冚、迳、塅、坣、窿 这些字在字表里,但训练数据里出现得极少。结果是 冚 被整个丢掉(“水冚村”读成“水村”),迳 变成 泾,坣 变成 堂,窿 变成 隆。模型对这些错误非常自信,因为从它的角度看,常见字才是“合理”的答案。

大模型换了一种错法。 视觉语言模型的词表来自 LLM 分词器,理论上覆盖全部 Unicode,字典上限没了。但它带着很强的语言先验。我用字体干净地渲染了一张“水冚村”,让一个 7B 的视觉模型转写,它写成“水田村”。算候选串的对数概率,“水田村”是 −0.64,“水冚村”是 −8.58。图再清楚,它也更愿意相信一个常见的词。

四条走不通的路 §

  1. 裁出单行、放大两倍、用同一个模型再认一次。 28 处错误里认对 6 处,输出变了 5 处,剩下 17 处原样不动。错误的来源是字表和先验,不是分辨率,同一个模型复查自己查不出来。

  2. 用视觉语言模型做第二意见。 它确实认出了几个原模型物理上认不出的字(乪、揾)。但在只有一行的小图上大量幻觉,30 个本来正确的行里有 13 个被它读成了点、下划线或日文。能用,但必须做输出清洗,而且修不了“两个模型错在同一个字上”的情况。

  3. 候选打分。 自己部署模型后,可以不让它自由生成,只比较几个候选串的概率。上面那个 −0.64 对 −8.58 说明,只要先验够强,打分一样选错。

  4. 零样本单字识别。 学术界有一类方法把汉字拆成笔画或部件序列来识别,没见过的字也能认。我用一个开源实现从头训练,刻意把目标生僻字排除在训练集之外:在真实字块上,目标字开放候选集 76%、限定候选集 86%,㘵 7/7、冚 10/10、迳 5/5 全对;但普通字只有 97.3%。作为“发现字表里没有的新字”的筛查工具有价值,做主力不行。

最后用的办法 §

回到最朴素的思路:目录是等宽的宋体印刷,一个汉字就是一个方格。那就把每个字切出来,单独分类。

  • 切字。 字距约等于行高。沿行做纵向墨迹投影,把切点吸附到字距网格上,防止把“朋”“州”这类左右结构的字切成两半。在人工核对过的 986 行上,切出的字数和正确名字的长度 100% 一致。
  • 训练数据全部合成。 类别是常用字加上书里、地名里出现过的所有字,第一版 6,788 类;用 27 个宋体、黑体字面渲染,再加扫描退化:模糊、二值化抖动、JPEG 压缩、轻微旋转、笔画粗细变化。训练时一张真实字块都没用。
  • 模型很小。 ResNet-18,输入 64×64,在一张 A4000 上训练约 40 分钟,显存 2.2 GB。

在 3,294 个人工核对过的真实字块上,逐字准确率 99.76%;迳/泾、窿/隆、坣/堂 这些易混对双向混淆为 0,字表外的 11 个字全对。

它的用法不是替代 OCR,而是做第二个读者:分类器读出的串和 OCR 读出的串不一致,这一行就交给人。 在那三卷上,这条规则抓到了人工发现的全部 30 处错误,940 个正确行里只误报 6 行;另外还找出 16 处人工核对时漏掉的错。

后来又遇到两个问题,都值得记下来:

  • 有两页是手机手持拍的,带运动拖影,分类器在这两页上掉到 44%。原因很直接,训练时的退化里没有运动模糊。加上运动模糊、散焦和重影增广重训后,拖影页回到 96.3%,清晰页没有变差。
  • 字表扩到全省地名用字时,第一版直接把 7,741 个码位都当成类别,结果准确率反而下降。原因是地名数据里混着繁体和异体码位,“高”和“髙”成了两个互相抢票的类别,同一个印刷字形被拆成两份。把 189 个异体码位并回标准字之后,定为 7,552 类,问题消失。

几点体会 §

  • 抓“高置信度但错误”的错,关键不是更强的模型,而是失效方式不同的第二个读者。单字分类器没有语言先验,冚 和 田 在它眼里是平等的两个类别,这正好补上 OCR 和大模型共同的盲区。
  • 合成数据比想象中好用,前提是退化要贴近真实材料。看一眼真实字块和合成字块并排的拼图,比调半天超参数有用。
  • 人工核对本身也有噪声。那三卷的 46 处真错里,第一轮人工漏了 16 处。拿人工结果当真值评估之前,最好先想清楚它的召回率。


最后修改:2026-10-24
粤ICP备2026145812号-1
粤公网安备44011302005976号