简介:古籍数字化长期受制于异体字规模庞大、版面结构复杂、原件质量参差三大难题。本文从字符集覆盖、版面解析、图像适应性与校对闭环四个维度拆解古籍OCR核心技术难点,给出一套可量化的评估框架与六阶段工程化流水线,帮助文献数字化团队科学选型、显著提升识别效率与文本质量。
通用文字识别技术在现代印刷体场景上已经相当成熟,但一进入古籍领域,识别效果往往断崖式下滑。根本原因在于,古籍与现代文档在字符、版面、图像质量三个层面都存在系统性差异,任何一环处理不到位,都会让最终文本无法直接用于研究与引用。
现代简体中文常用字约六千多个,GB2312收录的汉字为6763个,覆盖日常阅读绰绰有余。而古籍涉及的字符规模完全是另一个量级:历代字书累计收录的汉字字形(含异体字、俗字、讹字)总量超过十万,现行GB18030-2022标准收录的汉字也已达八万余个。这意味着古籍OCR的字符分布天然是“长尾”形态——大量低频生僻字在通用模型的训练语料中出现次数极少甚至从未出现,识别率必然大打折扣。
更棘手的是字形的历史变体:同一个字在不同刻工、不同抄手笔下形态各异;避讳字因缺笔而与标准字形不符;地方志、家谱中还存在大量区域性俗字。这些非标准字形对以规范字体为主要训练数据的通用模型构成直接挑战。
古籍版面的复杂度远超现代文档,常见结构包括:
通用版面分析算法大多按横排、左起的现代阅读逻辑组织输出,应用到古籍上极易出现两类错误:一是行序错乱,右列被排到左列之前;二是注释与正文混流,校对时需要反复对照原图重新梳理层次,工作量甚至超过重新录入。
古籍原件历经数百年,纸张老化泛黄、墨迹漫漶、虫蛀破损是常态。扫描环节还可能引入透光透字(背页文字透印形成干扰)、页面歪斜、装订处阴影等问题。若识别引擎不具备针对性预处理能力,这些噪声会被当作笔画特征,直接污染识别结果。
第一看字库覆盖范围:能否完整支持GB18030-2022字符集,能否正确处理Unicode中日韩汉字扩展区(CJK Extension B/C/D等)的编码输出。部分引擎对扩展区字符采用私用区(PUA)临时编码,此时必须提供PUA与标准Unicode的映射表,否则文本在交换、检索环节会出现乱码。
第二看生僻字兜底机制。再强的模型也无法覆盖全部历史字形,务实的做法是:模型识别大部分字符,对置信度极低或字库之外的字符,提供按部首、笔画数检索的补录工具,让录入员快速定位补录,而不是对着纸质字表逐字翻查。
这是古籍OCR区别于通用OCR的关键能力,评估时应重点验证:
一个可操作的检验方法:选取同时包含眉批与夹注的批校本样页,识别后直接检查注释是否污染正文、顺序是否正确,这是最容易暴露短板的用例。
向候选方案提供同一批“困难样本”:轻微歪斜页、透字页、装订阴影页,对比各家的识别稳定性。稳定的引擎应在内部完成倾斜矫正、背景分离与透字抑制,而不是要求用户修图后再提交。
识别只是流程的一半,校对决定最终交付质量。成熟方案应提供:置信度标注(低置信度字符高亮提示,校对员按优先级复核而非逐字通读)、图文对照界面(原图与文本并排联动,可回溯定位)、校对数据回流(人工修正结果沉淀为标注样本,反哺模型迭代,形成越用越准的数据闭环)。
对古籍数字化项目而言,单点工具只是一个环节,真正决定效率的是完整流水线的设计,建议按六个阶段组织:
阶段一:采集规范。扫描分辨率不低于300dpi,善本建议600dpi;采用彩色或灰度模式以保留批注墨色层次;建立“编号-卷次-页序”统一命名与元数据规范,避免后期整理混乱。
阶段二:预处理。完成去噪、自适应二值化、倾斜检测与矫正、装订阴影去除。
阶段三:识别。执行“版面分割→列切分→序列识别→后处理”的完整链路。
阶段四:结构化输出。识别结果连同坐标信息一并落盘,便于图文对照与溯源,参考结构如下:
{"book_id": "DFZ-1892-juan-3","page": 12,"reading_order": "rtl-ttb","blocks": [{"type": "body","direction": "vertical","bbox": [820, 40, 1140, 2100],"text": "……(正文)……","avg_conf": 0.97},{"type": "interlinear_note","anchor": "body.line[3]","text": "……(行间批)……"}]}
阶段五:人工校对。按置信度从低到高分派任务;生僻字通过部件检索工具补录;批注与正文分层核对。
阶段六:数据回流。将校对确认的文本与坐标构建为训练样本,持续优化模型。
整条流水线可用伪代码概括:
pages = scan(book, dpi=600, mode="color")for page in pages:img = preprocess(page) # 去噪 / 二值化 / 矫斜layout = segment(img) # 版面分割:正文/注释/插图for block in sort_rtl(layout.blocks): # 按古籍阅读顺序遍历lines = column_cut(block) # 竖排列切分text = recognize(lines) # 识别并输出置信度persist(page, layout, text) # 结构化落盘proofread(results, strategy="low-conf-first")feedback_loop(proofread_log) # 校对样本回流
选型与验收都应建立在可量化指标上。古籍OCR最核心的指标是字符错误率(CER),即识别文本相对人工标注文本的编辑距离占比,识别准确率 = 1 - CER,实现并不复杂:
def edit_distance(a, b):dp = list(range(len(b) + 1))for i, ca in enumerate(a, 1):diag, dp[0] = dp[0], ifor j, cb in enumerate(b, 1):up = dp[j]dp[j] = min(dp[j] + 1, # 删除dp[j - 1] + 1, # 插入diag + (ca != cb)) # 替换/保留diag = upreturn dp[-1]def cer(reference: str, hypothesis: str) -> float:if not reference:raise ValueError("参考文本不能为空")return edit_distance(reference, hypothesis) / len(reference)
评测时注意两点:一是按版式类型分组统计(刻本、抄本、批校本分开评测),整体均值会掩盖短板场景;二是测试集必须来自本机构真实馆藏,公开数据集代表性有限。建好标注测试集后,让候选方案跑同一份样本横向比较,结果远比任何宣传口径可信。
古籍数字化的本质,是把数百年积累的非结构化文本转化为可检索、可计算、可引用的数据资产。字符集覆盖决定“能不能识”,版面解析决定“读得对不对”,校对闭环决定“最终可不可用”。与其依赖单一工具的宣传数字,不如自建测试集、量化评测、组合能力,这套方法论适用于任何文献数字化团队,也是让技术真正服务于学术研究的关键所在。