实现类似扫描全能王的功能,将拍照得到可能存在扭曲的书本图像修正成类似扫描机扫出来的样子。
- ==local warping是不是可以直接用这个矩形点变化替代==(四个点效果应该不够好)
- ==Rectangling可以优化下,转置可以改掉,然后seam carving也可以优化==
- ==书本文字的扭曲可能要解决一下==
整体大概分为四种思路:
- 通过获得书本的四个顶点确定书本位置,然后直接使用透视变换扭曲成矩形;
- 人工指定书本四个顶点,然后直接使用透视变换扭曲成矩形;
- 通过GrabCut获得书本掩码然后再获得书本四个顶点,然后直接使用透视变换扭曲成矩形(其实有点多余,既然以及加了人工操作了,不如直接用方案2,不过这也是为0好与4进行效果对比);
- 通过GrabCut获得书本掩码,然后用Rectangling算法矩形化。
- 对抗文字变形
其中方案1、2、3、4使用c++实现,分别对应于scanner1.py
、scanner2.py
、scanner3.cpp, scanner3.py
和scanner4.cpp
。
从理解的顺序看应该是: 4->3->2->1->
通过获得书本四个顶点或是获得书本掩码来确定书本位置。
先高斯模糊后使用Canny算子检测,之后寻找最大的能近似形成矩形的轮廓:
不过若拍摄所处环境较差,难以准确找到书本边缘:
先使用GrabCut算法初步分离前后景;
然后利用洪范算法以及膨胀腐蚀操作得到最终掩码:
透视变换(Perspective Transformation)是将成像投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。简而言之,就是将一个平面通过一个投影矩阵投影到指定平面上。
透视变换是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换。
我们相机因为拍摄角度的问题得到不同的照片也是主要因为使用了不同的透视变换,因而很自然的想法是找到这个透视变换来矫正扭曲。
透视变换的数学表达如下:
从另一个角度也能说明三维变换和二维变换的意思,仿射变换的方程组有6个未知数,所以要求解就需要找到3组映射点,三个点刚好确定一个平面。透视变换的方程组有8个未知数,所以要求解就需要找到4组映射点,四个点就刚好确定了一个三维空间。
其实我觉得书本的扭曲和全景图矩形化是有较大不同的,按我的理解:
-
扫描仪的目标是希望矫正因为拍摄角度不好而造成内容扭曲的书本;
-
而全景图矩形化的目标是在保证图像内容尽量不失真的同时变成矩形。
即前者希望将扭曲的内容恢复,而后者希望能尽量保持图像内容不变,所以我们从后面的实验中也能看到其实Rectangling算法的效果不是很好。
诸如扫描全能王等软件往往还会有图像增强功能,无非就是做一些对比度提高,增强锐化:
经高斯滤波及矩阵除法处理:
增强对比度和亮度:
和我预想的结果差不多,原先是扭曲的内容由于Rectangling倾向于保留内容不变,所以在结果中还是斜的:
从掩码中获得顶点然后透视变换:
其实grabcut也需要人工指定,而透视变换只需要四个顶点,索性直接人工指 定四个顶点然后透视变换:
效果略差一些,但是在很多情况还是可以工作的不错