1.背景
因为数据集很少,项目还需要进行图像的识别,因此利用图像增广技术产生相似但是又不同的样本,扩大数据集的规模,从而降低模型对某些属性的依赖,从而提高模型的泛化能力。常见的图像增广技术有:翻转和剪切,变换颜色等。接下来介绍的这种是图像的旋转
2.实现方法
import cv2from math import *import osdef remote(img, degree):height, width = img.shape[:2]radians = float(degree / 180 * pi)heightNew = int(width * fabs(sin((radians))) + height * fabs(cos((radians))))widthNew = int(height * fabs(sin((radians))) + width * fabs(cos((radians))))# 得到二维矩阵的旋转的仿射矩阵matRotation = cv2.getRotationMatrix2D((width / 2, height / 2), degree, 1)# 中心位置的实际平移matRotation[0, 2] += (widthNew - width) / 2matRotation[1, 2] += (heightNew - height) / 2imgRotation = cv2.warpAffine(img, matRotation, (widthNew, heightNew), borderValue=(255, 255, 255))return imgRotationif __name__ == "__main__":# 图片路径image_path = r"C:/Users/zhang/Desktop/pic03/"# 角度列表agree_list = [-30, -60, -90, -120, -150, -180, -210, -240, -270, -300, -330]for dirpath, dirnames, filenames in os.walk(image_path):for filename in filenames:img = cv2.imread(os.path.join(image_path, filename))for agree in agree_list:imgRotation = remote(img, agree)cv2.imwrite(image_path + filename.split('.')[0] + "-" + str(agree) + ".jpg", imgRotation)
3.实现原理
基于最近邻取值的正向映射法以顺时针旋转为例来堆到旋转变换公式。如下图所示。
旋转前:
x0=rcosb;y0=rsinb
旋转a角度后:
x1=rcos(b-a)=rcosbcosa+rsinbsina=x0cosa+y0sina
y1=rsin(b-a)=rsinbcosa-rcosbsina=-x0sina+y0cosa
正向映射即根据原图的坐标推导出旋转图像对应点坐标,然后直接将原图坐标灰度值赋给x1,y1
2.基于最近邻取值的反向映射法
旋转前:
x1=rcosc;y1=rsinc
旋转a角度后:
x0=rcos(c+a)=rcosccosa-rsincsina=x1cosa-y1sina
y0=rsin(c+a)=rsinccosa+rcoscsina=-x1sina+y1cosa
反向映射即已知旋转后图像坐标,通过公式推导出原始图像上对应坐标,将该坐标对应灰度值赋给旋转后坐标。因为计算得到的y0, x0非整数,最近邻方法即将与(Xo,Yo)距离最近的像素的灰度值作为(Xo,Yo)的灰度值赋给(X1,Y1)点。
3.基于双线性插值的反向映射法
在计算(Xo,Yo)的灰度值时,采用如下方法计算:
4.实现方法的理解
其实步骤2代码采用的方法其实是最近邻取值的正向映射法,在计算出旋转变换矩阵M后,计算一下可以正常包含旋转后图像的外接矩形框的长和宽,然后计算外接矩形框的中心和原矩形框中心的距离,最后将旋转后的图像中心移到新的外接矩形框的中心。
参考
1:/p/109099445
2:/liyuan02/article/details/6750828
3:/lkj345/article/details/50555870