引子:
你是否遇到过这种情况:用手机对着身份证拍张照片,然后想打印出扫描件的效果?应用商城里有个热门app好像叫“扫描全能王”,大概提供了这个功能,但是它是收费的,普通用户用起来有些许不便。最近我也遇到了这个问题,别人用手机拍了个身份证照片传给我,如上面所示,让我把它打印出来:我最先想用PS,但是我发现无法用一个规则的矩形把它框得很好,我那没入门的PS技术无法解决这个问题,于是我就花了一晚上时间写了个程序,矫正结果如上面所示。本文将和大家分享一下我的代码。
一、矫正原理
根据宝典"Multiple View Geometry in Computer Vision",同一个相机从不同角度对一个平面成像,两个时刻成的像之间存在一个单应,也叫射影变换(3x3矩阵)。身份证表面是一个平面,现在的问题就是给定一个任意角度下拍摄的身份证照片,如何把它矫正成一个俯视视角下的照片,核心就是求解一个单应H。
单应是一个3阶矩阵,9个参数,8个自由度,求解单应需要8个线性方程,一对对应点(x,y)和可以构造2个线性方程,所以求解单应至少需要4对对应点。
如上图所示,我们依次选取身份证照片的左下角、左上角、右上角、右下角,然后将这四个位置坐标映射到一个标准矩形的四个顶点上,即可求出单应。在程序中,基于opencv的highgui实现了交互式从图像中选点,然后计算出身份证照片的长度height和宽度width,然后将原图中的身份证左下角映射到坐标(0,height),左上角映射到(0,0),右上角映射到(width,0),右下角映射到(width,height)。接着基于opencv已有函数求出单应。注:opencv以图像左上角为坐标原点,水平向右为x轴,竖直向下为y轴。这里有个小技术,因为身份证的长宽比是标准的,因此可以将width固定,height根据比例进行相应设置,则可以保证矫正后的身份证图片具有非常正确的比例。
如果直接应用上述单应对原图进行变化的话,会存在一些问题:图像中某些区域变换到负的坐标空间,从而被忽略掉,导致变换后的图像比原图像内容少了一大块。为了解决这个问题,只需要再上述变换的基础上再实施一个图像平移操作就可以了,具体地:根据上述单应,求出图像