一文搞懂仿射变换的原理和应用
connygpt 2024-12-09 11:43 11 浏览
导读
在图像处理中,我们经常需要对图像进行各种操作如平移、缩放、旋转、翻转等,这些操作都属于图像的仿射变换,我们通过一个变换矩阵就能很容易的实现。本篇文章详细的介绍了各种操作的实现原理,以及代码的实现和使用
仿射变换
仿射变换也称仿射投影,是指几何中,对一个向量空间进行线性变换并接上一个平移,变换为另一个向量空间。所以,仿射变换其实也就是在讲如何来进行两个向量空间的变换
假设有一个向量空间k:
和另一个向量空间j:
如果我们想要将向量空间由k变为j,可以通过下面的公式来实现:
将上式进行拆分可得
我们再将上式转换为矩阵的乘法
上式表明通过一个两行三列的矩阵M就可以实现两个向量空间之间的转换,在进行仿射变换的时候我们也只需要一个矩阵M就可以实现图像的平移、缩放、旋转和翻转变换。
接下来,会先介绍原理然后利用OpenCV来实现相应的例子,这里主要利用OpenCV的warpAffine函数来实现仿射变换
warpAffine函数参数:
- src:输入的图像数组
- M:仿射变换矩阵
- dsize:变换后图像的大小
- flags:使用的插值算法
- borderValue:边界的填充值
图像平移
在平面坐标系有点P(x,y)和点P′(x′,y′),如果我们想要将P点移动到P′通过下面的变换就可以实现
其中Δx和Δy就是x方向上和y方向上的偏移量,我们将其转换为矩阵的形式上面的矩阵MM就是仿射变换的平移参数,接下来我们利用OpenCV中的warpAffine函数来实现
上面的矩阵M就是仿射变换的平移参数,接下来我们利用OpenCV中的warpAffine函数来实现图像的平移
图像翻转
有时候我们我们需要对图像进行水平翻转、垂直翻转、镜像翻转(同时进行水平和垂直翻转),想要实现这个功能并不难,我们可以通过opencv内置的flip方法很容易实现,还可以通过numpy的索引来实现,当然也可以通过仿射变换矩阵来实现这个功能
上图中的A、B、C、D表示图像的四个顶点,如果我们需要对图像进行水平翻转,那么我们就需要将A点和B点进行交换,C点和D点进行交换,沿着x轴的中线进行对称交换位置,通过下面的式子可以实现水平翻转
上式中的w表示图像的宽,同理可得垂直翻转的实现公式
上式中的h表示的是图像的高
- 利用变换矩阵翻转图像
水平翻转的变换矩阵M:
垂直翻转的变换矩阵M:
镜像翻转的变换矩阵M:
- OpenCV的flip函数翻转图像
flip函数参数:
- src:输入的图像数组
- flipCode:图像翻转参数,1表示水平翻转,0表示垂直翻转,-1表示镜像翻转
- numpy的索引翻转图像
图像缩放
如果我们想要对坐标系的P点进行缩放操作,通过下面的公式就可以实现
通过在x和y前面添加一个缩放系数即可,同样我们将其转换为矩阵形式
通过上面的矩阵M我们就可以实现对图片的缩放
这里使用仿射变换实现的图片缩放其实和resize函数的效果是一样的,缩放时选择的插值函数不同最终效果会有所偏差
图像旋转
- 围绕原点旋转
我们先来看看一个二维平面上的点在围绕原点是如何旋转的
上图中点v在围绕原点旋转θ度之后得到了点v′,我们将坐标点用极坐标的形式来表示可以得到v(rcos?,rsin?),所以v′(rcos(θ+?),rsin(θ+?))利用正弦和余弦展开式将其展开可得,对于v点来说:
对于v′来说:
然后我们再将x和y代入上式可得
然后再将上式用矩阵M表示,可得
特别注意:我们在建立直角坐标系的时候是以左下角为原点建立的,然而对于图像而言是以左上角为原点建立的,所以我们需要对角度θ进行取反,结合三角函数的特性,M矩阵的表达式如下
还需要注意的是这里的角度都是弧度制,所以我们在使用的时候还需要对其进行转换,转换代码如下
#将角度转换为弧度制
radian_theta = theta/180 * np.pi#np.pi指的是π
将图片围绕原点进行逆时针旋转θ度的代码如下
- 围绕任意点旋转
如果我们想围绕任意坐标点旋转呢?其实也并不难,下图的v点在围绕c点(a,b)旋转90度得到v′。其实我们可以将其等价于,先将V点平移到V1点,然后再将V1点围绕原点旋转90度得到V2点,最后再将V2点沿着V点平移的反方向平移相同长度,最终得到V'。这样我们就将围绕任意坐标点旋转的问题转换成了围绕原点旋转的问题
我们来回顾一下,围绕原点旋转坐标的变换公式
在围绕原点旋转变换公式的基础上,我们将其改进为围绕任意点c(a,b)旋转,我们现在原来的坐标进行平移,得到变换后的坐标,最后再沿着之前平移的反方向进行平移,就得到围绕任意点旋转的变换公式
将其展开可得
将上式用矩阵M表示:
上式中的c(a,b)表示旋转中心,因为坐标系问题需要对θ进行取反,最终M矩阵的表达式如下
细心的同学也许已经发现了,上图中围绕图像中心旋转后的图片部分被裁剪掉了,如果我们想让旋转之后的图片仍然是完整,应该如何修改呢?
相关推荐
- 自学Python,写一个挨打的游戏代码来初识While循环
-
自学Python的第11天。旋转~跳跃~,我~闭着眼!学完循环,沐浴着while的光芒,闲来无事和同事一起扯皮,我说:“编程语言好神奇,一个小小的循环,竟然在生活中也可以找到原理和例子”,同事也...
- 常用的 Python 工具与资源,你知道几个?
-
最近几年你会发现,越来越多的人开始学习Python,工欲善其事必先利其器,今天纬软小编就跟大家分享一些常用的Python工具与资源,记得收藏哦!不然下次就找不到我了。1、PycharmPychar...
- 一张思维导图概括Python的基本语法, 一周的学习成果都在里面了
-
一周总结不知不觉已经自学Python一周的时间了,这一周,从认识Python到安装Python,再到基本语法和基本数据类型,对于小白的我来说无比艰辛的,充满坎坷。最主要的是每天学习时间有限。只...
- 三日速成python?打工人,小心钱包,别当韭菜
-
随着人工智能的热度越来越高,许多非计算机专业的同学们也都纷纷投入到学习编程的道路上来。而Python,作为一种相对比较容易上手的语言,也越来越受欢迎。网络上各类网课层出不穷,各式广告令人眼花缭乱。某些...
- Python自动化软件测试怎么学?路线和方法都在这里了
-
Python自动化测试是指使用Python编程语言和相关工具,对软件系统进行自动化测试的过程。学习Python自动化测试需要掌握以下技术:Python编程语言:学习Python自动化测试需要先掌握Py...
- Python从放弃到入门:公众号历史文章爬取为例谈快速学习技能
-
这篇文章不谈江流所专研的营销与运营,而聊一聊技能学习之路,聊一聊Python这门最简单的编程语言该如何学习,我完成的第一个Python项目,将任意公众号的所有历史文章导出成PDF电子书。或许我这个Py...
- 【黑客必会】python学习计划
-
阅读Python文档从Python官方网站上下载并阅读Python最新版本的文档(中文版),这是学习Python的最好方式。对于每个新概念和想法,请尝试运行一些代码片段,并检查生成的输出。这将帮助您更...
- 公布了!2025CDA考试安排
-
CDA数据分析师报考流程数据分析师是指在不同行业中专门从事行业数据搜集、整理、分析依据数据作出行业研究评估的专业人员CDA证书分为1-3级,中英文双证就业面广,含金量高!!?报考条件:满18...
- 一文搞懂全排列、组合、子集问题(经典回溯递归)
-
原创公众号:【bigsai】头条号:程序员bigsai前言Hello,大家好,我是bigsai,longtimenosee!在刷题和面试过程中,我们经常遇到一些排列组合类的问题,而全排列、组合...
- 「西法带你学算法」一次搞定前缀和
-
我花了几天时间,从力扣中精选了五道相同思想的题目,来帮助大家解套,如果觉得文章对你有用,记得点赞分享,让我看到你的认可,有动力继续做下去。467.环绕字符串中唯一的子字符串[1](中等)795.区...
- 平均数的5种方法,你用过几种方法?
-
平均数,看似很简单的东西,其实里面包含着很多学问。今天,分享5种经常会用到的平均数方法。1.算术平均法用到最多的莫过于算术平均法,考试平均分、平均工资等等,都是用到这个。=AVERAGE(B2:B11...
- 【干货收藏】如何最简单、通俗地理解决策树分类算法?
-
决策树(Decisiontree)是基于已知各种情况(特征取值)的基础上,通过构建树型决策结构来进行分析的一种方式,是常用的有监督的分类算法。决策树算法是机器学习中的一种经典算法,它通过一系列的规则...
- 面试必备:回溯算法详解
-
我们刷leetcode的时候,经常会遇到回溯算法类型题目。回溯算法是五大基本算法之一,一般大厂也喜欢问。今天跟大家一起来学习回溯算法的套路,文章如果有不正确的地方,欢迎大家指出哈,感谢感谢~什么是回溯...
- 「机器学习」决策树——ID3、C4.5、CART(非常详细)
-
决策树是一个非常常见并且优秀的机器学习算法,它易于理解、可解释性强,其可作为分类算法,也可用于回归模型。本文将分三篇介绍决策树,第一篇介绍基本树(包括ID3、C4.5、CART),第二篇介绍Ran...
- 大话AI算法: 决策树
-
所谓的决策树算法,通俗的说就是建立一个树形的结构,通过这个结构去一层一层的筛选判断问题是否好坏的算法。比如判断一个西瓜是否好瓜,有20条西瓜的样本提供给你,让你根据这20条(通过机器学习)建立起...
- 一周热门
- 最近发表
- 标签列表
-
- kubectlsetimage (56)
- mysqlinsertoverwrite (53)
- addcolumn (54)
- helmpackage (54)
- varchar最长多少 (61)
- 类型断言 (53)
- protoc安装 (56)
- jdk20安装教程 (60)
- rpm2cpio (52)
- 控制台打印 (63)
- 401unauthorized (51)
- vuexstore (68)
- druiddatasource (60)
- 企业微信开发文档 (51)
- rendertexture (51)
- speedphp (52)
- gitcommit-am (68)
- bashecho (64)
- str_to_date函数 (58)
- yum下载包及依赖到本地 (72)
- jstree中文api文档 (59)
- mvnw文件 (58)
- rancher安装 (63)
- nginx开机自启 (53)
- .netcore教程 (53)