Beispiel #1
0
 def compute_transformation(self, input: Tensor,
                            params: Dict[str, Tensor]) -> Tensor:
     return get_affine_matrix2d(
         torch.as_tensor(params["translations"],
                         device=input.device,
                         dtype=input.dtype),
         torch.as_tensor(params["center"],
                         device=input.device,
                         dtype=input.dtype),
         torch.as_tensor(params["scale"],
                         device=input.device,
                         dtype=input.dtype),
         torch.as_tensor(params["angle"],
                         device=input.device,
                         dtype=input.dtype),
         deg2rad(
             torch.as_tensor(params["sx"],
                             device=input.device,
                             dtype=input.dtype)),
         deg2rad(
             torch.as_tensor(params["sy"],
                             device=input.device,
                             dtype=input.dtype)),
     )
Beispiel #2
0
def angle_to_rotation_matrix(angle: torch.Tensor) -> torch.Tensor:
    r"""Create a rotation matrix out of angles in degrees.
    Args:
        angle: (torch.Tensor): tensor of angles in degrees, any shape.

    Returns:
        torch.Tensor: tensor of *x2x2 rotation matrices.

    Shape:
        - Input: :math:`(*)`
        - Output: :math:`(*, 2, 2)`

    Example:
        >>> input = torch.rand(1, 3)  # Nx3
        >>> output = kornia.angle_to_rotation_matrix(input)  # Nx3x2x2
    """
    ang_rad = deg2rad(angle)
    cos_a: torch.Tensor = torch.cos(ang_rad)
    sin_a: torch.Tensor = torch.sin(ang_rad)
    return torch.stack([cos_a, sin_a, -sin_a, cos_a], dim=-1).view(*angle.shape, 2, 2)
Beispiel #3
0
def get_rotation_matrix2d(center: torch.Tensor, angle: torch.Tensor,
                          scale: torch.Tensor) -> torch.Tensor:
    r"""Calculates an affine matrix of 2D rotation.

    The function calculates the following matrix:

    .. math::
        \begin{bmatrix}
            \alpha & \beta & (1 - \alpha) \cdot \text{x}
            - \beta \cdot \text{y} \\
            -\beta & \alpha & \beta \cdot \text{x}
            + (1 - \alpha) \cdot \text{y}
        \end{bmatrix}

    where

    .. math::
        \alpha = \text{scale} \cdot cos(\text{angle}) \\
        \beta = \text{scale} \cdot sin(\text{angle})

    The transformation maps the rotation center to itself
    If this is not the target, adjust the shift.

    Args:
        center (Tensor): center of the rotation in the source image.
        angle (Tensor): rotation angle in degrees. Positive values mean
            counter-clockwise rotation (the coordinate origin is assumed to
            be the top-left corner).
        scale (Tensor): isotropic scale factor.

    Returns:
        Tensor: the affine matrix of 2D rotation.

    Shape:
        - Input: :math:`(B, 2)`, :math:`(B)` and :math:`(B)`
        - Output: :math:`(B, 2, 3)`

    Example:
        >>> center = torch.zeros(1, 2)
        >>> scale = torch.ones(1)
        >>> angle = 45. * torch.ones(1)
        >>> M = kornia.get_rotation_matrix2d(center, angle, scale)
        tensor([[[ 0.7071,  0.7071,  0.0000],
                 [-0.7071,  0.7071,  0.0000]]])
    """
    if not torch.is_tensor(center):
        raise TypeError(
            "Input center type is not a torch.Tensor. Got {}".format(
                type(center)))
    if not torch.is_tensor(angle):
        raise TypeError(
            "Input angle type is not a torch.Tensor. Got {}".format(
                type(angle)))
    if not torch.is_tensor(scale):
        raise TypeError(
            "Input scale type is not a torch.Tensor. Got {}".format(
                type(scale)))
    if not (len(center.shape) == 2 and center.shape[1] == 2):
        raise ValueError("Input center must be a Bx2 tensor. Got {}".format(
            center.shape))
    if not len(angle.shape) == 1:
        raise ValueError("Input angle must be a B tensor. Got {}".format(
            angle.shape))
    if not len(scale.shape) == 1:
        raise ValueError("Input scale must be a B tensor. Got {}".format(
            scale.shape))
    if not (center.shape[0] == angle.shape[0] == scale.shape[0]):
        raise ValueError(
            "Inputs must have same batch size dimension. Got {}".format(
                center.shape, angle.shape, scale.shape))
    # convert angle and apply scale
    angle_rad: torch.Tensor = deg2rad(angle)
    alpha: torch.Tensor = torch.cos(angle_rad) * scale
    beta: torch.Tensor = torch.sin(angle_rad) * scale

    # unpack the center to x, y coordinates
    x: torch.Tensor = center[..., 0]
    y: torch.Tensor = center[..., 1]

    # create output tensor
    batch_size: int = center.shape[0]
    M: torch.Tensor = torch.zeros(batch_size,
                                  2,
                                  3,
                                  device=center.device,
                                  dtype=center.dtype)
    M[..., 0, 0] = alpha
    M[..., 0, 1] = beta
    M[..., 0, 2] = (torch.tensor(1.) - alpha) * x - beta * y
    M[..., 1, 0] = -beta
    M[..., 1, 1] = alpha
    M[..., 1, 2] = beta * x + (torch.tensor(1.) - alpha) * y
    return M