几何变换详解:平移、缩放、旋转
声明:此文章主要参考两位大佬的博客,参考文章在文末。
文章目录
- 平移变换
- 缩放变换
- 旋转变换
- 绕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-blog.csdnimg.cn/20200423170641358.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 cv2
import 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 cv2
import 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# 绕图像的中心旋转
# 参数:旋转中心 旋转度数 scale
M1 = 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()
参考文章
https://blog.csdn.net/zhengxiuchen86/article/details/81951608
https://blog.csdn.net/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
几何变换详解:平移、缩放、旋转相关推荐
- [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)
欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...
- css3transform rotate,CSS3详解:transform [旋转rotate、扭曲skew、缩放scale和移动translate以及矩阵变形matrix]...
CSS3详解:transform [旋转rotate.扭曲skew.缩放scale和移动translate以及矩阵变形matrix] transform的属性包括:rotate() / skew() ...
- qgraphicsview鼠标移动图片_交互式QGraphicsView(平移/缩放/旋转)-阿里云开发者社区...
简述 Graphics View提供了一个平台用于大量自定义 2D 图元的管理与交互框架包括一个事件传播架构支持场景 Scene 中的图元 Item 进行精确的双精度交互功能.Item 可以处理键盘事 ...
- html旋转角度计算,CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate) | 0101后花园...
CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate) | 0101后花园 2018-09-26 在CSS3中,可以利用transfor ...
- 【数字图像处理】图像的几何变换之 图形平移与旋转
(一)基础知识 (1)常见图片几何运算 图像的几何变换主要就是一下这些. 这里只是一些最简单的函数处理 ·图像的平移变换 ·图像的镜像变换 ·图像的转置变换 ·图像的旋转变换 ·图像的缩放 这里我主要 ...
- 补间动画详解五 缩放动画ScaleAnimation
ScaleAnimation是尺寸变化动画的类,控制View的尺寸变化. ScaleAnimation类官方文档: https://developer.android.com/reference/an ...
- [Python图像处理] 三十六.OpenCV图像几何变换万字详解(平移缩放旋转、镜像仿射透视)
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...
- WebGL—点精灵PointSprite详解: 纹理映射,旋转,缩放,移动
第一,什么是点精灵 openGL的图形由顶点构成,以后利用顶点进行纹理的映射.点精灵就是,一个顶点被当作一个精灵来处理.特别之处就是,一个顶点也可进行纹理贴出.例如,原来是个顶点构成的一个矩形,现在一 ...
- OpenGL点精灵PointSprite详解: 纹理映射,旋转,缩放,移动
第一,什么是点精灵 openGL的图形由顶点构成,以后利用顶点进行纹理的映射.点精灵就是,一个顶点被当作一个精灵来处理.特别之处就是,一个顶点也可进行纹理贴出.例如,原来是个顶点构成的一个矩形,现在一 ...
最新文章
- 电脑电视兼容成科技行业新课题
- 01:初识Redis
- 为什么生产环境都是linux,关于生产环境linux系统中的wheel用户组
- 《超越需求:敏捷思维模式下的分析》—第1章 1.1节简介
- Android11vivox21刷机包,vivo x21旧版官方固件rom系统刷机包
- MySQL in 查询,并通过 FIELD 函数按照查询条件顺序返回结果
- Servlet 转发与重定向
- 北京互联网地域歧视链
- python 大智慧自定义数据_大智慧自定义指数
- MATLAB 字符串与矩阵的学习
- Word中无法插入公式的解决方案
- 多种方法教你如何让手机免费上网
- Mac下移动硬盘的使用
- FPGA读取ADXL345
- 0xc0000225无法进系统_Win10无法开机0xc0000225错误代码解决方法
- get请求 params参数传递以及获取
- 记录nodejs使用express搭建一个api服务器程序(5)-nodejs操作SQL数据库,Sequelize和Knex
- reference_line_provider
- MATLAB教室人数统计开源代码(包含 GUI 注释 课题分析)
- 如果只定一个指标,市场运营的考核指标应该是什么?