CV — 数据增强:仿射变换

本文介绍了仿射变换的概念及其在图像处理中的应用,包括平移、翻转、缩放、旋转和裁剪等。通过OpenCV的warpAffine和warpPerspective函数,详细展示了如何在Python中实现这些变换,以增强深度学习的数据集。
摘要由CSDN通过智能技术生成

CV — 数据增强:仿射变换

一、前言

(一) 仿射变换概念

  1. 前言:
    在深度学习的数据增强中,我们经常需要对图像进行各种增强操作如:平移、翻转(flip)、缩放(Scale)、旋转(Rotation)、裁剪(Shear) 等,这些其实都是 图像的仿射变换
    待确认:对比度,色彩抖动,噪声

  2. 仿射变换原理:

    • 维基百科定义:
      仿射变换(Affine transformation),又称 仿射映射,是指在 几何 中,对一个 向量空间 进行一次 线性变换 并接上一个 平移,变换为另一个向量空间。

      简单来说,“仿射变换” 就是:“线性变换” + “平移”。

    • 示例:

      假设有一个向量空间 k:k = (x, y),还有一个向量空间 j:j = (x’, y’),可以通过仿射变换来将 j 变换成 k。

      步骤如下:

      • 令:j = w * k + b,
        分解式:x’ = w00 * x + w01 * y + b0,y’ = w10 * x + w11 * y + b1
      • 转换为矩阵的乘法:
        在这里插入图片描述
        通过 参数矩阵M 就可以实现两个向量空间之间的转换。
    • 总结:
      在进行仿射变换的时候我们也只需要一个矩阵M就可以实现平移、缩放、旋转和翻转等变换。

      仿射变换是一种二维坐标到二维坐标之间的线性变换,它保持了二维图形的 “平直性”(直线经过变换之后依然是直线)和 “平行性”(二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。任意的仿射变换 都能表示为乘以一个矩阵(线性变换),再加上一个向量 (平移) 的形式.

(二) 仿射变换矩阵

  1. 平移:

    # x向左平移(负数向左,正数向右) dx 个像素
    # y向下平移(负数向上,正数向下) dy 个像素
    M = [[1, 0, dx],
         [0, 1, dy]]
    

    在这里插入图片描述

  2. 翻转(flip):

    # 水平翻转
    M = [[-1, 0, w],
         [0, 1, 0]]
    
    # 垂直翻转
    M = [[1, 0, 0],
         [0, -1, h]]
    

    在这里插入图片描述

  3. 缩放(Scale):

    # fx,fy:宽高缩放的倍数
    M = [[fx, 0, 0],
         [0, fy, 0]])
    

    在这里插入图片描述

  4. 旋转(Rotation):

    # 以原点为中心旋转
    # d:要转化为弧度制,d = 角度a * pi / 180
    M = [[cosd, -sind, 0],
         [sind, cosd, 0]]
    

    在这里插入图片描述

  5. 裁剪(Shear):

    # a,b:要转化为弧度制,角度 * pi / 180
    # 仅 x 坐标剪切
    M = [[1, tan(a), 0],
         [0, 1, 	 0]]
         
    # 仅 y 坐标剪切
    M = [[1, 	  0, 0],
         [tan(b), 1, 0]]
     
    # x 与 y坐标同时剪切
    M = [[1, 	  tan(a), 0],
         [tan(b), 1, 	  0]]
    

    在这里插入图片描述

二、代码实现

(一) opencv 函数说明

1. warpAffine
  1. def warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None):

    • 解释:
      仿射变换函数,可实现旋转,平移,缩放;变换后的平行线依旧平行

    • 参数:

      src: 输入图像 dst:输出图像
      M: 2×3的变换矩阵
      dsize: 变换后输出图像尺寸
      flag: 插值方法
      borderMode:边界像素外扩方式
      borderValue:边界像素插值,默认用0填充

2. warpPerspective
  1. def warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None):

    • 解释:
      透视变换函数,可保持直线不变形,但是平行线可能不再平行
    • 参数:
      其相关参数和cv2.warpAffine函数的类似,
      区别在于:M 为 3×3 的变换矩阵,矩阵前两行用于仿射变换,第三行用于透视变换。

(二) 实现代码

  • 完整代码:

    • 完整代码连接:仿射变换-opencv

    • 挑选其中的一个进行阐述:
      以仿射变换中的 平移 为例子,其他变换只要 替换仿射变换的矩阵 即可:

      import cv2
      import numpy as np
      
      def translation_img(image, pad_color=(114, 114, 114)):
          """
          仿射变换:平移
          步骤:1. 设置平移仿射系数  2. 利用OpenCV中的warpAffine函数
          :return:
          """
          # 定义一个图像平移矩阵,矩阵M:仿射变换的平移参数
          # x向左平移(负数向左,正数向右) 100 个像素
          # y向下平移(负数向上,正数向下) 100 个像素
          # M = [[1, 0, dx],
          #      [0, 1, dy]]
          M = np.array([[1, 0, -100],
                        [0, 1, 100]], dtype=np.float)
      
          # 定义平移后图像的大小,保持和原图大小一致
          dsize = image.shape[:2][::-1]
          # 采用灰色来填充边界
          image = cv2.warpAffine(image, M, dsize, borderValue=pad_color)
      
          return image
      
      
      if __name__ == '__main__':
          image = cv2.imread('000007.jpg')
      
          cv2.imshow('org_img', image)
      
          image_dst = translation_img(image)
      
          cv2.imshow('image_dst', image_dst)
      
          cv2.waitKey(0)
          cv2.destroyAllWindows()
      
      
  • 效果如下:

    左图为原图,右图为 平移仿射变换 之后的图。

    在这里插入图片描述

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值