1. 引用
2. 什么是仿射变换?
3. 定义
向量空间中进行一次线性变换(乘以一个矩阵A)再加上一个平移(加上一个向量B)。
现定义参数A,B和AB的组合M(固定尺寸2*3):
定义自变量(起始量):
则X → T 的仿射变换过程可以表达式为:
或者:
得到结果T:
其实可以看出,矩阵M中a决定缩放旋转等性质,b决定平移性质。若a为单位矩阵,则M实际是表示平移b的效果:
仿射变换(Affine Transformation)
4. 常用的转换矩阵
5.实际应用
我们知道仿射变换一句话概括:原始图像IMG1在矩阵M的变换下,得到结果图像IMG2。
那么实际的应用就分两种情况:
- 知自变量和因变量X和T,求参数M(即A和B)【求关系–M代表IMG1和IMG2的关系】
- 知自变量X和参数M,求结果T 【求结果–知道IMG1和矩阵M,就结果图】
由上式可见,完成仿射变换的公式含有6个未知数,则需要6个公式来表示才可解,所以完成图像的仿射变换需要三个点的对应关系,从而解出6个未知数,通过仿射公式对全部图像像素点进行仿射变换,所以在实际应用中需要先知晓3对坐标点的位置,计算出映射关系的仿射矩阵𝑀𝑀,再对全部像素进行仿射变换运算得到仿射后的图,完成仿射变换。
5.1 栗子1
在openCV中:
比如将128*128的图像上移30,左移30,则:
我们已经得到有三对相应点
# 定义原图中三个点pts1
pts1=np.float32(([0,0],[0,127],[127,127]))
# 定义结果图中三个点pts2
pts2=np.float32(([30,0],[30,97],[127,97]))
# 利用这三对点,求出变换矩阵M
M=cv2.getAffineTransform(pts1,pts2)
# 再利用变换矩阵对原图所有像素点进行变换
# 并指定了输出图像的shape和原图shape一样
res=cv2.warpAffine(img,M,dsize=img.shape[0:2])
cv2.imshow("",res)
cv2.waitKey(0)
5.2 栗子2
- 使用仿射变换,将图片在x方向上放大1.3倍,在y方向上缩小至原来的4/5。
对应的坐标如下:
代码如下:
import numpy as np
import cv2
img=cv2.imread("../imori.jpg")
pts1=np.float32(([0,0],[0,127],[127,127]))
pts2=np.float32(([0,0],[0,101],[165,101]))
M=cv2.getAffineTransform(pts1,pts2)
# 在定义输出图像尺寸时,从上图可以看出,有效图片在165*101部分
res=cv2.warpAffine(img,M,(165,101))
cv2.imshow("",res)
cv2.waitKey(0)
如果在上面的结果之上,同时在x方向上向右平移30,在y方向上向上平移30呢?
对应坐标为:
如法炮制,代码:
import numpy as np
import cv2
img=cv2.imread("../imori.jpg")
pts1=np.float32(([0,0],[0,127],[127,127]))
pts2=np.float32(([30,0],[30,71],[195,71]))
M=cv2.getAffineTransform(pts1,pts2)
# 在定义输出图像尺寸时,从上图可以看出,有效图片在165*101部分
res=cv2.warpAffine(img,M,(165,101))
cv2.imshow("",res)
cv2.waitKey(0)