图像的几何变换
一、引言
打开任意一个图像的编辑器,一般都可以进行对图像进行放大、缩小、旋转等操作,这类操作改变了原图中各区域的空间关系。对于这类操作,通常称为图像的几何变换。
完成一张图像的几何变换需要两个独立的算法。首先,需要一个算法实现空间坐标变换,用它描述每个像素如何从初始位置移动到终止位置;其次,还需一个插值算法完成输出图像的每个像素的灰度值。
二、图像平移的原理
平移是最简单的图像的几何变换。如图所示
,
假设空间坐标(x,y),其中图片的尺寸范围为0<=X<=200, 0<=Y<=200,先沿X轴正方向平移400,再沿Y轴正方向平移200;就得的到上面的平移图片。
将上述示例一般化,假设任意空间坐标(x,y)先沿X轴平移tx,再沿Y轴平移ty,则最后得到的坐标为(m,n) = (x+tx,y+ty)。用矩阵的形式表示该平移变换换过程如图所示,。
其中, 若tx>0,则表示图片沿x轴正方向移动;若tx<0,则表示图片沿x轴负方向移动。ty与之相类似。
三、代码展示
1:方程法
矩阵仿射变换有6个未知的参数,所以只需要三组对应位置坐标,构造出由六个方程组成的方程组即可解六个未知参数。
举例:如果(0,0),(200,0),(0,200),这三个坐标通过某仿射变换矩阵A分别转换为(0,0),(100,0),(0,100),则可利用这三组对应的坐标构造出这6个方程,求解出仿射矩阵A。OpenCV提供的函数:cv2.getAffineTransform(src, dst)。通过这样的方法,可以计算矩阵src到dst相对应的仿射矩阵,且仿射矩阵为2行3列的矩阵。每一行代表一个坐标,且数据类型必须为浮点类型,否则会报错。示例代码如下:
import cv2
import numpy as np
#输入矩阵
src = np.array([ [0, 0], [200, 0], [0, 200]], np.float32)
#目标矩阵
dst = np.array([ [0, 0], [100, 0], [0, 100]], np.float32)
#仿射矩阵
A = cv2.getAffineTransform(src, dst)
print(A)
2:矩阵法
对于使用矩阵相乘法计算仿射矩阵,前提是需要知道基本仿射矩阵变换步骤。即以空间坐标(x,y)平移为例,则变换后的形式为:,显然仿射矩阵就是平移矩阵。对于矩阵的乘法,注意不是矩阵的点乘,Numpy提供了dot函数来实现。假设,对空间坐标(x,y)先在水平方向上平移100,在垂直方向上平移100,计算该仿射变换矩阵,代码如下:
import numpy as np
t = np.array([ [1, 0, 100], [0, 1, 0], [0, 0, 1] ]) #平移矩阵x方向
y = np.array([ [1, 0, 0], [0, 1, 2000], [0, 0, 1] ]) #平移矩阵y方向
#仿射矩阵 当然t矩阵和y矩阵可以直接写在一起
a = np.dot(t,y)
print(a)