在做人脸或物体检测的任务中,往往需要对训练集进行随机旋转,做数据增强,增加模型的鲁棒性。
在进行图像随机旋转的同时,相应的label值坐标也要进行相应的旋转。
如人脸关键点检测中人脸对应的关键点坐标,物体检测任务中的物体所在box坐标。
(1).原理-------坐标旋转变换公式
原理参照博客:
https://blog.csdn.net/u012686154/article/details/88854386
最终变换公式如下:
坐标(x,y)顺时针旋转 β 度,则经过矩阵相乘,转换成新的坐标(x‘,y')
(2).实现-------python代码实现
import math
from PIL import Image
#box为0~1的值,为[ymin, xmin, ymax, xmax]
#landmarks为0~1的值,为[y0,x0,y1,x1,y2,x2......yn,xn]
def random_rotation(image, box, landmarks, max_angle=90):
#为随机旋转的角度-90~90度
angle = np.random.uniform(-max_angle,max_angle)
theta = angle*(math.pi/180.0)
#获取旋转的中心坐标
#也即是图像的中心坐标
image_height = image.shape[0]
image_width = image.shape[1]
scaler = np.stack([image_height, image_width], axis=0)
center = np.reshape(0.5*scaler, [1, 2])
#求旋转矩阵
rotation = np.stack([np.cos(theta), np.sin(theta),-np.sin(theta), np.cos(theta)], axis=0)
rotation_matrix = np.reshape(rotation, [2, 2])
#旋转方框
ymin, xmin, ymax, xmax = box
h, w = ymax - ymin, xmax - xmin
box = np.stack([ymin, xmin, ymin, xmax,ymax, xmax, ymax, xmin], axis=0)
box = np.matmul(np.reshape(box, [4, 2])*scaler - center, rotation_matrix) + center
box = box/scaler
y ,x = box[:,0],box[:,1]
ymin, ymax = np.min(y), np.max(y)
xmin, xmax = np.min(x), np.max(x)
box = np.stack([ymin, xmin, ymax, xmax], axis=0)
#旋转坐标
landmarks = np.matmul(landmarks*scaler - center, rotation_matrix) + center
landmarks = landmarks/scaler
#旋转图像
image = Image.fromarray(image)
im_rotate = image.rotate(angle)
im_rotate = np.array(im_rotate)
return im_rotate, box, landmarks