zoukankan      html  css  js  c++  java
  • 【图像处理:平移,缩放,旋转等】仿射变换过程与仿射变换矩阵

    遇到了一些情况需要将图片旋转一定角度使其相对来说是符合人类认知的形式【就是歪图转正】于是接触了处理图片的经典方式——仿射变换

    定义:仿射变换的功能是从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的原子变换的复合来实现,包括平移,缩放,翻转,旋转和剪切。

    1)图像的几何变换

    对图像进行放大、缩小、旋转等操作,会改变原图中各区域的空间关系,这类操作就是图像的几何变换。

    2)仿射变换

    对原来的x和y坐标分别进行线性的几何变换,得到新的x和y,这种变换就是放射变换。

    3)投影变换

    4)极坐标变换

    5)齐次坐标

    在原坐标的基础上,引入第三个数值为1的坐标,这种表示方法就是齐次坐标。

    6)仿射变换矩阵

    仿射变换矩阵的最后一行均为(0,0,1)此形式,最后一个值为1。


    平移(translation)旋转(rotation) 顾名思义,两者的组合称之为 欧式变换(Euclidean transformation)刚体变换(rigid transformation)

    放缩(scaling) 可进一步分为 uniform scalingnon-uniform scaling,前者每个坐标轴放缩系数相同(各向同性),后者不同;如果放缩系数为负,则会叠加上反射(reflection)——可以看成是特殊的scaling;

    刚体变换+uniform scaling 称之为,相似变换(similarity transformation),即平移+旋转+各向同性的放缩;

    剪切变换(shear mapping) 将所有点沿某一指定方向成比例地平移

    上图
    在这里插入图片描述
    这张图就是被各大博客,知乎精华所引用的仿射变换的

    简单来说,图像的本质可以看做一个三维矩阵,第一维为长度,第二维是宽度,第三维是通道数(RGB),如果一张图在python中是一个变量image,那么其长宽即width, height = image.shape[:2],即前两维度的表示方法。

    对于图像矩阵中的每一个像素坐标(x,y),我们可以令其乘上一个矩阵,使所有像素坐标平移,旋转,缩放,翻转到处理后的图像新坐标上

    对于每种操作的矩阵构造如下:
    在这里插入图片描述
    以下是对单一变换时所做的矩阵操作
    在这里插入图片描述
    要知道,计算机中往往左上角是坐标原点,图片的高度(width)是X轴,宽度(height)是Y轴,因此当以原点为圆心顺时针旋转90°为例,我们将把图旋转出第一象限,此时需要将图片向Y轴方向平移原图的高度(width)才能回到第一象限:
    在这里插入图片描述
    这样的复合操作其实是多个矩阵相乘的结果
    在这里插入图片描述
    分解后是多个单独的操作

    以(0,0)为中心进行放大和缩小

    这里的放大和缩小不是指在物理空间中某一物体的放大和缩小。

    二维空间坐标(x, y)以(0,0)为中心,在水平上缩放Sx倍,指的是变换后的坐标位置(x’,y’)离(0,0)的水平距离变为原坐标(x,y)离位置中心点的水平距离的Sx倍;在垂直方向上缩放Sy倍,指的是变换后的坐标位置(x’,y’)离(0,0)的垂直距离为原坐标(x,y)离位置中心的垂直距离的Sy倍。

    用数学公式表示,(x’, 'y) = (Sx * x, Sy * y)

    如果Sx>1,则表示在水平方向上放大;如果0<Sx<1,则表示在水平方向上缩小。

    如果Sy>1,则表示在垂直方向上放大;如果0<Sy<1,则表示在垂直方向上缩小。


    假设已知参数是图片本体,我们可以自己构造一个需要的仿射变换矩阵,做自定义操作。
    如顺时针旋转90°:

    width, height = img.shape[:2]
    transform = np.matrix(
          [[1, 0, 0], [0, 1, width], [0, 0, 1]], dtype='float')
      transform *= np.matrix(
          [
              [np.cos(np.pi / 2), np.sin(np.pi / 2), 0],
              [-np.sin(np.pi / 2), np.cos(np.pi / 2), 0], [0, 0, 1]
          ],
          dtype='float')
      transform = np.linalg.inv(transform)
      img = cv2.warpAffine(img, transform[:2], (width, height))
    

    以(x0,y0)为中心的放大和缩小

    以(0,0)为中心的放大和缩小,很容易理解。而以(x0,y0)为中心的放大和缩小,直接来理解比较苦难。但是可以用分解步骤的思想来进行理解,可以变得简单一些。

    以(x0,y0)为中心的缩放(x,y)=先将原点(0,0)移动到中心点(x0,y0)—>以新原点为中心点进行缩放—>然后再移回坐标原点。

    等比例缩放

    在上面放大和缩小的公式中,如果Sx==Sy,则表示是等比例缩放。


    吐槽一下自己,突然意识到自己从秋招回学校之后就开始浪了,再也懒得写博客了,虽然零零散散接触了些新东西,但是没有系统的学过,也不好将皮毛整理成博客。接下来是正经的学习期,以及毕设的准备与实践采坑,,,新的开始,忘掉过去,要写一些更实用的博客了。

  • 相关阅读:
    移动端的头文件
    时间倒计时
    H5 判断应用是否打开或是下载
    创建 XMLHttpRequest 对象
    JS 发送POST
    总结题
    uploadify 插件,去了进度条
    PC 拖动 以百分比计算
    pc 拖动效果,拖动带范围
    spring.net 在demo中的分析
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/12392103.html
Copyright © 2011-2022 走看看