def test_homography_warper_gradcheck(self): # generate input data batch_size = 1 height, width = 16, 32 # small patch, otherwise the test takes forever eye_size = 3 # identity 3x3 # create checkerboard board = utils.create_checkerboard(height, width, 4) patch_src = torch.from_numpy(board).view( 1, 1, height, width).expand(batch_size, 1, height, width) patch_src = utils.tensor_to_gradcheck_var(patch_src) # to var # create base homography dst_homo_src = utils.create_eye_batch(batch_size, eye_size) dst_homo_src = utils.tensor_to_gradcheck_var( dst_homo_src, requires_grad=False) # to var # instantiate warper warper = tgm.HomographyWarper(height, width) # evaluate function gradient res = gradcheck(warper, (patch_src, dst_homo_src,), raise_exception=True) self.assertTrue(res) # evaluate function gradient res = gradcheck( tgm.homography_warp, (patch_src, dst_homo_src, (height, width)), raise_exception=True) self.assertTrue(res)
def test_translation(self, shape): # create input data offset = 2. # in pixel height, width = shape patch_src = torch.rand(1, 1, height, width) dst_homo_src = utils.create_eye_batch(batch_size=1, eye_size=3) dst_homo_src[..., 0, 2] = offset / (width - 1) # apply offset in x # instantiate warper and from source to destination warper = tgm.HomographyWarper(height, width) patch_dst = warper(patch_src, dst_homo_src) assert utils.check_equal_torch(patch_src[..., 1:], patch_dst[..., :-1])
def test_identity(self): # create input data height, width = 2, 5 patch_src = torch.rand(1, 1, height, width) dst_homo_src = utils.create_eye_batch(batch_size=1, eye_size=3) # instantiate warper warper = tgm.HomographyWarper(height, width) # warp from source to destination patch_dst = warper(patch_src, dst_homo_src) assert utils.check_equal_torch(patch_src, patch_dst)
def test_angle_axis_to_rotation_matrix(self): # generate input data batch_size = 2 angle_axis = torch.rand(batch_size, 3) eye_batch = utils.create_eye_batch(batch_size, 4) # apply transform rotation_matrix = tgm.angle_axis_to_rotation_matrix(angle_axis) rotation_matrix_eye = torch.matmul(rotation_matrix, rotation_matrix.transpose(1, 2)) self.assertTrue(check_equal_torch(rotation_matrix_eye, eye_batch))
def test_inverse_pose(self): # generate input data batch_size = 1 eye_size = 4 # identity 4x4 dst_pose_src = utils.create_random_homography(batch_size, eye_size) dst_pose_src[:, -1] = 0.0 dst_pose_src[:, -1, -1] = 1.0 # compute the inverse of the pose src_pose_dst = tgm.inverse_pose(dst_pose_src) # H_inv * H == I res = torch.matmul(src_pose_dst, dst_pose_src) error = compute_mse(res, utils.create_eye_batch(batch_size, eye_size)) self.assertAlmostEqual(error.item(), 0.0, places=4)
def test_angle_axis_to_rotation_matrix(batch_size, device_type): # generate input data device = torch.device(device_type) angle_axis = torch.rand(batch_size, 3).to(device) eye_batch = utils.create_eye_batch(batch_size, 4).to(device) # apply transform rotation_matrix = kornia.angle_axis_to_rotation_matrix(angle_axis) rotation_matrix_eye = torch.matmul( rotation_matrix, rotation_matrix.transpose(1, 2)) assert check_equal_torch(rotation_matrix_eye, eye_batch) # evaluate function gradient angle_axis = utils.tensor_to_gradcheck_var(angle_axis) # to var assert gradcheck(kornia.angle_axis_to_rotation_matrix, (angle_axis,), raise_exception=True)
def test_inverse(self): # generate input data batch_size = 2 eye_size = 3 # identity 3x3 homographies = utils.create_random_homography(batch_size, eye_size) homographies_inv = tgm.inverse(homographies) # H_inv * H == I res = torch.matmul(homographies_inv, homographies) eye = utils.create_eye_batch(batch_size, eye_size) error = utils.compute_mse(res, eye) self.assertAlmostEqual(error.item(), 0.0, places=4) # functional self.assertTrue( torch.allclose(homographies_inv, tgm.Inverse()(homographies)))
def test_warp_grid_translation(self, shape, offset): # create input data height, width = shape patch_src = torch.rand(1, 1, height, width) dst_homo_src = utils.create_eye_batch(batch_size=1, eye_size=3) dst_homo_src[..., 0, 2] = offset # apply offset in x # instantiate warper warper = tgm.HomographyWarper(height, width, normalized_coordinates=False) flow = warper.warp_grid(dst_homo_src) # the grid the src plus the offset should be equal to the flow # on the x-axis, y-axis remains the same. assert utils.check_equal_torch(warper.grid[..., 0] + offset, flow[..., 0]) assert utils.check_equal_torch(warper.grid[..., 1], flow[..., 1])
def test_identity_resize(self, batch_shape): # create input data batch_size, channels, height, width = batch_shape patch_src = torch.rand(batch_size, channels, height, width) dst_homo_src = utils.create_eye_batch(batch_size, eye_size=3) # instantiate warper warp from source to destination warper = tgm.HomographyWarper(height // 2, width // 2) patch_dst = warper(patch_src, dst_homo_src) # check the corners assert utils.check_equal_torch(patch_src[..., 0, 0], patch_dst[..., 0, 0]) assert utils.check_equal_torch(patch_src[..., 0, -1], patch_dst[..., 0, -1]) assert utils.check_equal_torch(patch_src[..., -1, 0], patch_dst[..., -1, 0]) assert utils.check_equal_torch(patch_src[..., -1, -1], patch_dst[..., -1, -1])
def test_local_homography_warper(self): # generate input data batch_size = 1 height, width = 16, 32 eye_size = 3 # identity 3x3 # create checkerboard board = utils.create_checkerboard(height, width, 4) patch_src = torch.from_numpy(board).view( 1, 1, height, width).expand(batch_size, 1, height, width) # create local homography dst_homo_src = utils.create_eye_batch(batch_size, eye_size) dst_homo_src = dst_homo_src.view(batch_size, -1).unsqueeze(1) dst_homo_src = dst_homo_src.repeat(1, height * width, 1).view( 1, height, width, 3, 3) # NxHxWx3x3 # warp reference patch patch_src_to_i = tgm.homography_warp( patch_src, dst_homo_src, (height, width))
def test_homography_warper(self, batch_size, device_type): # generate input data height, width = 128, 64 eye_size = 3 # identity 3x3 device = torch.device(device_type) # create checkerboard board = utils.create_checkerboard(height, width, 4) patch_src = torch.from_numpy(board).view(1, 1, height, width).expand( batch_size, 1, height, width) patch_src = patch_src.to(device) # create base homography dst_homo_src = utils.create_eye_batch(batch_size, eye_size).to(device) # instantiate warper warper = tgm.HomographyWarper(height, width) for i in range(self.num_tests): # generate homography noise homo_delta = torch.zeros_like(dst_homo_src) homo_delta[:, -1, -1] = 0.0 dst_homo_src_i = dst_homo_src + homo_delta # transform the points from dst to ref patch_dst = warper(patch_src, dst_homo_src_i) patch_dst_to_src = warper(patch_dst, torch.inverse(dst_homo_src_i)) # projected should be equal as initial error = utils.compute_patch_error(patch_dst, patch_dst_to_src, height, width) assert error.item() < self.threshold # check functional api patch_dst_to_src_functional = tgm.homography_warp( patch_dst, torch.inverse(dst_homo_src_i), (height, width)) assert utils.check_equal_torch(patch_dst_to_src, patch_dst_to_src_functional)
def test_gradcheck(self, batch_shape, device_type): # generate input data device = torch.device(device_type) eye_size = 3 # identity 3x3 # create checkerboard patch_src = torch.rand(batch_shape).to(device) patch_src = utils.tensor_to_gradcheck_var(patch_src) # to var # create base homography batch_size, _, height, width = patch_src.shape dst_homo_src = utils.create_eye_batch(batch_size, eye_size) dst_homo_src = utils.tensor_to_gradcheck_var( dst_homo_src, requires_grad=False) # to var # instantiate warper warper = tgm.HomographyWarper(height, width) # evaluate function gradient assert gradcheck(warper, (patch_src, dst_homo_src,), raise_exception=True)
def test_rotation(self, batch_shape): # create input data batch_size, channels, height, width = batch_shape patch_src = torch.rand(batch_size, channels, height, width) # rotation of 90deg dst_homo_src = utils.create_eye_batch(batch_size, 3) dst_homo_src[..., 0, 0] = 0.0 dst_homo_src[..., 0, 1] = 1.0 dst_homo_src[..., 1, 0] = -1.0 dst_homo_src[..., 1, 1] = 0.0 # instantiate warper and warp from source to destination warper = tgm.HomographyWarper(height, width) patch_dst = warper(patch_src, dst_homo_src) # check the corners assert utils.check_equal_torch(patch_src[..., 0, 0], patch_dst[..., 0, -1]) assert utils.check_equal_torch(patch_src[..., 0, -1], patch_dst[..., -1, -1]) assert utils.check_equal_torch(patch_src[..., -1, 0], patch_dst[..., 0, 0]) assert utils.check_equal_torch(patch_src[..., -1, -1], patch_dst[..., -1, 0])