示例#1
0
def _compose_affine_matrix_3x3(translations: torch.Tensor,
                               center: torch.Tensor,
                               scale: torch.Tensor,
                               angle: torch.Tensor,
                               sx: Optional[torch.Tensor] = None,
                               sy: Optional[torch.Tensor] = None) -> torch.Tensor:
    r"""Composes affine matrix Bx3x3 from the components
    Returns:
        torch.Tensor: params to be passed to the affine transformation.
    """
    transform: torch.Tensor = get_rotation_matrix2d(center, -angle, scale)
    transform[..., 2] += translations  # tx/ty
    # pad transform to get Bx3x3
    transform_h = convert_affinematrix_to_homography(transform)
    if sx is not None:
        x, y = torch.split(center, 1, dim=-1)
        x = x.view(-1)
        y = y.view(-1)
        sx_tan = torch.tan(sx)  # type: ignore
        sy_tan = torch.tan(sy)  # type: ignore
        zeros = torch.zeros_like(sx)  # type: ignore
        ones = torch.ones_like(sx)  # type: ignore
        shear_mat = torch.stack([ones,   -sx_tan,                 sx_tan * x,  # type: ignore   # noqa: E241
                                 -sy_tan, ones + sx_tan * sy_tan, sy_tan * (-sx_tan * x + y)],  # noqa: E241
                                dim=-1).view(-1, 2, 3)
        shear_mat = convert_affinematrix_to_homography(shear_mat)
        transform_h = transform_h @ shear_mat
    return transform_h
示例#2
0
def _get_random_affine_params(
    batch_size: int,
    height: int,
    width: int,
    degrees: TupleFloat,
    translate: Optional[TupleFloat],
    scales: Optional[TupleFloat],
    shears: Optional[TupleFloat],
) -> torch.Tensor:
    r"""Get parameters for affine transformation. The returned matrix is Bx3x3.

    Returns:
        torch.Tensor: params to be passed to the affine transformation.
    """
    angle = Uniform(degrees[0], degrees[1]).rsample((batch_size, ))

    # compute tensor ranges
    if scales is not None:
        scale = Uniform(scales[0], scales[1]).rsample((batch_size, ))
    else:
        scale = torch.ones(batch_size)

    if shears is not None:
        shear = Uniform(shears[0], shears[1]).rsample((batch_size, ))
    else:
        shear = torch.zeros(batch_size)

    if translate is not None:
        max_dx: float = translate[0] * width
        max_dy: float = translate[1] * height
        translations = torch.stack([
            Uniform(-max_dx, max_dx).rsample((batch_size, )),
            Uniform(-max_dy, max_dy).rsample((batch_size, )),
        ],
                                   dim=-1)
    else:
        translations = torch.zeros(batch_size, 2)

    center: torch.Tensor = torch.tensor([width, height],
                                        dtype=torch.float32).view(1, 2) / 2
    center = center.expand(batch_size, -1)

    # concatenate transforms
    transform: torch.Tensor = get_rotation_matrix2d(center, angle, scale)
    transform[..., 2] += translations  # tx/ty
    transform[..., 0, 1] += shear
    transform[..., 1, 0] += shear

    # pad transform to get Bx3x3
    transform_h = torch.nn.functional.pad(transform, [0, 0, 0, 1], value=0.)
    transform_h[..., -1, -1] += 1.0
    return transform_h