OpenCV:使用 warpAffine 旋转地板纹理并保持瓷砖接缝彼此相邻
OpenCV: Rotate floor texture with warpAffine and keep tile seams adjacent to each other
给定一个正方形或长方形的地砖纹理,如何warpAffine
旋转任意角度并保持地砖相邻? (视觉上)
原装地砖
预期结果
4x4 拼接拼贴 + cv2.BORDER_WRAP
,拼贴接缝相邻。贴图逆时针旋转了45度,但只有n*pi/2
角度当n
为奇数
时才能正常工作
瓷砖在视觉上不相交,角度 = 75 度
代码
texture = cv2.imread(ACTIVE_TEXTURE)
def concat_tile(im_list_2d):
return cv2.vconcat([cv2.hconcat(im_list_h) for im_list_h in im_list_2d])
def rotate_texture(texture, angle=0, scale=1.0):
print(angle)
height, width = texture.shape[:2]
midpoint = (width / 2, height / 2)
rotation_mat = cv2.getRotationMatrix2D(tuple(midpoint), angle, scale)
abs_cos = abs(rotation_mat[0, 0])
abs_sin = abs(rotation_mat[0, 1])
bound_w = int(height * abs_sin + width * abs_cos)
bound_h = int(height * abs_cos + width * abs_sin)
rotation_mat[0, 2] += bound_w / 2 - midpoint[0]
rotation_mat[1, 2] += bound_h / 2 - midpoint[1]
texture_rotated = cv2.warpAffine(texture, rotation_mat, (bound_w, bound_h), borderMode=cv2.BORDER_WRAP,
flags=cv2.INTER_AREA)
texture_rotated = cv2.resize(texture_rotated, (height, width), interpolation=cv2.INTER_AREA)
return texture_rotated
rot_angle = 45
texture = rotate_texture(texture, angle=rot_angle)
tiles = [[texture for _ in range(4)] for _ in range(4)]
texture = concat_tile(tiles)
cv2.namedWindow('image', cv2.WINDOW_GUI_NORMAL)
cv2.resizeWindow('image', 600, 600)
cv2.imshow('image', texture)
cv2.waitKey()
cv2.destroyAllWindows()
让我提出一个解决方法:
- 创建不旋转的图块,但增大尺寸以允许裁剪
- 旋转整个图像
- 裁剪到所需尺寸
给定一个正方形或长方形的地砖纹理,如何warpAffine
旋转任意角度并保持地砖相邻? (视觉上)
原装地砖
预期结果
4x4 拼接拼贴 + cv2.BORDER_WRAP
,拼贴接缝相邻。贴图逆时针旋转了45度,但只有n*pi/2
角度当n
为奇数
瓷砖在视觉上不相交,角度 = 75 度
代码
texture = cv2.imread(ACTIVE_TEXTURE)
def concat_tile(im_list_2d):
return cv2.vconcat([cv2.hconcat(im_list_h) for im_list_h in im_list_2d])
def rotate_texture(texture, angle=0, scale=1.0):
print(angle)
height, width = texture.shape[:2]
midpoint = (width / 2, height / 2)
rotation_mat = cv2.getRotationMatrix2D(tuple(midpoint), angle, scale)
abs_cos = abs(rotation_mat[0, 0])
abs_sin = abs(rotation_mat[0, 1])
bound_w = int(height * abs_sin + width * abs_cos)
bound_h = int(height * abs_cos + width * abs_sin)
rotation_mat[0, 2] += bound_w / 2 - midpoint[0]
rotation_mat[1, 2] += bound_h / 2 - midpoint[1]
texture_rotated = cv2.warpAffine(texture, rotation_mat, (bound_w, bound_h), borderMode=cv2.BORDER_WRAP,
flags=cv2.INTER_AREA)
texture_rotated = cv2.resize(texture_rotated, (height, width), interpolation=cv2.INTER_AREA)
return texture_rotated
rot_angle = 45
texture = rotate_texture(texture, angle=rot_angle)
tiles = [[texture for _ in range(4)] for _ in range(4)]
texture = concat_tile(tiles)
cv2.namedWindow('image', cv2.WINDOW_GUI_NORMAL)
cv2.resizeWindow('image', 600, 600)
cv2.imshow('image', texture)
cv2.waitKey()
cv2.destroyAllWindows()
让我提出一个解决方法:
- 创建不旋转的图块,但增大尺寸以允许裁剪
- 旋转整个图像
- 裁剪到所需尺寸