Community图像github.com

shlomsh/scanned-pdf-cleaner

将手机拍摄的照片或粗糙扫描的书籍页面、学术论文转换为干净、平整、适合打印的PDF文件。通过文本本身校正弯曲行和倾斜页面,去除手指、书脊阴影、页面卷曲、邻页碎片、污渍和边角笔迹,保留印刷文本、图表、标题和页码,并统一页边距。

scanned-pdf-cleaner 是什么?

此AI技能专为处理手机拍摄或低质量扫描的书籍章节、文章或论文PDF/图片而设计,旨在生成清晰、可读且类似打印版的PDF。它通过一系列脚本实现自动化处理:首先将输入转换为标准格式并生成网格参考图;然后由AI或用户追踪每页的四角坐标,并自动微调至实际纸张边缘;接着利用文本行检测和列对齐信息进行几何校正与色调归一化,将弯曲的文本行拉直、纸张变白、墨迹变黑,并自动移除接触页面边缘的暗色标记(如手指、书脊阴影)。用户需通过接触印片检查处理效果,并手动决定文本区域外标记的保留或移除(例如区分印刷体与手写笔记)。最终输出时统一页面大小、边距和字号。该技能支持多种书写系统(包括从右至左的希伯来语和阿拉伯语),并针对短行(如图表标注)和跨栏论文做了优化。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/shlomsh/scanned-pdf-cleaner/tree/HEAD/plugins/scanned-pdf-cleaner/skills/scanned-pdf-cleaner

Installed? Explore more 图像 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

扫描版PDF清洁器

用手机拍摄的打开书籍照片,在书脊附近会出现弯曲、倾斜、发灰,边缘还有拇指印和下一页的碎片。此技能可将它们转换为如同干净印刷品般可读的页面。

脚本负责像素处理,而您负责判断:您需要追踪每页的角落,查看被移除的内容,并决定文本外部的标记是印刷体(保留)还是非印刷体(移除)。每一步都会生成可读的接触印片,请务必查看,不要假设步骤已完美执行。

设置(每台机器只需一次)

SKILL=<此技能所在文件夹>      # 存放此 SKILL.md 的文件夹
python3 -m venv ~/.cache/scanned-pdf-cleaner-venv
~/.cache/scanned-pdf-cleaner-venv/bin/pip install -q -r "$SKILL/requirements.txt"
PY=~/.cache/scanned-pdf-cleaner-venv/bin/python

以下所有命令均以 cd "$SKILL/scripts" && $PY <脚本> ... 的形式运行。每个文档使用一个新的、空的工作文件夹,位于用户项目之外(例如临时文件夹)。用户的文件仅被读取。

工作流程

1. 准备

$PY prepare.py INPUT.pdf WORK          # 或者:图片文件夹,或图片文件(HEIC:请先转换)

生成 WORK/src/p-NNN.jpg(竖立照片)、WORK/grid/g-NNN.jpg(每张照片上叠加每100像素的红色网格,四边标有百位数字)以及 WORK/rough.json(包含每张照片的占位轮廓)。

如果照片侧向或倒置,请旋转:$PY prepare.py --turn WORK p-003.jpg 90|180|270(顺时针)。

2. 追踪页面角落(由您完成)

阅读每张网格图像。为每张照片找到属于文档的页面。将其四个角点写入 WORK/rough.json,使用源像素坐标,按页面阅读顺序排序:左上、右上、右下、左下。对于横向标签7、纵向标签12的点,写为 [700, 1200]。

{"001": {"src": "p-000.jpg", "quad": [[96,72],[930,92],[945,1468],[70,1480]]}}
  • 键是输出页面顺序(001, 002, ...)。保持该顺序与阅读顺序一致。
  • 取页面的纸张边缘,而非文本。靠近书脊处,取页面弯曲进入装订线的线条。如果页面超出照片范围,则角点放在照片边缘上。
  • 双页跨页照片给出两个具有相同 src 的条目,每页一个,例如 "005" 和 "006"。
  • 精度在约30像素内即可。下一步会自动吸附到真实边缘。

3. 吸附到纸张边缘

$PY refine.py WORK

生成 WORK/quads.json 和 WORK/sheets/quads-NN.jpg:橙色 = 您的追踪,红色 = 吸附后,绿色圆点 = 左上角。阅读这些印片。如果红色轮廓跳到了阴影、桌面或邻页上,请修正该追踪并重新运行此步骤。

4. 展平、调色并清洁边缘

$PY clean.py WORK            # 或者:clean.py WORK 004 007 来重做某些页面

对于每一页,此步骤:

  • 查找文本行和已对齐的列边缘;
  • 将文本块方正,并为每一行拟合一个平滑弯曲表面,使弯曲的行变直;
  • 将纸张调为白色,墨迹调为黑色;
  • 移除接触页面边缘的暗色标记:手指、书脊卷曲、折痕和邻页碎片。

对于少于5行文本的页面(如标题页和全页图),改用简单的四角扭曲。输出:WORK/pages/、WORK/blocks.json 和 WORK/sheets/review-NN.jpg,其中红色 = 已移除,蓝色 = 留给您决定,绿色 = 文本块。

阅读审查印片。需要检查的事项:

  • 行仍然弯曲或页面倾斜:追踪有误。修正 rough.json,然后为该页面重新运行 refine 和 clean。
  • 绿色框内的文本显示为红色:告知用户。边缘清洁从不移除文本框内的文本,除非文本位于页面边缘带上。

5. 列出文本外部的标记

$PY flags.py WORK

生成 WORK/flags/flags-N.jpg:文本块外每个暗色标记的编号图块。

6. 决定保留或移除(由您完成)

阅读标记印片,并编写 WORK/decisions.json:

{"keep": [0, 3, 4, 7], "strokes_only": [23], "erase": [{"page": "014", "box": [1500, 300, 80, 900], "mode": "strokes"}]}
  • keep:所有印刷内容。包括页码、页眉、章节编号、图注、侧边标签、表格线、插图和绘图。印刷体的文字清晰规则。书籍中的绘图也属于印刷内容,即使是涂鸦式的儿童画。
  • remove:不将其编号列出。包括手写、钢笔和铅笔笔记、污渍、斑点、指纹、灰色条和撕裂边缘阴影。钢笔线条细、不均匀且常倾斜,与字体不匹配。
  • strokes_only:带有穿过或划过印刷字母的笔画。仅移除高于1.5行的笔画。
  • erase:在 pages/page-KEY.jpg 上以页面像素为单位指定方框,用于处理文本框内您被要求移除的标记。"mode": "all" 将方框变白;"strokes" 仅移除高笔画。

在移除用户可能想要保留的内容前请询问用户。这包括文本内部的钢笔下划线和行间注释,以及荧光笔。默认:移除页边注释,保留文本内的下划线。当您无法区分印刷体和手写时也请询问。展示图块,不要描述它。

7. 完成

$PY finish.py WORK OUT.pdf           # --no-frame 保留每页自身的边框;--dpi 默认为 300

功能:

  • 将文本块外的所有内容变白,但保留的项目除外。
  • 移除紧贴文本块两侧的细长钢笔括号。
  • 将所有页面统一到一种页面尺寸:
    • 文本大小一致:近拍或远拍的照片匹配。缩放使用文本块的宽度,或者当图形缩窄列时使用行距。
    • 左右边距相等,因此原来靠一边的内容或因书籍厚度偏移的内容居中。
    • 每页顶部边距相同。

请阅读 WORK/sheets/final-NN.jpg 后交付。检查每页是否有残留污渍、被裁切的文本以及误保留的内容。然后向用户提供PDF路径。将PDF保存在输入文件旁边(例如 <名称>_clean.pdf),除非用户另有说明。

理想效果

  • 文本行从头到尾笔直且水平,包括靠近书脊的那一行。
  • 纸张纯白,墨迹纯黑,细笔画保持完整。大面积的暗色绘图保留其填充。
  • 没有手指、阴影、邻页碎片或斑点。左右边距相等,每页文本大小一致。

实际使用中的注意事项

  • 修正器通过阅读文本工作,因此对于充满对齐行的页面效果最佳。它适用于任何文字系统,包括从右至左(希伯来语、阿拉伯语),因为它仅查看行的形状。
  • 图形内的短行(标注)在拟合弯曲时会被忽略,因此图形不会导致页面折叠。
  • 大面积暗色绘图如果使用简单调色会被洗成灰色。tone() 会利用周围纸张信息保持纸张估算值。
  • 当页面的卷曲吞没了书脊附近的几个字母时,照片中已无信息可恢复。请如实告知,不要虚构文本。
  • 双栏论文:文本块跨越两栏。检查审查印片,确认跨栏区域的线条拟合正确。

相关技能