简介:古籍数字化正从人工转录走向智能识别。本文拆解古籍 OCR 的三大技术难关——海量字符集、复杂版面与手写稿本,给出科学的评估指标与 CER 计算示例,并梳理一套可落地的数字化工作流,帮助古籍整理与数字人文从业者高效构建可靠的古籍文本数据资产。
古籍是文明传承的重要载体,但纸本文本难以检索、难以传播、难以长期保存。过去做古籍整理,主要依靠研究者逐字誊录,一部地方志动辄数十万字,人工转录往往耗时数月,且极易引入错漏。近十年来,文字识别(OCR)技术逐渐成为古籍数字化的核心引擎,但很多人低估了它的难度:古籍 OCR 并不是“现代文本 OCR 的直接套用”,而是在字符集、版面、书写形态三个维度上都远超现代场景的综合难题。
一个直观的数字对比可以说明问题:现代汉语常用简体字不过六千多个,国标 GB2312 收录的汉字仅有 6763 个;而历代积累下来的汉字——包括正字、异体字、俗字、避讳字、讹字——在 Unicode 编码体系中的总量已接近十万。这意味着古籍 OCR 的“字符空间”比现代场景大了一个数量级,且大量生僻字在训练语料中出现频率极低,呈典型的长尾分布。理解了这一点,才能理解后面所有技术决策的出发点。
评估任何古籍识别方案,第一个要问的问题是“它认识多少字”。从技术上看,方案需要覆盖 GB18030 及 Unicode 中日韩统一表意文字的基本区与各扩展区,才能应对刻本中的正字与常见异体字;对抄本、稿本中的俗字、省笔字,则要依赖模型对字形结构的泛化能力,而非简单的字表匹配。
识别准确率并不是一个均一数字。在高频字上,成熟方案的准确率可以做到很高;但准确率会随字频下降而快速衰减,生僻字恰恰是古籍研究中最具价值的部分。因此,做技术评估时不能只看“总体准确率”,而要看分层指标:常用字、次常用字、生僻字各自的表现,必要时按字频区间分别统计。
识别只是第一步。古籍文本往往“一字多形”,同一个字存在多个异体写法,数字化时需要建立异体字映射表做归一化,输出统一的“定本”文字。对于模型确实无法识别的极生僻字,工程上通常保留原字形图像,配合超大字符集的检索查询工具,由人工查证后补录。这是一个“机器识别 + 人工兜底”的合理闭环,务实的目标是让机器承担八成以上的常规工作,而不是苛求机器百分之百全能。
顺带提醒一个常见坑:繁简并非一一映射。一个简体字可能对应多个繁体字,语义不同则字形不同,自动转换必须结合上下文判断,否则会在后处理阶段引入本不存在的新错误。
古籍版式的复杂度远超现代图书,主要体现在四类结构上:一是筒子页,一张纸对折后正反两面共同构成一个“叶”,版心在外,文字竖排;二是多栏布局,三栏稿本等版式中正文与注释共存于同一页面;三是批注体系,天头(书眉)、地脚处的批语、行间夹批以及正文中的双行小注,构成了多层级的文本;四是从右到左、从上到下的阅读顺序,与现代排版习惯完全相反。
传统 OCR 管线通常假设“横排、从左到右、单栏”,直接套用到古籍上会出现两类高频故障:其一,文字顺序错乱,输出结果与原文阅读顺序不一致,后续根本无法使用;其二,注释与正文混流,双行小注被拼接进正文,校对时需要反复对照原书重新梳理,工作量不降反升。
现代方案的通行做法是基于深度学习的版面分析:先将页面切分为正文、注释、批语、插图、版心等语义区域,再识别各区域的类型与坐标,最后按古籍阅读习惯重排输出。工程上可抽象为“区域检测 → 类型分类 → 顺序重排 → 结构化输出”四步。输出文本应保留层级关系(例如以标签区分“正文 / 夹注 / 眉批”),供后续校勘、注释研究与引用使用。
刻本字形相对规整,尚属可控;稿本、抄本则把手写变体、俗字、涂改、行间补字全部叠加在一起,构成古籍识别难度的天花板。手写识别需要更细粒度的文本行切割(行倾斜、行距不均都是常态),并且要先区分“正文手迹”与“批注手迹”——不同人的笔迹混在同一页上,必须先完成区域归属判断再进行识别。务实的做法是:识别结果附带置信度,低置信度区域直接推送给人工校对,把有限的人力用在最需要的地方。
不要被单一的“准确率 XX%”说服,评估必须自己动手,建议分三步。
按刻本 / 抄本 / 稿本、朝代、版式、字号等维度分层抽样,每层人工标注若干页“金标准”转录文本,反复校对至可信。评估集的质量决定了所有后续结论的有效性。
CER 是 OCR 领域的标准指标,基于编辑距离实现,示例代码如下:
def edit_distance(ref: str, hyp: str) -> int:"""计算两段文本的编辑距离(删除/插入/替换各计 1 次操作)"""m, n = len(ref), len(hyp)prev = list(range(n + 1))for i in range(1, m + 1):curr = [i] + [0] * nfor j in range(1, n + 1):cost = 0 if ref[i - 1] == hyp[j - 1] else 1curr[j] = min(prev[j] + 1, # 删除curr[j - 1] + 1, # 插入prev[j - 1] + cost) # 替换prev = currreturn prev[n]def cer(ref: str, hyp: str) -> float:"""字符错误率 CER = 编辑距离 / 参考文本长度,准确率 = 1 - CER"""if len(ref) == 0:raise ValueError("参考文本不能为空")return edit_distance(ref, hyp) / len(ref)# 示例:假设识别结果错了一个字ref = "学而时习之不亦说乎"hyp = "学而时刁之不亦说乎"print(f"CER = {cer(ref, hyp):.2%}") # 输出:CER = 11.11%
除 CER 外,还应统计文本块检出率、阅读顺序正确率、注释归属正确率。一个字符准确率高但顺序错乱的系统,对古籍整理几乎不可用。
完整流程可概括为一条主线:图像采集与预处理 → 版面分析 → 行切割与识别 → 后处理 → 人工校对 → 结构化归档。用伪代码表达如下:
def guji_ocr_pipeline(page_image):img = preprocess(page_image) # 纠偏、去污、对比度增强regions = layout_analyze(img) # 版面分割:正文/注释/批语/插图output = []for region in reading_order(regions): # 按古籍阅读顺序:右→左、上→下for line in line_segmentation(region.image):text, conf = recognize(line)text = postprocess(text) # 异体字归一、字典校验output.append((region.type, text, conf))return output
各阶段的工程要点:
对古籍整理团队而言,选型前应先建立基线:可用成熟云厂商的通用 OCR 能力(例如百度智能云的文字识别类服务)在自有样张上跑一遍,得到通用引擎在古籍数据上的表现下限,再评估专门方案带来的增益是否值得投入。学术场景还有几条硬性考量:支持批量、可复现的调用方式;识别结果可导出为结构化格式(如学界通用的 TEI XML);支持多人协作校对与版本追溯。这些决定了工具能否真正融入研究工作流,而不是沦为一次性 demo。
更值得关注的方向是识别与理解的融合:多模态大模型可以直接完成从图像到文本的端到端转换,并结合上下文完成句读、纠错,甚至给出校勘建议。这将把研究者从逐字转录的机械劳动中解放出来,把精力留给版本比对、文本考订等真正体现学术价值的工作。近年已有机构将 AI 系统性地引入古籍整理实践,“机器初校 + 学者终审”的分工模式被证明能显著提升整理效率。
古籍文字识别的难度,本质上是字符空间、版面语法与书写形态三重复杂度的叠加。理解这三个维度,就能建立理性的评估框架:先问字符覆盖度,再看版面还原能力,最后在自己的数据上计算 CER 与顺序指标。无论选用商用方案还是自建管线,“机器识别 + 人工兜底 + 数据回流”的闭环,都是当下最务实的技术路线。