文章目录
CV — 数据增强:仿射变换
一、前言
(一) 仿射变换概念
-
前言:
在深度学习的数据增强中,我们经常需要对图像进行各种增强操作如:平移、翻转(flip)、缩放(Scale)、旋转(Rotation)、裁剪(Shear) 等,这些其实都是 图像的仿射变换。
待确认:对比度,色彩抖动,噪声 -
仿射变换原理:
-
维基百科定义:
仿射变换(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 就可以实现两个向量空间之间的转换。
- 令:j = w * k + b,
-
总结:
在进行仿射变换的时候我们也只需要一个矩阵M就可以实现平移、缩放、旋转和翻转等变换。仿射变换是一种二维坐标到二维坐标之间的线性变换,它保持了二维图形的 “平直性”(直线经过变换之后依然是直线)和 “平行性”(二维图形之间的相对位置关系保持不变,平行线依然是平行线,且直线上点的位置顺序不变)。任意的仿射变换 都能表示为乘以一个矩阵(线性变换),再加上一个向量 (平移) 的形式.
-
(二) 仿射变换矩阵
-
平移:
# x向左平移(负数向左,正数向右) dx 个像素 # y向下平移(负数向上,正数向下) dy 个像素 M = [[1, 0, dx], [0, 1, dy]]
-
翻转(flip):
# 水平翻转 M = [[-1, 0, w], [0, 1, 0]] # 垂直翻转 M = [[1, 0, 0], [0, -1, h]]
-
缩放(Scale):
# fx,fy:宽高缩放的倍数 M = [[fx, 0, 0], [0, fy, 0]])
-
旋转(Rotation):
# 以原点为中心旋转 # d:要转化为弧度制,d = 角度a * pi / 180 M = [[cosd, -sind, 0], [sind, cosd, 0]]
-
裁剪(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 函数说明
-
参考资料:
- 仿射说明及opencv使用:https://blog.csdn.net/zhuguiqin1/article/details/113813272
- 仿射变换与透视变换区别:https://blog.csdn.net/flyyufenfei/article/details/80208361
1. warpAffine
-
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
-
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()
-
-
效果如下:
左图为原图,右图为 平移仿射变换 之后的图。