正如我们在上面讨论的,你有可能被重叠的瓷砖,所以这已经被解决了。缺少的是旋转瓷砖。我们需要指定一个随机旋转角度,这样我们就可以先生成一个随机角度。
之后,这只是一个应用仿射变换的问题,仿射变换纯粹是对平铺的旋转,然后附加到列表中。在OpenCV中旋转图像的问题是,当你旋转图像时,它会被裁剪,所以一旦旋转,你就无法获得图像中包含的整个平铺。
我用了
following post as inspiration
为了解决这个问题,当你旋转时,图像被完全包含。请注意,为了适应旋转并保持旋转结果中包含的整个图像,图像将在尺寸上展开。
import cv2
import numpy as np
def rotate_about_center(src, angle):
h, w = src.shape[:2]
rangle = np.deg2rad(angle) # angle in radians
# now calculate new image width and height
nw = (abs(np.sin(rangle)*h) + abs(np.cos(rangle)*w))
nh = (abs(np.cos(rangle)*h) + abs(np.sin(rangle)*w))
# ask OpenCV for the rotation matrix
rot_mat = cv2.getRotationMatrix2D((nw*0.5, nh*0.5), angle, 1)
# calculate the move from the old centre to the new centre combined
# with the rotation
rot_move = np.dot(rot_mat, np.array([(nw-w)*0.5, (nh-h)*0.5,0]))
# the move only affects the translation, so update the translation
# part of the transform
rot_mat[0,2] += rot_move[0]
rot_mat[1,2] += rot_move[1]
return cv2.warpAffine(src, rot_mat, (int(math.ceil(nw)), int(math.ceil(nh))), flags=cv2.INTER_LANCZOS4)
你使用这个函数,用一个随机角度调用它,然后在完成后保存补丁。当然,您还需要指定最大旋转角度。
import random
max_angle = 20 # +/- 20 degrees maximum rotation
patches = []
idxs = []
for i in range(0, count):
start_row_idx = random.randint(0, img_height-target_height-1)
start_col_idx = random.randint(0, img_width-target_width-1)
# Generate an angle between +/- max_angle
angle = (2*max_angle)*random.random() - max_angle
if mode == 'rgb':
patch = img_array[start_row_idx:(start_row_idx+target_height), start_col_idx:(start_col_idx+target_width), :]
else:
patch = img_array[start_row_idx:(start_row_idx+target_height), start_col_idx:(start_col_idx+target_width)]
# Randomly rotate the image
patch_r = rotate_about_center(patch, angle)
# Save it now
patches.append(patch_r)
idxs.append((start_row_idx, start_col_idx))