scan-to-docx · 扫描资料转精准 Word
通用型扫描资料 → Word 转换 skill。核心价值:通用 OCR→docx 工具会丢掉原图下划线的「填空」语义,本 skill 把它还原成 Word 里可编辑的下划线空位。
何时用
- 扫描件(图片 / PDF)想转成可编辑 Word。
- 原图有下划线填空,要求转后仍是下划线(不是纯文本)。
- 批量处理同类资料:写一个 profile,反复用。
架构(通用管线与文档配置解耦)
扫描图/PDF
└─[ocr.py] PaddleOCR 文字识别 + 下划线检测
├─ ocr_result.json 每页文字框 {x0,y0,x1,y1,text}
└─ lines.json 每页下划线线段 segs [[x0,x1,y], ...]
└─[pipeline.py] 行合并 → 块分类(标题/单元/课/条目/填空) → 下划线坐标重建 → 修正表应用
└─[docx_writer.py] 版式/字体/页眉页脚/每页后缀,写出精准 .docx
所有「这份资料专属」的东西都在 profile JSON 里:纠错表、标题正则、版式常量、页眉页脚文案、段落后缀。换一份资料只改 profile,管线代码不动。
依赖
paddlepaddle paddleocr python-docx opencv-python(paddleocr 自带) pypdfium2(paddleocr 自带)
PaddleOCR / opencv / pypdfium2 在 ocr.py 内懒加载;只用「吃已有 OCR 结果」模式时不需 paddle。
用法
1) 直接吃已有 OCR 中间结果(调试/回归):
python scripts/run.py \
--ocr-result ocr_result.json --lines lines.json \
--profile profiles/_base.json \
--out out.docx
2) 内部跑 PaddleOCR(标准用法):
python scripts/run.py \
--input scan.pdf # 或图片目录 / 单张图
--profile profiles/_base.json \
--out out.docx
--input 模式会把 OCR 中间结果写到 --work-dir(默认输出目录下的 .ocr_tmp)。
Profile 字段
| 字段 | 说明 |
|---|---|
block_rules |
块分类正则:title/unit/lesson/item/sub2/sub,每项 {regex, max_len?, first_page_only?}。匹配不到则归为 cont。 |
corrections.global / corrections.once |
[[错字,正字], ...]。匹配不上只警告不崩溃。 |
skip |
跳过行正则(页脚页码、水印等)。 |
motto_filter |
含此串且较短的行整体丢弃。 |
title_text / lesson_suffix |
标题固定文案、每课末尾后缀(如「班级:_ 姓名:_」)。 |
fonts / page / header / footer |
字体、页边距、页眉页脚(footer="page" 生成「第X页 共Y页」)。 |
ul_y_minus / ul_y_plus / ul_overlap |
下划线映射窗口与重叠阈值。 |
ul_detect_threshold / ul_band_ratio / ul_min_width_ratio |
ocr.py 下划线检测的暗度阈值、条带比例、最小宽度比。 |
模板:profiles/_base.json —— 字段齐全但取中性默认值的空骨架,照着它复制改名即可,无需附带任何具体资料的配置。
扩展新资料类型
- 复制
_base.json改名,按新资料填block_rules、corrections、page、header等。 - 先用「吃已有 OCR 结果」模式跑通,核对下划线段落数与预期。
- 再切到
--input模式整链验证;下划线偏少就调低ul_detect_threshold或ul_min_width_ratio。
已知边界
- 表格、插图目前按「整页文本 + 填空」处理;结构化表格恢复是后续模块(PaddleOCR layout 已具备基础能力,按需接入)。
- 不同 OCR 引擎识别结果不同,换引擎后
corrections需按新错字重校。 - 下划线检测对扫描质量敏感:阴影、双下划线、手写体可能漏检,靠 profile 阈值调。