import random
import cv2
import numpy as np
import math
def random_rotate(img, boxes,angle_range):
'''
boxes形状位[None,2](x,y)
'''
angle = random.uniform(*angle_range)
height, width = img.shape[:2]
# 绕着图片中心旋转得到的旋转矩阵
rotation_matrix = cv2.getRotationMatrix2D(
(width / 2, height / 2), angle, 1)
corner_points = [(0, 0), (width-1, 0), (width-1, height-1), (0, height-1)]
# 旋转后的角点
lanmark_ = np.asarray([(rotation_matrix[0][0] * x + rotation_matrix[0][1] * y + rotation_matrix[0][2],
rotation_matrix[1][0] * x + rotation_matrix[1][1] * y + rotation_matrix[1][2]) for (x, y) in corner_points])
# 给图片填充边界
right,bottom = np.max(lanmark_,axis=0)
left,top = np.min(lanmark_,axis=0)
top_pad = np.max((0, math.ceil(-top)))
left_pad = np.max((0, math.ceil(-left)))
bottom_pad = np.max((0, math.ceil(bottom-height)))
right_pad = np.max((0, math.ceil(right-width)))
img = cv2.copyMakeBorder(
img, top_pad, bottom_pad, left_pad, right_pad, cv2.BORDER_CONSTANT, 0)
# 旋转图片
rotation_matrix = cv2.getRotationMatrix2D(
(width / 2 + left_pad, height / 2 + top_pad), angle, 1)
# 计算boxes
boxes_container = []
for index,box in enumerate(boxes):
points = np.asarray([(box[0],box[1]),(box[0],box[3]),(box[2],box[1]),(box[2],box[3])])
points = points + np.array([left_pad,top_pad])
points = np.asarray([(rotation_matrix[0][0] * x + rotation_matrix[0][1] * y + rotation_matrix[0][2],
rotation_matrix[1][0] * x + rotation_matrix[1][1] * y + rotation_matrix[1][2]) for (x, y) in points])
tl_point = np.min(points, axis=0)
rb_point = np.max(points, axis=0)
boxes[index][0:4] = [tl_point[0],tl_point[1],rb_point[0],rb_point[1]]
img_rotation = cv2.warpAffine(
img, rotation_matrix, (img.shape[1], img.shape[0]))
img = img_rotation
return img, boxes
效果图(红框为旋转前box,黄框为旋转后box):