opencv仿射变换原理
仿射变换是opencv的基本知识点,主要目的是将原始图片经过仿射变换矩阵,平移、缩放、旋转成目标图像。用数学公式表示就是坐标转换。
其中x,y是原始图像坐标,u,v是变换后的图像坐标。将公式转换为齐次坐标矩阵:
下面用常见的仿射变换来解释一下具体变换过程。
常见的仿射变换形式
蓝色为原始图像,橙色为变换后图像。
平移
缩放
旋转
具体代码解析
总述
opencv的cv2.warpAffine
函数用来进行仿射变换,其具体参数为:
cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
src: 输入图像。
M: 变换矩阵,是一个 2x3 的矩阵。
dsize: 输出图像的大小,是一个二元组 (width, height)。
dst (可选): 输出图像,可以是预先创建的空白图像。
flags (可选): 插值方法的标志。可以是以下之一:
cv2.INTER_LINEAR: 线性插值(默认)。
cv2.INTER_NEAREST: 最近邻插值。
cv2.INTER_CUBIC: 三次样条插值(用于放大)。
cv2.INTER_AREA: 区域插值(用于缩小)。
等等。
borderMode (可选): 边界模式,用于处理超出边界的像素。可以是以下之一:
cv2.BORDER_CONSTANT: 常量填充。
cv2.BORDER_REPLICATE: 复制边界像素。
cv2.BORDER_REFLECT: 反射边界。
cv2.BORDER_WRAP: 包裹边界。
等等。
borderValue (可选): 当使用常量填充时的边界值,默认为 0。
要求知道上述仿射变换矩阵M,由于最后一行固定是001,因此变量M只有6个变量2X3。
通常在opencv中使用两种方法来求取仿射变换矩阵,分别是cv2.getAffineTransform
和cv2.getRotationMatrix2D
cv2.getAffineTransform
3点法,也叫方程法,通过不共线的3个点确定仿射变换矩阵。
import numpy as np
src = np.array([[0, 0], [100, 0], [0, 100]], np.float32) # 源图像坐标
dst = np.array([[0, 0], [50, 0], [0, 50]], np.float32) # 转换后图像坐标
M = cv2.getAffineTransform(src, dst)
print(M)
'''
[[0.5 0. 0. ] [0. 0.5 0. ]]
'''
原始图像3个点为src,变换后的3个点名为dst,从数字也能看出来,这个变换就是x,y缩小一半。
cv2.getRotationMatrix2D
旋转矩阵法,通过指定旋转中心和旋转角度来自动求取变换矩阵。
M = cv2.getRotationMatrix2D((256, 256), 30, 1)
print(M)
上面代码意思是以256,256为中心逆时针旋转30度,缩放比例设置为1.
代码及效果图
img = cv2.imread("00000.png")
H,W,C = img.shape
warpimg = cv2.warpAffine(img,M,(W,H)) ##M为上面两种方式求的矩阵
cv2.imshow("ori",img)
cv2.imshow("out",warpimg)
cv2.waitKey(0)
矩阵1:缩放
矩阵2:旋转30度