声明:此文章主要参考两位大佬的博客,参考文章在文末。
文章目录
平移变换缩放变换旋转变换绕X轴旋转绕Y轴旋转绕Z轴旋转绕坐标轴旋转的矩阵推导逆矩阵代码实战1.平移2.缩放3.旋转参考文章本文介绍图像三种主要的几何变换:平移、缩放、旋转。
平移变换
将三维空间中的一个点 [x,y,z,1][x, y, z, 1][x,y,z,1] 移动到另外一个点 [x′,y′,z′,1][x', y', z', 1][x′,y′,z′,1] ,三个坐标轴的移动分量分别为 dx=Tx,dy=Ty,dz=Tzdx=Tx, dy=Ty, dz=Tzdx=Tx,dy=Ty,dz=Tz , 即
x′=x+Txx' = x + Txx′=x+Tx
y′=y+Tyy' = y + Tyy′=y+Ty
z′=z+Tzz' = z + Tzz′=z+Tz
平移变换的矩阵如下:
[x′,y′,z′,1]=[x,y,z,1]∗A[x^{'},y^{'},z^{'},1]=[x,y,z,1]*A[x′,y′,z′,1]=[x,y,z,1]∗A
A=(100001000010TxTyTz0)A = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0\\ T_x & T_y & T_z & 0\\ \end{pmatrix}A=⎝⎜⎜⎛100Tx010Ty001Tz0000⎠⎟⎟⎞
缩放变换
将模型放大或者缩小,本质也是对模型上每个顶点进行放大和缩小(顶点坐标值变大或变小),假设变换前的点是[x,y,z,1][x, y, z, 1][x,y,z,1],变换后的点是[x′,y′,z′,1][x', y', z', 1][x′,y′,z′,1],那么
x′=x∗Sxx' = x * S_xx′=x∗Sx
y′=y∗Syy' = y * S_yy′=y∗Sy
z′=z∗Szz' = z * S_zz′=z∗Sz
缩放变换的矩阵如下:
[x′,y′,z′,1]=[x,y,z,1]∗B[x^{'},y^{'},z^{'},1]=[x,y,z,1]*B[x′,y′,z′,1]=[x,y,z,1]∗B
B=(Sx0000Sx0000Sx00001)B = \begin{pmatrix} S_x & 0 & 0 & 0 \\ 0 & S_x & 0 & 0 \\ 0 & 0 & S_x & 0\\ 0 & 0 & 0 & 1 \\ \end{pmatrix}B=⎝⎜⎜⎛Sx0000Sx0000Sx00001⎠⎟⎟⎞
旋转变换
绕X轴旋转
旋转的正方向为顺时针方向。
绕X轴旋转变换的矩阵如下:
[x′,y′,z′,1]=[x,y,z,1]∗C1[x^{'},y^{'},z^{'},1]=[x,y,z,1]*C_1[x′,y′,z′,1]=[x,y,z,1]∗C1
C1=(10000cosθsinθ00−sinθcosθ00001)C_1 = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & \sin\theta & 0 \\ 0 & -\sin\theta & \cos\theta & 0\\ 0 & 0 & 0 & 1 \\ \end{pmatrix}C1=⎝⎜⎜⎛10000cosθ−sinθ00sinθcosθ00001⎠⎟⎟⎞
绕Y轴旋转
绕Y轴旋转变换的矩阵如下:
[x′,y′,z′,1]=[x,y,z,1]∗C2[x^{'},y^{'},z^{'},1]=[x,y,z,1]*C_2[x′,y′,z′,1]=[x,y,z,1]∗C2
C2=(cosθ0−sinθ00100sinθ0cosθ00001)C_2 = \begin{pmatrix} \cos\theta & 0 & -\sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ \sin\theta & 0 & \cos\theta & 0\\ 0 & 0 & 0 & 1 \\ \end{pmatrix}C2=⎝⎜⎜⎛cosθ0sinθ00100−sinθ0cosθ00001⎠⎟⎟⎞
绕Z轴旋转
绕Z轴旋转变换的矩阵如下:
[x′,y′,z′,1]=[x,y,z,1]∗C3[x^{'},y^{'},z^{'},1]=[x,y,z,1]*C_3[x′,y′,z′,1]=[x,y,z,1]∗C3
C3=(cosθsinθ00−sinθcosθ0000100001)C_3 = \begin{pmatrix} \cos\theta & \sin\theta & 0 & 0 \\ -\sin\theta & \cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \\ \end{pmatrix}C3=⎝⎜⎜⎛cosθ−sinθ00sinθcosθ0000100001⎠⎟⎟⎞
绕坐标轴旋转的矩阵推导
上面三种绕坐标轴旋转的情况属于特殊的二维旋转,比如绕Z轴旋转,相当于在与XOYXOYXOY平面上绕原点做二维旋转。
假设点P(x,y)P(x, y)P(x,y)是平面直角坐标系内一点,其到原点的距离为rrr,其与XXX轴的夹角为AAA,现将点PPP绕原点旋转θθθ度,得到点P′(x′,y′)P'(x', y')P′(x′,y′),P′P'P′与XXX轴的夹角为BBB,则A=B−θA = B - θA=B−θ。(注意,在二维坐标中,逆时针旋转时角度为正,顺时针旋转时角度为负,下图中由PPP旋转到P′P'P′,角度为θθθ,若是由P′P'P′转到PPP,则角度为−θ-θ−θ)。
得到下面的转换方程:
写成矩阵的形式:
求得旋转矩阵:
由于这里使用齐次坐标,所以还需加上一维,最终变成如下形式:
(绕Z轴旋转变换矩阵)
对于绕X轴旋转的情况,我们只需将式一中的x用y替换,y用z替换,z用x替换即可:
(绕X轴旋转变换矩阵)
(绕Y轴旋转变换矩阵)
逆矩阵
平移变换矩阵的逆矩阵与原来的平移量相同,但是方向相反:
旋转变换矩阵的逆矩阵与原来的旋转轴相同但是角度相反:
![在这里插入图片描述](https://img-/170641358.pn
g?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMzE3MjA0,size_16,color_FFFFFF,t_70)缩放变换的逆矩阵正好和原来的效果相反,如果原来是放大,则逆矩阵是缩小,如果原来是缩小,则逆矩阵是放大:
代码实战
1.平移
图像平移:设(x0, y0)是缩放后的坐标,(x, y)是缩放前的坐标,dx、dy为偏移量,则公式如下:
图像平移首先定义平移矩阵M,再调用warpAffine()函数实现平移,核心函数如下:
M = np.float32([[1, 0, x], [0, 1, y]]) shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
(注:M作为仿射变换矩阵,一般反映平移或旋转的关系,为InputArray类型的2×3的变换矩阵)
cv2.imread()和cv2.cvtColor() 的使用
cv2.warpAffine 参数详解
import cv2import numpy as np# 读取图片img = cv2.imread('my goddess zhang.jpg')image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)# 图像平移 下、上、右、左平移M = np.float32([[1, 0, 0], [0, 1, 100]])img1 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))M = np.float32([[1, 0, 0], [0, 1, -100]])img2 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))M = np.float32([[1, 0, 100], [0, 1, 0]])img3 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))M = np.float32([[1, 0, -100], [0, 1, 0]])img4 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))# 显示图形cv2.imshow('original', image)cv2.imshow('down', img1)cv2.imshow('up', img2)cv2.imshow('right', img3)cv2.imshow('left', img4)cv2.waitKey(0)cv2.destroyAllWindows()
结果如下:
2.缩放
图像缩放主要调用resize()函数实现:
result = cv2.resize(src, dsize[, result[. fx[, fy[, interpolation]]]])
其中src表示原始图像,dsize表示缩放大小,fx和fy也可以表示缩放大小倍数,他们两个(dsize或fx\fy)设置一个即可实现图像缩放。
如:
方法1. result = cv2.resize(src, (160,160))
方法2. result = cv2.resize(src, None, fx=0.5, fy=0.5)
图像缩放:设(x0,y0)(x0, y0)(x0,y0)是缩放后的坐标,(x,y)(x, y)(x,y)是缩放前的坐标,sxsxsx、sysysy为缩放因子,则公式如下:
方法一:
import cv2# 读取图片src = cv2.imread('my goddess zhang.jpg')# 图像缩放result = cv2.resize(src, (200, 300))print(result.shape)# 显示图像cv2.imshow("src", src)cv2.imshow("result", result)# 等待显示cv2.waitKey(0)cv2.destroyAllWindows()
方法二:
import cv2import numpy as np# 读取图片src = cv2.imread('my goddess zhang.jpg')rows, cols = src.shape[:2]print(rows, cols)# 图像缩放 dsize(列,行)result = cv2.resize(src, (int(cols * 0.6), int(rows * 1.2)))# 显示图像cv2.imshow("src", src)cv2.imshow("result", result)# 等待显示cv2.waitKey(0)cv2.destroyAllWindows()
import cv2# 读取图片src = cv2.imread('my goddess zhang.jpg')rows, cols = src.shape[:2]print(rows, cols)# 图像缩放result = cv2.resize(src, None, fx=1.5, fy=1.5)# 显示图像cv2.imshow("src", src)cv2.imshow("result", result)# 等待显示cv2.waitKey(0)cv2.destroyAllWindows()
3.旋转
图像旋转主要调用getRotationMatrix2D()函数和warpAffine()函数实现,绕图像的中心旋转,具体如下:
M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1)
参数分别为:旋转中心、旋转度数、scale
rotated = cv2.warpAffine(src, M, (cols, rows))
参数分别为:原始图像、旋转参数、原始图像宽高
图像旋转:设(x0, y0)是旋转后的坐标,(x, y)是旋转前的坐标,(m,n)是旋转中心,a是旋转的角度,(left,top)是旋转后图像的左上角坐标,则公式如下:
import cv2# 读取图片src = cv2.imread('my goddess zhang.jpg')# 原图的高、宽 以及通道数rows, cols, channel = src.shape# 绕图像的中心旋转# 参数:旋转中心 旋转度数 scaleM1 = cv2.getRotationMatrix2D((cols / 2, rows / 2), 30, 1)M2 = cv2.getRotationMatrix2D((cols / 2, rows / 2), -60, 1)# 参数:原始图像 旋转参数 元素图像宽高rotated1 = cv2.warpAffine(src, M1, (cols, rows))rotated2 = cv2.warpAffine(src, M2, (cols, rows))# 显示图像cv2.imshow("src", src)# cv2.imshow("rotated", rotated1)cv2.imshow("rotated", rotated2)# 等待显示cv2.waitKey(0)cv2.destroyAllWindows()
参考文章
/zhengxiuchen86/article/details/81951608
/Eastmount/article/details/82454335?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-3