agentleFS
MidnightDarlingMidnightDarling/collate/skills/prep-scan/SKILL.md

prep-scan

Skill8 starsChanged 7 months agoApache-2.0View on GitHub

使用场景:用户在 Mac 上运行 `/collate:prep-scan`、提供一个扫描版 PDF、说出"去水印""去馆藏章""去知网水印""去页眉页脚""预处理论文 PDF""清理扫描件""图书馆章""历史文献 OCR 前处理""国家图书馆藏""中华再造善本"等。典型输入是用户从知网、读秀、国图扫描服务、档案馆数字资源、古籍数据库下载的 PDF,上面常见问题是:红蓝馆藏章、数据库 logo 水印(知网/维普/读秀/CNKI)、扫描日期戳、页眉刊名、页脚馆藏号、古籍版心鱼尾。这个 skill 把这些都处理干净并合回一份 cleaned.pdf,给下一步 OCR 用。这个 skill 应当主动触发,只要用户提到历史论文 PDF 或图像预处理就走它,不必等用户说"预处理"三个字。

  • Installs packages

The file

Files
SKILL.md

PDF 预处理 — 历史扫描件专用

Task

用户要校对的扫描件不是干净原稿。典型来源和污染物:

来源常见污染
中国知网(CNKI)/ 万方右下角 logo 水印、"中国学术期刊出版总库" 对角线水印
读秀 / 超星全页淡灰"读秀学术搜索"水印
国家图书馆 / 省图红色馆藏章、馆藏登记号、扫描日期戳
中华再造善本 / 古籍数据库馆藏章、版权水印、影印页眉
档案馆扫描件红色骑缝章、档号戳、扫描批次编号
民国期刊影印本刊名页眉、期号页脚、补白广告

这些污染会让 OCR 把"國立北平圖書館藏"之类的章文识别进正文,也会把"下载日期:2024-xx-xx"当成脚注。你要把它们清掉,但不能伤到正文——尤其是淡墨古籍、残损民国报刊,比水印还浅。

输出:<pdf-basename>.ocr/prep/cleaned.pdf + 逐页 PNG(供 OCR 和后面的对照预览复用)。

目录布局:本 skill 产物全部落在 <pdf-basename>.ocr/prep/ 下,和后续 OCR 产物共享同一个 .ocr/ 工作区。权威规范见插件的 references/workspace-layout.md——不要在 PDF 同级另建 .prep/ 目录。

Process

Step 1:确认输入

test -f "<pdf-path>" && file "<pdf-path>" | grep -qi pdf || echo "NOT_A_PDF"

若返回 NOT_A_PDF,终止并报告路径或格式问题。

检查是不是"已 OCR 的文字版 PDF"(例如知网下载的"CAJ 转 PDF"带有文本层):

python3 -c "
import PyPDF2
with open('<pdf-path>', 'rb') as f:
    r = PyPDF2.PdfReader(f)
    t = r.pages[0].extract_text() or ''
    print('TEXT_LAYER' if len(t.strip()) > 50 else 'SCAN_ONLY')
"
  • TEXT_LAYER:PDF 已含文字层,OCR 步骤可跳过。继续处理图像水印(文字层不影响)。
  • SCAN_ONLY:走完整流程。

Step 2:建工作目录

在 PDF 同级建 .ocr/ 工作区,并在里面开 prep/ 子目录,不改动用户原文件:

PDF="<pdf-path>"
DIR=$(dirname "$PDF")
BASE=$(basename "$PDF" .pdf)
OCR="$DIR/$BASE.ocr"
WORK="$OCR/prep"
mkdir -p "$WORK/pages" "$WORK/cleaned_pages" "$WORK/trimmed_pages"
cp "$PDF" "$WORK/original.pdf"

original.pdf 作为原始备份保留在 prep/,供后续回滚。注意:.ocr/ 根目录的 source.pdf 会在 Step 6 由 cleaned.pdf 派生出来,它才是"进入 OCR 阶段的 PDF"。

Step 3:拆页成 PNG

python3 "${CLAUDE_PLUGIN_ROOT}/skills/prep-scan/scripts/split_pages.py" \
    --pdf "$WORK/original.pdf" \
    --out "$WORK/pages" \
    --dpi 300

300 DPI 是 OCR 黄金点。再高 → 图大内存贵 OCR 不多提升;再低 → 小字(民国 5 号字、古籍双行夹注)糊掉。

老扫描件本身就不到 200 DPI 的情况,强行 300 会放大噪点。脚本会先探测原图 DPI,自动封顶:原图低于 250 就不强行上采样。

Step 4:去水印 / 去馆藏章

python3 "${CLAUDE_PLUGIN_ROOT}/skills/prep-scan/scripts/dewatermark.py" \
    --in "$WORK/pages" \
    --out "$WORK/cleaned_pages" \
    $( [ "$2" = "--aggressive" ] && echo "--aggressive" ) \
    $( [ "$2" = "--keep-color" ] || [ "$3" = "--keep-color" ] && echo "--keep-color" )

脚本处理三类水印:

  1. 彩色章(红 / 蓝):HSV 色域分离,S 通道高饱和 + H 在红/蓝区间的像素用周围底色 inpainting。历史文献特别要处理好红色——古籍朱批和馆藏红章像素上难分,脚本会按形状做二次判定(章是规则矩形/圆形,批注是手写自由形状)。默认保留朱批、去馆藏章。
  2. 灰度对角水印:典型知网/维普的对角大字水印。Hough 变换检测一致角度的线性重复文本,擦除后 inpaint。
  3. 浅灰重复水印:如"读秀学术搜索"整页淡水印。形态学顶帽变换提取浅色重复纹,减去。

--aggressive:放宽阈值,适合顽固水印,代价是可能擦掉淡墨字。水印未清理干净时再加。

--keep-color:关闭颜色通道处理。处理彩色历史地图、影印彩图时使用。

Step 5:裁页眉页脚

# 默认裁上下各 8%;输出到独立目录,不覆盖 cleaned_pages
python3 "${CLAUDE_PLUGIN_ROOT}/skills/prep-scan/scripts/remove_margins.py" \
    --in "$WORK/cleaned_pages" \
    --out "$WORK/trimmed_pages" \
    --header-ratio 0.08 \
    --footer-ratio 0.08

独立目录的意义:保留 cleaned_pages/ 作为"仅去水印、未裁边"的中间态,一旦裁过头可以从这里直接重新裁,不必从 pages/ 重跑去水印。

这一步要看文献类型决定:

情况处理
现代期刊(有刊名页眉 + 页码)默认 8% 裁掉,Step 6 用 trimmed_pages 合 PDF
民国报刊(刊名页眉要留作考据)跳过此步,Step 6 直接用 cleaned_pages 合 PDF
古籍(版心鱼尾 + 书口)跳过此步,古籍的版式信息本身就是研究对象
档案影像(档号脚注要留)跳过此步

判断依据:打开 $WORK/pages/page_001.png 确认第一页内容——

  • 页眉是"XX 史研究 2023 年第 3 期"这类 → 裁
  • 页眉是"北京大学学报(哲学社会科学版)"但整页只有两行 → 不裁(可能是封面)
  • 页眉是古籍版心鱼尾 → 不裁

类型不明时询问用户。

Step 6:合回 PDF + 发布到工作区根

# 跑过裁边(现代期刊) → 用 trimmed_pages
# 跳过裁边(古籍/档案/民国报刊) → 用 cleaned_pages
SRC="$WORK/trimmed_pages"   # 或 "$WORK/cleaned_pages"
python3 "${CLAUDE_PLUGIN_ROOT}/skills/prep-scan/scripts/pages_to_pdf.py" \
    --in "$SRC" \
    --out "$WORK/cleaned.pdf"

# 发布到 .ocr/ 根目录作为 source.pdf,供 ocr-run 直接消费
cp "$WORK/cleaned.pdf" "$OCR/source.pdf"

source.pdf 是 .ocr/ 根部唯一的 PDF 文件,永远指向"待 OCR 的当前版本";prep/cleaned.pdf 是它的同级孪生,保留在 prep/ 里供回滚和调试。

Step 7:刷新 README + 报告 + 对照抽样

跑完后重写工作区 README.md(目录地图):

python3 "${CLAUDE_PLUGIN_ROOT}/scripts/workspace_readme.py" --workspace "$OCR"

汇报格式:

清理完成。工作区:$OCR/

- 原件备份:$OCR/prep/original.pdf
- 清理版:  $OCR/prep/cleaned.pdf
- 入 OCR 用:$OCR/source.pdf(= cleaned.pdf 的副本)

已打开前 3 页对照图核验:
  $OCR/prep/pages/page_001.png         (原图)
  $OCR/prep/cleaned_pages/page_001.png  (清理后)

若正文被误伤 → 重跑加 --keep-color
若水印残留   → 重跑加 --aggressive

下一步:/collate:ocr-run $OCR/source.pdf
(或先 /collate:visual-preview $OCR 核查清理效果)

对照图打开:

open "$OCR/prep/pages/page_001.png" "$OCR/prep/cleaned_pages/page_001.png"

判断规则

  • PDF 为古籍竖排:本地 MinerU CLI 当前不支持 --layout,在 ocr-run 阶段改用 baidu_client.py --layout vertical 或 mineru_client.py --layout vertical(云端 API)。
  • 第一页为扉页 / 版权页:询问用户是否从最终输出剔除。
  • PDF 超过 200 页:建议按章节拆分处理,避免云 OCR 配额超限和核验困难。

失败兜底

  • OpenCV 报 libGL error:brew install opencv
  • pdf2image 报 Unable to get page count:poppler 未安装,brew install poppler
  • PDF 加密:用 macOS 预览.app「另存为 PDF」通常可去密

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.