import torch


def perspectiveTransformBatched(points, homography):
    """
    Transform point with given homography.

    Args:
        points (np.array of size BxNx2) - 2D points to be transformed
        homography (np.array of size Bx3x3) - homography matrix

    Returns:
        (np.array of size BxNx2) - transformed 2D points
    """

    # Asserts
    assert len(points.shape) == 3 and points.shape[2] == 2, 'points arg should be of size Nx2, but has size: {}'. \
        format(points.shape)
    assert homography.shape[1:] == (3, 3), 'homography arg should be of size 3x3, but has size: {}'\
        .format(homography.shape)

    if 'torch' in str(type(homography)) and 'torch' in str(type(points)):

        points = torch.nn.functional.pad(points, (0, 1), "constant", 1.)
        points_transformed = homography @ (points.permute(0, 2, 1))
        points_transformed = points_transformed.permute(0, 2, 1)
        return points_transformed[:, :, :2] / points_transformed[:, :, 2:].repeat(1, 1, 2)

    elif 'numpy' in str(type(homography)) and 'numpy' in str(type(points)):
        assert False, 'Not implemented - I was too lazy, sorry!'
    else:
        assert False, 'Wrong or inconsistent types?'