예제 #1
0
    def test_normalize_homography_identity(self, batch_size, device, dtype):
        # create input data
        input_shape = (4, 8, 5)
        dst_homo_src = utils.create_eye_batch(batch_size=batch_size, eye_size=4).to(device=device, dtype=dtype)

        res = torch.tensor(
            [[[0.5000, 0.0, 0.0, -1.0], [0.0, 0.2857, 0.0, -1.0], [0.0, 0.0, 0.6667, -1.0], [0.0, 0.0, 0.0, 1.0]]],
            device=device,
            dtype=dtype,
        )
        norm = kornia.normal_transform_pixel3d(input_shape[0], input_shape[1], input_shape[2]).to(
            device=device, dtype=dtype
        )
        assert_close(norm, res, rtol=1e-4, atol=1e-4)

        norm_homo = kornia.normalize_homography3d(dst_homo_src, input_shape, input_shape).to(device=device, dtype=dtype)
        assert_close(norm_homo, dst_homo_src, rtol=1e-4, atol=1e-4)

        norm_homo = kornia.normalize_homography3d(dst_homo_src, input_shape, input_shape).to(device=device, dtype=dtype)
        assert_close(norm_homo, dst_homo_src, rtol=1e-4, atol=1e-4)

        # change output scale
        norm_homo = kornia.normalize_homography3d(
            dst_homo_src, input_shape, (input_shape[0] // 2, input_shape[1] * 2, input_shape[2] // 2)
        ).to(device=device, dtype=dtype)
        res = torch.tensor(
            [[[4.0, 0.0, 0.0, 3.0], [0.0, 0.4667, 0.0, -0.5333], [0.0, 0.0, 3.0, 2.0], [0.0, 0.0, 0.0, 1.0]]],
            device=device,
            dtype=dtype,
        ).repeat(batch_size, 1, 1)
        assert_close(norm_homo, res, rtol=1e-4, atol=1e-4)
예제 #2
0
    def test_jit_warp_homography(self, batch_size, align_corners, normalized_coordinates, device, dtype):
        # generate input data
        height, width = 128, 64
        eye_size = 3  # identity 3x3

        patch_src = torch.rand(batch_size, 1, height, width, device=device, dtype=dtype)

        # create base homography
        dst_homo_src = utils.create_eye_batch(batch_size, eye_size, device=device, dtype=dtype)

        for _ in range(self.num_tests):
            # generate homography noise
            homo_delta = torch.rand_like(dst_homo_src) * 0.3

            dst_homo_src_i = dst_homo_src + homo_delta

            # transform the points with and without jit
            patch_dst = kornia.homography_warp(
                patch_src,
                dst_homo_src_i,
                (height, width),
                align_corners=align_corners,
                normalized_coordinates=normalized_coordinates,
            )
            patch_dst_jit = torch.jit.script(kornia.homography_warp)(
                patch_src,
                dst_homo_src_i,
                (height, width),
                align_corners=align_corners,
                normalized_coordinates=normalized_coordinates,
            )

            assert_close(patch_dst, patch_dst_jit, atol=1e-4, rtol=1e-4)
예제 #3
0
    def test_warp_grid_translation(self, shape, offset, device, dtype):
        # create input data
        depth, height, width = shape
        dst_homo_src = utils.create_eye_batch(batch_size=1,
                                              eye_size=4,
                                              device=device,
                                              dtype=dtype)
        dst_homo_src[..., 0, 3] = offset  # apply offset in x
        grid = kornia.create_meshgrid3d(depth,
                                        height,
                                        width,
                                        normalized_coordinates=False)
        flow = kornia.warp_grid3d(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_allclose(grid[..., 0].to(device=device, dtype=dtype) + offset,
                        flow[..., 0],
                        atol=1e-4,
                        rtol=1e-4)
        assert_allclose(grid[..., 1].to(device=device, dtype=dtype),
                        flow[..., 1],
                        atol=1e-4,
                        rtol=1e-4)
        assert_allclose(grid[..., 2].to(device=device, dtype=dtype),
                        flow[..., 2],
                        atol=1e-4,
                        rtol=1e-4)
예제 #4
0
    def test_jit_warp_homography(self, device, batch_size, align_corners,
                                 normalized_coordinates):
        # generate input data
        height, width = 128, 64
        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).to(device)

        # create base homography
        dst_homo_src = utils.create_eye_batch(batch_size, eye_size).to(device)

        for i in range(self.num_tests):
            # generate homography noise
            homo_delta = torch.rand_like(dst_homo_src) * 0.3

            dst_homo_src_i = dst_homo_src + homo_delta

            # transform the points with and without jit
            patch_dst = kornia.homography_warp(
                patch_src,
                dst_homo_src_i, (height, width),
                align_corners=align_corners,
                normalized_coordinates=normalized_coordinates)
            patch_dst_jit = torch.jit.script(kornia.homography_warp)(
                patch_src,
                dst_homo_src_i, (height, width),
                align_corners=align_corners,
                normalized_coordinates=normalized_coordinates)

            assert_allclose(patch_dst, patch_dst_jit)
예제 #5
0
    def test_gradcheck(self, batch_shape, device, dtype):
        # generate input data
        eye_size = 3  # identity 3x3

        # create checkerboard
        patch_src = torch.rand(batch_shape, device=device, dtype=dtype)
        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,
                                              device=device,
                                              dtype=dtype)
        dst_homo_src = utils.tensor_to_gradcheck_var(
            dst_homo_src, requires_grad=False)  # to var

        # instantiate warper
        warper = kornia.HomographyWarper(height, width, align_corners=True)

        # evaluate function gradient
        assert gradcheck(warper, (
            patch_src,
            dst_homo_src,
        ),
                         raise_exception=True)
예제 #6
0
    def test_normalize_homography_identity(self, batch_size, device, dtype):
        # create input data
        height, width = 2, 5
        dst_homo_src = utils.create_eye_batch(batch_size=batch_size,
                                              eye_size=3,
                                              device=device,
                                              dtype=dtype)

        res = torch.tensor(
            [[[0.5, 0.0, -1.0], [0.0, 2.0, -1.0], [0.0, 0.0, 1.0]]],
            device=device,
            dtype=dtype)
        assert (kornia.normal_transform_pixel(height,
                                              width,
                                              device=device,
                                              dtype=dtype) == res).all()

        norm_homo = kornia.normalize_homography(dst_homo_src, (height, width),
                                                (height, width))
        assert (norm_homo == dst_homo_src).all()

        norm_homo = kornia.normalize_homography(dst_homo_src, (height, width),
                                                (height, width))
        assert (norm_homo == dst_homo_src).all()

        # change output scale
        norm_homo = kornia.normalize_homography(dst_homo_src, (height, width),
                                                (height * 2, width // 2))
        res = torch.tensor(
            [[[4.0, 0.0, 3.0], [0.0, 1 / 3, -2 / 3], [0.0, 0.0, 1.0]]],
            device=device,
            dtype=dtype).repeat(batch_size, 1, 1)
        assert_allclose(norm_homo, res, atol=1e-4, rtol=1e-4)
예제 #7
0
    def test_homography_warper(self, batch_size, device, dtype):
        # generate input data
        height, width = 128, 64
        eye_size = 3  # identity 3x3

        patch_src = torch.ones(batch_size,
                               1,
                               height,
                               width,
                               device=device,
                               dtype=dtype)

        # create base homography
        dst_homo_src = utils.create_eye_batch(batch_size,
                                              eye_size,
                                              device=device,
                                              dtype=dtype)

        # instantiate warper
        warper = kornia.geometry.transform.HomographyWarper(height,
                                                            width,
                                                            align_corners=True)

        for _ in range(self.num_tests):
            # generate homography noise
            homo_delta = torch.rand_like(dst_homo_src) * 0.3

            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_cast(dst_homo_src_i))

            # same transform precomputing the grid
            warper.precompute_warp_grid(_torch_inverse_cast(dst_homo_src_i))
            patch_dst_to_src_precomputed = warper(patch_dst)
            assert_close(patch_dst_to_src_precomputed,
                         patch_dst_to_src,
                         atol=1e-4,
                         rtol=1e-4)

            # projected should be equal as initial
            error = utils.compute_patch_error(patch_src, patch_dst_to_src,
                                              height, width)

            assert error.item() < self.threshold

            # check functional api
            patch_dst_to_src_functional = kornia.geometry.transform.homography_warp(
                patch_dst,
                _torch_inverse_cast(dst_homo_src_i), (height, width),
                align_corners=True)

            assert_close(patch_dst_to_src,
                         patch_dst_to_src_functional,
                         atol=1e-4,
                         rtol=1e-4)
예제 #8
0
    def test_identity(self, device, dtype):
        # create input data
        height, width = 2, 5
        patch_src = torch.rand(1, 1, height, width, device=device, dtype=dtype)
        dst_homo_src = utils.create_eye_batch(batch_size=1, eye_size=3, device=device, dtype=dtype)

        # instantiate warper
        warper = kornia.HomographyWarper(height, width, align_corners=True)

        # warp from source to destination
        patch_dst = warper(patch_src, dst_homo_src)
        assert_close(patch_src, patch_dst)
    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 = kornia.HomographyWarper(height, width)
        patch_dst = warper(patch_src, dst_homo_src)
        assert_allclose(patch_src[..., 1:], patch_dst[..., :-1])
예제 #10
0
    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 = kornia.HomographyWarper(height, width)

        # warp from source to destination
        patch_dst = warper(patch_src, dst_homo_src)
        assert_allclose(patch_src, patch_dst)
예제 #11
0
    def test_translation(self, shape, device, dtype):
        # create input data
        offset = 2.0  # in pixel
        height, width = shape
        patch_src = torch.rand(1, 1, height, width, device=device, dtype=dtype)
        dst_homo_src = utils.create_eye_batch(batch_size=1, eye_size=3, device=device, dtype=dtype)
        dst_homo_src[..., 0, 2] = offset / (width - 1)  # apply offset in x

        # instantiate warper and from source to destination
        warper = kornia.HomographyWarper(height, width, align_corners=True)
        patch_dst = warper(patch_src, dst_homo_src)
        assert_close(patch_src[..., 1:], patch_dst[..., :-1], atol=1e-4, rtol=1e-4)
예제 #12
0
    def test_homography_warper(self, batch_size, device, dtype):
        # generate input data
        height, width = 128, 64
        eye_size = 3  # identity 3x3

        # create checkerboard
        board = utils.create_checkerboard(height, width, 4)
        patch_src = torch.from_numpy(board).to(
            device=device,
            dtype=dtype).view(1, 1, height,
                              width).expand(batch_size, 1, height, width)

        # create base homography
        dst_homo_src = utils.create_eye_batch(batch_size,
                                              eye_size,
                                              device=device,
                                              dtype=dtype)

        # instantiate warper
        warper = kornia.HomographyWarper(height, width, align_corners=True)

        for i in range(self.num_tests):
            # generate homography noise
            homo_delta = torch.rand_like(dst_homo_src) * 0.3

            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))

            # same transform precomputing the grid
            warper.precompute_warp_grid(torch.inverse(dst_homo_src_i))
            patch_dst_to_src_precomputed = warper(patch_dst)
            assert (patch_dst_to_src_precomputed == patch_dst_to_src).all()

            # projected should be equal as initial
            error = utils.compute_patch_error(patch_src, patch_dst_to_src,
                                              height, width)

            assert error.item() < self.threshold

            # check functional api
            patch_dst_to_src_functional = kornia.homography_warp(
                patch_dst,
                torch.inverse(dst_homo_src_i), (height, width),
                align_corners=True)

            assert_allclose(patch_dst_to_src,
                            patch_dst_to_src_functional,
                            atol=1e-4,
                            rtol=1e-4)
예제 #13
0
    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 = kornia.HomographyWarper(height // 2, width // 2)
        patch_dst = warper(patch_src, dst_homo_src)

        # check the corners
        assert_allclose(patch_src[..., 0, 0], patch_dst[..., 0, 0])
        assert_allclose(patch_src[..., 0, -1], patch_dst[..., 0, -1])
        assert_allclose(patch_src[..., -1, 0], patch_dst[..., -1, 0])
        assert_allclose(patch_src[..., -1, -1], patch_dst[..., -1, -1])
예제 #14
0
    def test_identity_resize(self, batch_shape, device, dtype):
        # create input data
        batch_size, channels, height, width = batch_shape
        patch_src = torch.rand(batch_size, channels, height, width, device=device, dtype=dtype)
        dst_homo_src = utils.create_eye_batch(batch_size, eye_size=3, device=device, dtype=dtype)

        # instantiate warper warp from source to destination
        warper = kornia.HomographyWarper(height // 2, width // 2, align_corners=True)
        patch_dst = warper(patch_src, dst_homo_src)

        # check the corners
        assert_close(patch_src[..., 0, 0], patch_dst[..., 0, 0], atol=1e-4, rtol=1e-4)
        assert_close(patch_src[..., 0, -1], patch_dst[..., 0, -1], atol=1e-4, rtol=1e-4)
        assert_close(patch_src[..., -1, 0], patch_dst[..., -1, 0], atol=1e-4, rtol=1e-4)
        assert_close(patch_src[..., -1, -1], patch_dst[..., -1, -1], atol=1e-4, rtol=1e-4)
예제 #15
0
def test_angle_axis_to_rotation_matrix(batch_size, device, dtype):
    # generate input data
    angle_axis = torch.rand(batch_size, 3, device=device, dtype=dtype)
    eye_batch = create_eye_batch(batch_size, 3, device=device, dtype=dtype)

    # 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_allclose(rotation_matrix_eye, eye_batch, atol=1e-4, rtol=1e-4)

    # evaluate function gradient
    angle_axis = tensor_to_gradcheck_var(angle_axis)  # to var
    assert gradcheck(kornia.angle_axis_to_rotation_matrix, (angle_axis, ),
                     raise_exception=True)
예제 #16
0
    def test_warp_grid_translation(self, shape, offset, device):
        # create input data
        height, width = shape
        dst_homo_src = utils.create_eye_batch(batch_size=1,
                                              eye_size=3).to(device)
        dst_homo_src[..., 0, 2] = offset  # apply offset in x

        # instantiate warper
        warper = kornia.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_allclose(warper.grid[..., 0].to(device) + offset, flow[..., 0])
        assert_allclose(warper.grid[..., 1].to(device), flow[..., 1])
예제 #17
0
    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 = kornia.HomographyWarper(height, width)
        patch_dst = warper(patch_src, dst_homo_src)

        # check the corners
        assert_allclose(patch_src[..., 0, 0], patch_dst[..., 0, -1])
        assert_allclose(patch_src[..., 0, -1], patch_dst[..., -1, -1])
        assert_allclose(patch_src[..., -1, 0], patch_dst[..., 0, 0])
        assert_allclose(patch_src[..., -1, -1], patch_dst[..., -1, 0])
예제 #18
0
    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 = kornia.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 = kornia.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)