文档照片展平:把拍弯的纸拉平
书页再弯、小票再皱,拍下来就能拉平。计算全在你自己的设备上,照片不会离开浏览器。
待处理的页面
把四个黄点拖到纸的四个角上。结果会按这个框裁切,长宽比例也按你标的四条边来算——细长的小票出来就还是细长的。
它是怎么做的
先把方向摆正
一个 6.8 MB 的小分类器(PP-LCNet)先看一眼,判断纸是横着的还是倒着的,转正了再往下走。拍的时候手机横竖拿错也不要紧。
估出纸是怎么弯的
UVDoc 把照片缩到 712 × 488,预测一张 45 × 31 的形变网格:平整纸面上的每一处,在你的照片里跑到了哪里——书脊处的卷曲、折痕、相机的倾斜都在这张网格里。
把每个像素拉回原位
网格放大到照片原分辨率,每个输出像素按网格指的位置取回来。结果和原图一样大,再裁边、调效果,就可以保存了。
为什么「四角校正」救不了弯曲的书页
网上大多数免费扫描工具、很多手机 App 的自动裁切,做法都是找到纸的四个角,做一次透视变换。对一张斜着拍的平纸,这完全够用。可书页靠近书脊的地方不是平的,它朝远离镜头的方向卷下去,文字行拍出来是弧线——一次透视变换没法把弧线变直。
UVDoc 训练时看的是大量「折过、卷过、揉过的纸的照片」和它们平整原件的配对,所以它对纸面每一小块给出不同的校正量。示例里的皱小票演示的是折痕,书页演示的是书脊。
怎么拍,展平效果最好
- 整张纸都拍进来,四周留一圈桌面。模型要看到纸的边缘,才知道纸到哪儿为止。
- 尽量从正上方拍。倾斜它能纠正,但字在照片里本来就很小的话,展平后也还是小。
- 一张照片只拍一页。书摊开时左右两页分开拍;两页一起拍会被当成一整张纸来展平。
- 台灯从侧面照,书缝里会有一道阴影。选「去阴影」可以把底色拉匀;要打印、交作业,选「黑白」。
用到的模型与许可证
展平用的是苏黎世联邦理工学院 Floor Verhoeven、Tanguy Magne、Olga Sorkine-Hornung 的 UVDoc(SIGGRAPH Asia 2023,MIT 许可证),权重是飞桨 PaddlePaddle 发布的 ONNX 版本 PaddlePaddle/UVDoc_onnx(Apache-2.0,31.7 MB)。方向判断用飞桨的 PP-LCNet_x1_0_doc_ori(Apache-2.0,6.8 MB)。
两个模型都由 ONNX Runtime Web 在这个标签页里运行:浏览器支持 WebGPU 就用显卡,不支持就用 CPU(WebAssembly)。许可证全文见 LICENSE-model.txt。
我们测试机(Apple M2 Max + Chrome)上的实测:1600 × 1200 的照片,WebGPU 0.06 秒、CPU 0.95 秒(这里的 WebAssembly 是单线程);1200 万像素的手机原图分别是 0.2 秒和 1.2 秒。普通笔记本用 CPU 会更慢。
常见问题
照片会上传到服务器吗?
不会。页面只从我们这里下载两个模型文件,之后所有计算都在你的浏览器标签页里完成。原照片、展平结果、导出的 PDF 都只在你的设备上生成,不发给任何服务器——模型加载完之后断开网络,在同一个标签页里照样能继续处理。
和手机自带的扫描、网上的「四角校正」工具有什么区别?
那些工具找到纸的四个角再拉成矩形,纠正的是拍摄角度;纸本身是弯的,出来还是弯的。这个工具估算的是纸面怎么弯的,再把弯曲还原,所以书脊附近、折痕两侧的字行都能变直。上面那两张示意图就是区别。
为什么第一次要下载 37 MB?
那是两个神经网络:UVDoc(31.7 MB)和方向分类器(6.8 MB)。这个模型没有更小的量化版本,所以用的是原始精度。下载后存在浏览器缓存里,下次打开一秒左右就能用,不会再下载。
我的浏览器没有 WebGPU,能用吗?
能用。没有 WebGPU 时同一个模型改用 CPU(单线程 WebAssembly)运行,在我们的 M2 Max 上一张常见照片从 0.06 秒变成 1 秒左右,慢一些的笔记本还要更久。结果完全一样——我们逐像素比过两条路径,最大差别是 1/255。
能一次处理多页、合成一个 PDF 吗?
能。一批最多放 5 张,缩略图下面的箭头可以调页序,最后点「全部存成 PDF」。每页保留自己的比例和你选的效果。PDF 是这个页面自己拼出来的,不经过任何在线服务。
能把纸上的字识别出来吗?
这个工具只负责把图拉平,不识别文字。要转成可编辑的文字,把展平后的图存下来,放进本站的 图片转文字 工具——它也在本地运行,而且拉平后的页面比弯的识别得准得多。
什么样的照片容易出问题?
纸被画面切掉一截的(看不到的部分没法拉平)、两页一起拍的(会被当成一张纸)、离得太远字太小的。另外输出和原照片一样大,所以细长的小票出来会被拉宽——用「裁四角」把它裁回纸的形状就好。