仿射变换(Affine Transformation)
Affine Transformation是一种二维坐标到二维坐标之间的线性变换,保持二维图形的“平直性”(译注:straightness,即变换后直线还是直线不会打弯,圆弧还是圆弧)和“平行性”(译注:parallelness,其实是指保二维图形间的相对位置关系不变,平行线还是平行线,相交直线的交角不变。)
仿射变换中集合中的一些性质保持不变::
1)变换前是直线,变换后仍是直线
2)共线性:若几个点变换前在一条线上,则仿射变换后仍然在一条线上
3)平行性:若两条线变换前平行,则变换后仍然平行
4)共线比例不变性:变换前一条线上两条线段的比例,在变换后比例不变
仿射变换包括平移(translation)、旋转(rotation)、缩放(scaling)、错切(shear )四种类型:
- 平移和旋转两者的组合不改变图像的大小和形状,只有图像的位置(平移变换)和朝向(旋转变换)发生改变,称之为欧式变换(Euclidean transformation)或刚体变换(rigid transformation)
- 缩放又分为等比例缩放(uniform scaling)和非等比例缩放(non-uniform scaling),如果缩放系数为负数,则会叠加翻转(reflection,又翻译为反射、镜像),因此翻转可以看成是特殊的缩放
- 欧式变换和等比例缩放保持了图像外观没有变形,因此二者的组合称为相似变换(similarity transformation)
- 错切是保持图形上各点的某一坐标值不变,而另一坐标值关于该保持不变坐标值进行线性变换。坐标不变的轴称为依赖轴,其余坐标轴称为方向轴。错切分为水平错切和垂直错切。
效果图
图像的仿射
仿射变换(Affine Transformation)是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,其数学表达式形式如下:
对应的齐次坐标矩阵表示形式为:
仿射变换(Affine Transformation) 保持了二维图形的“平直性”(直线经仿射变换后依然为直线)和“平行性”(直线之间的相对位置关系保持不变,平行线经仿射变换后依然为平行线,且直线上点的位置顺序不会发生变化)。非共线的三对对应点确定一个唯一的仿射变换。
一、图像平移
二、图像水平镜像
三、图像垂直镜像
四、图像缩放
五、图像旋转
代码实现
1. 平移
import cv2 import numpy as np img = cv2.imread("c:/lena.png") rows, cols, channel = img.shape #向下移二格,向右移一格 #方法1 原始python实现,即移动每个像素位置 movX = 1 movY = 2 newImg = np.zeros((rows+10, cols+10, 3), dtype=np.uint8) for i in range(rows): for j in range(cols): newImg[i+movX,j+movY] = img[i,j] #方法2, 使用矩阵计算,原理为上面说的公式 dx = 2 dy = 1 M = np.float32([[1, 0, dx], [0, 1, dy]]) dst = cv2.warpAffine(img, M, (cols, rows)) ##第三个参数:变换后的图像大小 cv2.imshow("img", dst) cv2.waitKey(0)
2. 旋转
import cv2 import numpy as np img = cv2.imread("c:/lena.png") rows, cols, channel = img.shape #第一个参数旋转中心,第二个参数旋转角度,第三个参数:缩放比例 M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1) #将图像相对于中心旋转90度而不进行任何缩放 dst = cv2.warpAffine(img,M,(rows,cols)) cv2.imshow("img", dst) cv2.waitKey(0)
3. 图像的仿射
图像的旋转加上拉升就是图像仿射变换,仿射变化也是需要一个M矩阵就可以,但是由于仿射变换比较复杂,一般直接找很难找到这个矩阵,opencv提供了根据变换前后三个点的对应关系来自动求解M。这个函数是 M=cv2.getAffineTransform(pos1,pos2),其中两个位置就是变换前后的对应位置关系。 然后再使用函数cv2.warpAffine()。
import cv2 import numpy as np img = cv2.imread("c:/lena.png") rows, cols, channel = img.shape pts1 = np.float32([[50,50],[200,50],[50,200]]) pts2 = np.float32([[10,100],[200,50],[100,250]]) M = cv2.getAffineTransform(pts1,pts2) dst = cv2.warpAffine(img,M,(rows,cols)) cv2.imshow("img", dst) cv2.waitKey(0)