古籍图片转文字:繁体OCR识别应用

发布于 2026-09-12

为啥普通繁体OCR直接拿来识别古籍根本不好使

我19年刚接触地方图书馆古籍数字化项目的时候,想当然觉得“繁体OCR嘛,找个识别繁体字的接口不就完了”,当时充了200块腾讯云通用OCR的余额,选了繁体中文模型,拿清刻本《温州府志》的扫描页测了10页,结果出来直接傻了:竖排的文字顺序全乱,异体字一半认错,板框的黑线条被识别成一串“一”字,连页面上的虫蛀黑点都被识别成顿号,算下来字准确率才刚过60%,根本没法用。

古籍文本和现代繁体的3个核心差异

后来翻了快半个月相关资料,又跟图书馆的文献学老师聊了才知道,古籍的文字和版式跟现代繁体印刷品根本不是一回事,差得远了:
1. 版式逻辑完全不同:绝大多数古籍是竖排右翻,阅读顺序是从右到左、从上到下,还经常夹着双行小注、眉批、圈点,现代OCR默认是横排从左到右的逻辑,行排序直接错;
2. 字形复杂度远超现代繁体:刻本里有大量异体字、避讳缺笔字、俗体字,比如“岩”在不同古籍里可能写成“巖”“喦”“嵒”,清刻本里“玄”“弘”这些字会故意缺笔避皇帝讳,通用繁体模型的训练集基本是现代繁体书籍、网页文字,根本没见过这些字形;
3. 图片干扰项多:古籍扫描件普遍有纸张泛黄、虫蛀、污渍、板框界栏、藏书印章,很多刻本的字体是软体写刻,不是规整的印刷宋体,对模型的抗干扰能力要求比普通印刷品高太多。

我当时在100页标注好的清刻本测试集上,测了不同方案的实际效果,数据摆在这里:

模型类型 单字准确率 竖排行顺序正确率 异体字识别率
通用云服务繁体OCR 61% 38% 22%
PaddleOCR通用繁体模型 57% 32% 18%
专项古籍OCR云接口 92% 97% 88%
开源本地微调古籍模型 89% 94% 81%

踩过最亏的坑:别觉得“繁体OCR都一样”,只要识别对象是古籍,直接pass掉所有不带“古籍专项”标签的OCR模型,省得像我一样充了钱买了额度才发现用不了。

零代码快速落地的可用方案选型(亲测有效)

如果不是专门做算法研发,其实完全没必要自己从零训模型,目前不管是商业API还是开源模型,都有现成能用的古籍识别方案,根据自己的场景选就行,我把这几年测过能用的整理了下:

云端API类:适合小批量、商用交付场景

这类方案不用部署,直接传图片就能返回结果,精度普遍不错,适合批量不大(几万页以内)、没有强数据隐私要求的项目:

产品名称 支持竖排 异体字识别率 单A3页成本 适合场景
百度智能云古籍OCR 90% 0.08元 普通刻本、版式规整的古籍
阿里读光古籍专项识别 94% 0.1元 带夹注、眉批的复杂版式古籍
籍合网在线古籍OCR 87% 免费(额度内) 个人用户少量识别需求

本地部署类:适合大批量、有隐私要求的场景

如果是图书馆、馆藏机构的项目,要求扫描件数据不能出内网,或者批量在十万页以上,用云API成本太高,推荐直接用PaddleOCR官方开源的古籍微调模型,我自己项目里跑了快两年,稳定性没问题,单张A3图在2080Ti上推理不到1秒,精度跟商业API差不了太多。

部署起来也简单,先装依赖,再从PaddleOCR的官方模型库下载古籍专用的检测、识别权重,几行代码就能跑:

from paddleocr import PPStructure, save_structure_res
import cv2

# 加载本地古籍模型,开启竖排适配、角度分类
ocr = PPStructure(
    show_log=False,
    lang='ch',
    # 替换成你自己下载的模型权重路径
    det_model_dir='./weights/ch_PP-OCRv4_det_general',
    rec_model_dir='./weights/ch_PP-OCRv4_rec_ancient',
    use_angle_cls=True,
    verticalize=True  # 这个参数一定要开!开了行排序正确率直接翻倍
)

# 单张图片识别
img = cv2.imread('scan_page_001.jpg')
result = ocr(img)
# 结果保存到output目录
save_structure_res(result, './output/', 'page_001')

真的要提醒:第一次跑的时候忘了开verticalize=True这个参数,100页识别结果的行顺序全乱,花了一晚上排查才发现是这个开关的问题,开了之后竖排行顺序的正确率直接从37%升到94%,别踩这个低级坑。

识别效果优化的几个实战技巧

哪怕用了最好的专项模型,直接拿原始扫描件去识别,准确率一般也就85%左右,稍微做几步优化,准确率能直接拉到90%以上,这些都是我在项目里攒的实招,没有虚的:

预处理:把图片调到模型最“舒服”的状态

模型训练的时候用的都是处理过的干净图片,你给它喂满是污渍、歪歪扭扭的原始扫描件,效果肯定差,三个操作性价比最高:
1. 分辨率统一调到300DPI:现在所有公开的古籍OCR模型,训练样本基本都是300DPI的扫描件,你拿72DPI的网图去识别,字都糊成一团,准确率至少掉20%;
2. 用自适应阈值做二值化:别用全局阈值二值化,古籍纸张泛黄、污渍不均匀,全局阈值会把浅的笔画直接滤掉,用OpenCV的自适应高斯阈值,blockSize设25、C取10,亲测对大部分清末民国刻本效果最好;
3. 提前去掉板框、界栏:古籍页面四周的黑边框、列之间的竖线,十有八九会被识别成“一”“丨”这类错字,用形态学操作把长横线、长竖线检测出来用白色填充掉,能减少至少10%的误识别。

对应的预处理代码我一直用这个,拿过去改改路径就能跑:

import cv2
import numpy as np

def preprocess_page(img_path, output_path):
    # 读入灰度图
    img = cv2.imread(img_path, 0)
    # 自适应二值化,适配不均匀的泛黄页面
    binary = cv2.adaptiveThreshold(
        img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY, blockSize=25, C=10
    )
    # 检测并去除长竖线(界栏)
    v_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 30))
    v_lines = cv2.morphologyEx(binary, cv2.MORPH_OPEN, v_kernel, iterations=2)
    # 检测并去除长横线(板框)
    h_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 1))
    h_lines = cv2.morphologyEx(binary, cv2.MORPH_OPEN, h_kernel, iterations=2)
    # 把线条区域填充成白色,不覆盖文字
    clean_page = cv2.bitwise_or(binary, v_lines)
    clean_page = cv2.bitwise_or(clean_page, h_lines)
    cv2.imwrite(output_path, clean_page)

识别中:加规则匹配修正专属错误

古籍里有很多固定的错误模式,不用改模型,加几行规则就能修正一大片:
- 针对特定朝代的避讳字做映射表:比如清康熙朝之后的刻本,“玄”缺笔经常被识别成“元”“亠”,乾隆朝之后“弘”缺笔容易被识别成“弓”,根据你识别的古籍成书年代,做个避讳字对应表,自动修正;
- 按字号区分正文和夹注:古籍里的双行小注字号比正文小一半,在检测阶段把文本框的高度做个聚类,大的归为正文,小的归为注释,识别完单独存放,不会混在一起;
- 异体字别随便替换:如果是做学术用途,识别出的异体字、俗体字要保留原字形,别自动转换成现代规范字,不然会丢失文献价值。

后处理:用本地大模型做首轮纠错

这是去年开始用的最省时间的技巧:初识别完的文本,不用直接扔给人工校,先过一遍本地部署的开源大模型(比如Qwen-14B、Llama3-8B中文微调版),用固定prompt让它在不改动原文的前提下,修正形近字错误、调整乱序的行,亲测能把剩下的错字再修正60%左右,能省一半的校对时间。

我自己用的prompt给大家参考,别让大模型自由发挥:

你是古籍数字化校对助手,处理中国古代刻本的OCR识别结果,严格遵守以下规则:
1. 绝对不增删原文内容、不改变语义、不把繁体转成简体,异体字、避讳字保留原字形
2. 修正“日/曰”“己/已/巳”“戊/戌/戍”这类形近字识别错误,结合上下文判断
3. 竖排文本按“从右到左、从上到下”的顺序调整错乱的行序
4. 删除被误识别为文字的板框线、污渍、多余圈点
直接输出修正后的文本,不要加任何解释、前缀、后缀。
待修正文本:
{ocr_raw_content}

血的教训:一开始写prompt没加“不增删原文、不转简体”的约束,模型直接把一篇光绪年间的县志改成了现代白话简体,还自己加了一堆段落总结,一下午的活白干。

批量项目落地的真实成本与效果参考

很多人一听说古籍数字化就觉得贵、费时间,我拿23年做的浙南某县民国版县志数字化项目算笔账,大家就知道投入产出比了:
这个项目总共有12600页扫描件,每页大概600字,总字数约750万。一开始图书馆找的传统人工录入团队报价是每千字35元,算下来要26万,周期4个月,准确率承诺98%。

我们最后用的方案是:
1. 预处理:用上面的脚本批量矫正歪斜、去板框、调分辨率,2天跑完,服务器成本90块;
2. 初识别:本地部署Paddle古籍模型,2080Ti显卡跑批,1个半小时跑完,显卡成本20块;
3. 模型纠错:本地部署Qwen-14B-Int4版本跑prompt纠错,3小时跑完,成本30块;
4. 人工终校:找了2个古典文献专业的研究生,按每万字80块的酬劳(因为错字率已经很低,比从零录入轻松很多),12天校完,总共付了14400块。

最后验收的时候随机抽了200页核验,单字准确率99.3%,比传统人工录入的准确率还高,总成本加起来不到1万5,是传统方案的1/17,周期不到3周。

特别提醒:如果是馆藏项目,所有流程一定要本地部署,绝对不能把未公开的古籍扫描件传到公网API、公网大模型里,数据出了问题是要担责任的,我这个项目一开始本来打算用云API,最后因为图书馆的数据合规要求,全换成了本地模型。

这些场景别硬上OCR,目前真的搞不定

干了这么多年项目,最烦那种上来就说“AI啥都能识别”的销售,实际上目前公开的古籍OCR方案能力边界很清楚,有些场景真的别浪费时间硬上:
1. 手写草书稿本:现在所有公开模型基本都是用刻本训练的,手写稿尤其是草书、行书的个人稿本,书写风格差异太大,训练样本极少,实测准确率最高也就60%左右,很多字连文史专家都要结合上下文猜,直接找专业人士人工录更划算;
2. 严重破损的页面:虫蛀面积超过30%、纸张炭化、页面残缺的,OCR最多能识别出残存的清晰笔画,缺的内容是靠文献考据补的,算法根本干不了,别信宣传里的“AI复原残缺古籍”,那都是演示用的个例,落地根本用不了;
3. 多元素混杂的页面:满页都是朱笔批校、大印章压在字上、手绘插图占一半以上的,现在的版面分析模型很容易把批注、印章篆字跟正文混在一起,识别完整理的时间比人工录还长,效率提升不明显;
4. 特殊文字类古籍:比如满汉合璧、藏文、西夏文的古籍,或是带大量算筹、符箓的道藏、医书,公开模型根本没覆盖这些字符,除非自己标个几千页样本微调,不然识别出来全是乱码。

说白了,现在的古籍OCR本质上是帮人干80%-90%的体力活,把人从对着图片一个字一个字敲的重复劳动里解放出来,最后那1%的精准度,还是得靠人把着关,毕竟古籍里藏的东西,算法是读不懂的。

常见问题

这篇文章的代码可以直接用吗?

文中代码示例均来自真实线上项目,但具体使用需要根据你的环境调整参数和依赖版本。

有问题想请教作者怎么办?

欢迎在文章页面留言评论,我们看到后会尽快回复。也可以通过网站联系我们。

相关工具推荐