一文搞懂仿射变换的原理和应用

导读

在图像处理中,我们经常需要对图像进行各种操作如

平移缩放旋转翻转等,这些操作都属于图像的仿射变换,我们通过一个变换矩阵就能很容易的实现。本篇文章详细的介绍了各种操作的实现原理,以及代码的实现和使用

仿射变换

仿射变换也称仿射投影,是指几何中,对一个向量空间进行线性变换并接上一个平移,变换为另一个向量空间。所以,仿射变换其实也就是在讲如何来进行两个向量空间的变换

假设有一个向量空间k:

一文搞懂仿射变换的原理和应用

向量空间k

和另一个向量空间j:

一文搞懂仿射变换的原理和应用

向量空间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的索引来实现,当然也可以通过仿射变换矩阵来实现这个功能

一文搞懂仿射变换的原理和应用

上图中的ABCD表示图像的四个顶点,如果我们需要对图像进行水平翻转,那么我们就需要将A点和B点进行交换,C点和D点进行交换,沿着x轴的中线进行对称交换位置,通过下面的式子可以实现水平翻转

一文搞懂仿射变换的原理和应用

水平翻转

上式中的w表示图像的宽,同理可得垂直翻转的实现公式

一文搞懂仿射变换的原理和应用

垂直翻转

上式中的h表示的是图像的高

  • 利用变换矩阵翻转图像

水平翻转的变换矩阵M:

一文搞懂仿射变换的原理和应用

仿射变换水平翻转矩阵

垂直翻转的变换矩阵M:

一文搞懂仿射变换的原理和应用

仿射变换垂直翻转矩阵

镜像翻转的变换矩阵M:

一文搞懂仿射变换的原理和应用

仿射变换镜像翻转矩阵


一文搞懂仿射变换的原理和应用

仿射变换实现图像的镜像翻转


一文搞懂仿射变换的原理和应用

镜像翻转

  • OpenCV的flip函数翻转图像

flip函数参数:

  • src:输入的图像数组
  • flipCode:图像翻转参数,1表示水平翻转,0表示垂直翻转,-1表示镜像翻转
一文搞懂仿射变换的原理和应用

flip函数实现图像翻转

  • numpy的索引翻转图像
一文搞懂仿射变换的原理和应用

numpy通过索引数组实现图像翻转

图像缩放

如果我们想要对坐标系的P点进行缩放操作,通过下面的公式就可以实现

一文搞懂仿射变换的原理和应用

图像缩放

通过在x和y前面添加一个缩放系数即可,同样我们将其转换为矩阵形式

一文搞懂仿射变换的原理和应用

图像缩放的矩阵形式

通过上面的矩阵M我们就可以实现对图片的缩放

一文搞懂仿射变换的原理和应用

仿射变换实现图像缩放


一文搞懂仿射变换的原理和应用

仿射变换实现图像缩放

这里使用仿射变换实现的图片缩放其实和resize函数的效果是一样的,缩放时选择的插值函数不同最终效果会有所偏差

图像旋转

  • 围绕原点旋转

我们先来看看一个二维平面上的点在围绕原点是如何旋转的

一文搞懂仿射变换的原理和应用

任意一点围绕原点旋转

上图中点v围绕原点旋转θ度

之后得到了点v′,我们将坐标点用极坐标的形式来表示可以得到v(rcosϕ,rsinϕ),所以v′(rcos(θ+ϕ),rsin(θ+ϕ))利用正弦和余弦展开式将其展开可得,对于v点来说:

一文搞懂仿射变换的原理和应用

v点坐标展开式

对于v′来说:

一文搞懂仿射变换的原理和应用

v'点坐标展开式

然后我们再将x和y代入上式可得

一文搞懂仿射变换的原理和应用

变换后的x和y的坐标

然后再将上式用矩阵M表示,可得

一文搞懂仿射变换的原理和应用

旋转后坐标的矩阵表示形式

特别注意:我们在建立直角坐标系的时候是以左下角为原点建立的,然而对于图像而言是以左上角为原点

建立的,所以我们需要对角度θ进行取反,结合三角函数的特性,M矩阵的表达式如下

一文搞懂仿射变换的原理和应用

围绕原点旋转的仿射变换矩阵

还需要注意的是这里的角度都是弧度制,所以我们在使用的时候还需要对其进行转换,转换代码如下

<code>#将角度转换为弧度制
radian_theta = theta/180 * np.pi#np.pi指的是π/<code>

将图片围绕原点进行逆时针旋转θ度的代码如下


一文搞懂仿射变换的原理和应用

将图像围绕原点旋转

  • 围绕任意点旋转

如果我们想围绕任意坐标点旋转呢?其实也并不难,下图的v点在围绕c点(a,b)旋转90度得到v′

。其实我们可以将其等价于,先将V点平移到V1点,然后再将V1点围绕原点旋转90度得到V2点,最后再将V2点沿着V点平移的反方向平移相同长度,最终得到V'。这样我们就将围绕任意坐标点旋转的问题转换成了围绕原点旋转的问题

一文搞懂仿射变换的原理和应用

我们来回顾一下,围绕原点旋转坐标的变换公式

一文搞懂仿射变换的原理和应用

围绕原点旋转

在围绕原点旋转变换公式的基础上,我们将其改进为围绕任意点c(a,b)旋转,我们现在原来的坐标进行平移,得到变换后的坐标,最后再沿着之前平移的反方向进行平移,就得到围绕任意点旋转的变换公式

一文搞懂仿射变换的原理和应用

围绕任意点旋转

将其展开可得

一文搞懂仿射变换的原理和应用

围绕任意点旋转的展开式

将上式用矩阵M表示:

一文搞懂仿射变换的原理和应用

矩阵形式表示围绕点c进行旋转

上式中的c(a,b)表示旋转中心,因为坐标系问题需要对θ进行取反,最终M矩阵的表达式如下

一文搞懂仿射变换的原理和应用

旋转矩阵


一文搞懂仿射变换的原理和应用

围绕图像中心旋转图像

一文搞懂仿射变换的原理和应用

围绕图像中心旋转图像

细心的同学也许已经发现了,上图中围绕图像中心旋转后的图片部分被裁剪掉了,如果我们想让旋转之后的图片仍然是完整,应该如何修改呢?


一文搞懂仿射变换的原理和应用

围绕图像中心旋转后仍保持完整


一文搞懂仿射变换的原理和应用


分享到:


相關文章: