照片转扫描件
将手机拍摄的文档照片(合同、收据、书本、票据等)转为清晰的扫描件效果。自动去除桌面/背景、消除不均匀阴影、增强文字对比度,输出白底黑字的标准扫描件。
适用场景
- 用户上传手机拍摄的文档/合同/收据/书本照片,要求变成扫描件
- 用户说"转成扫描件" / "扫描件效果" / "清晰的扫描件" / "拍照转扫描" / "文档扫描"
- 照片有明显的桌面背景、光照阴影、拍摄角度倾斜
- 输出要求:白底、文字清晰可读、适合打印或归档
不适用场景
- 用户需要 OCR 文字提取(请用其他 OCR 技能)
- 用户希望保留彩色原始效果(本技能输出黑白扫描风格)
- 输入已经是清晰的数字 PDF(无需"扫描")
依赖
运行前需确保 Python 环境已安装 opencv-python-headless 和 numpy:
pip install opencv-python-headless numpy
使用流程
-
接收输入图片 — 接受一张或多张 JPG/PNG 文件(多页文档可批量处理)。
-
运行处理脚本:
bash python <skill_dir>/scripts/photo_to_scan.py \ <input1.jpg> <input2.jpg> ... \ -o <输出目录> \ [--edge-margin 0.04]
脚本处理流程:
- Otsu 自动阈值:分离纸张(亮)与背景(暗)
- 裁切纸张区域:忽略外圈 4% 边角阴影,取中心区域白色像素的 bounding box
- 阴影去除:分通道形态学白顶帽归一化,消除不均匀光照
- 自适应阈值 + 反锐化蒙版:文字更黑更锐利
- 边缘填白:外圈 2% 强制填白,去除残余黑色噪点
-
展示结果 — 用
present_files将输出图片展示给用户查看。 -
质量验证 — 文字应清晰可读、边缘干净、无明显伪影。如用户不满意,可调整:
- 增大--edge-margin(如 0.06):适用于边缘阴影较多的照片
- 减小--edge-margin(如 0.02):适用于裁切过于激进的情况
参数说明
| 参数 | 默认值 | 说明 |
|---|---|---|
inputs |
(必填) | 输入图片路径,支持多张 |
-o, --output-dir |
./scan_outputs |
输出目录 |
--edge-margin |
0.04 |
边角阴影安全区比例(0.04 = 4%),值越大裁切越多 |
技术要点(调参前必读)
- 为什么用 Otsu + 边距裁切,不用 Canny 边缘检测:Canny 在内容密集的文档图像上会把文字边缘误认为纸张边缘,导致裁出极小的碎片区域。Otsu + 4% 边距 + 亮区 bounding box 在手机拍摄的文档照片上更加稳健。
- 为什么用形态学白顶帽去阴影:简单有效。分通道
dilate + medianBlur估计局部背景,再255 - absdiff + normalize拉平光照。比 CLAHE 更适合文档场景。 - 自适应阈值参数(Gaussian, block=31, C=12):针对中文文档在手机照片典型分辨率下调优。反锐化蒙版(1.5/-0.5)在二值化后进一步增强锐度。
- 2% 边缘填白是关键步骤 — 没有这一步,Otsu + 4% 边距会在角落留下暗色阴影斑点,被自适应阈值放大成黑色噪点。
常见坑(避免重复踩)
- 不要用 Canny + 轮廓找纸张:在桌面背景的照片上,Canny 会锁定文字轮廓,裁出极小区域。请用 Otsu + bounding box。
- 不要过度形态学闭运算:在 Otsu 二值图上用 31 像素核迭代 3 次,会把纸张和背景连成一片。用小核(15-25, 1-2 次)或跳过闭运算,依赖 4% 边距。
--edge-margin是比例值不是像素值:0.04 = 4%,值越大裁切越多、边缘伪影越少;值越小保留内容越多。- 本技能不做透视矫正/倾斜校正:仅做裁切和增强。如果照片严重倾斜(旋转数度),需要先做 Hough 直线 / PCA 校正,或把校正后的图再过一遍本技能。
文件结构
photo-to-scan/
├── SKILL.md # 本文件
└── scripts/
└── photo_to_scan.py # 主处理脚本