在平面图像处理中,因为镜头角度等原因,容易导致图像出现倾斜、变形等情况,为了方便后续处理我们常常需要进行图像矫正,其中主要技术原理是两种变换类型–仿射变换(Affine Transformation)和透视变换(Perspective Transformation)。
仿射变换是二维坐标间的线性变换, 故而变换后的图像仍然具有原图的一些性质,包括“平直性”以及“平行性”,常用于图像翻转(Flip)、旋转(Rotations)、平移(Translations)、缩放(Scale operations)等,具体到代码应用可以参见OpenCV官方介绍。说句题外话,如果没记错的话,仿射变换在高中数学的选修部分就出现过,它可以解决一些初等几何问题,比如部分椭圆题,使用仿射变换往往能得到优雅解法。
但是仿射变换不能矫正一些变形,如矩形区域的部分发生变化最终变成梯形,这时候矫正就需要用到透视变换。透视变换(Perspective Transformation),又称投影映射(Projective Mapping)、投射变换等,是三维空间上的非线性变换,可看作是仿射变换的更一般形式,简单讲即通过一个3x3的变换矩阵将原图投影到一个新的视平面(ViewingPlane),在视觉上的直观表现就是产生或消除了远近感。落实到OpenCV,图像的透视变换由以下函数完成(该函数是针对图像的包装,其本质调用cv::perspectiveTransform进行向量坐标的变换):
void cv::warpPerspective ( InputArray src, OutputArray dst, InputArray M, Size dsize, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar &borderValue = Scalar(0))
其中,src是输入图像,dst是输出图像,M是3x3变换矩阵,dsize是输出图像的大小,flags指定像素插补方法以及矩阵倒置标志cv::WARP_INVERSE_MAP,borderMode指定边沿像素的推算模式,其中BORDER_CONSTANT指示边沿像素用borderValue替换,因为默认是0,所以我们变换后的图像边界可能会出现黑边,此时可以指定BORDER_REPLICATE对边界像素进行复制,即aaaaaa|abcdefgh|hhhhhhh
(a-h代表像素)。