o
    oiZ                     @   s   d dl mZmZmZmZmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZmZ d dlmZ d dlmZmZ G dd	 d	e
Zd
S )    )AnyDictOptionalTupleUnion)random_generator)GeometricAugmentationBase2D)ResampleSamplePadding)Tensor	as_tensor)deg2rad)get_affine_matrix2dwarp_affinec                       sx  e Zd ZdZdddejjddejjddf	de	e
eeeef f dee	e
eeef f  dee	e
eeef eeeeef f  dee	e
eeeef f  d	e	eeef d
edede	eeef dededdf fddZde
deee
f deeef de
fddZ	dde
deee
f deeef dee
 de
f
ddZ		dde
deeef dee
 deeeef  de
f
ddZ  ZS )RandomAffinea  Apply a random 2D affine transformation to a tensor image.

    .. image:: _static/img/RandomAffine.png

    The transformation is computed so that the image center is kept invariant.

    Args:
        degrees: Range of degrees to select from.
            If degrees is a number instead of sequence like (min, max), the range of degrees
            will be (-degrees, +degrees). Set to 0 to deactivate rotations.
        translate: tuple of maximum absolute fraction for horizontal
            and vertical translations. For example translate=(a, b), then horizontal shift
            is randomly sampled in the range -img_width * a < dx < img_width * a and vertical shift is
            randomly sampled in the range -img_height * b < dy < img_height * b. Will not translate by default.
        scale: scaling factor interval.
            If (a, b) represents isotropic scaling, the scale is randomly sampled from the range a <= scale <= b.
            If (a, b, c, d), the scale is randomly sampled from the range a <= scale_x <= b, c <= scale_y <= d.
            Will keep original scale by default.
        shear: Range of degrees to select from.
            If float, a shear parallel to the x axis in the range (-shear, +shear) will be applied.
            If (a, b), a shear parallel to the x axis in the range (-shear, +shear) will be applied.
            If (a, b, c, d), then x-axis shear in (shear[0], shear[1]) and y-axis shear in (shear[2], shear[3])
            will be applied. Will not apply shear by default.
        resample: resample mode from "nearest" (0) or "bilinear" (1).
        padding_mode: padding mode from "zeros" (0), "border" (1) or "reflection" (2).
        same_on_batch: apply the same transformation across the batch.
        align_corners: interpolation flag.
        p: probability of applying the transformation.
        keepdim: whether to keep the output shape the same as input (True) or broadcast it to the batch form (False).

    Shape:
        - Input: :math:`(C, H, W)` or :math:`(B, C, H, W)`, Optional: :math:`(B, 3, 3)`
        - Output: :math:`(B, C, H, W)`

    .. note::
        This function internally uses :func:`kornia.geometry.transform.warp_affine`.

    Examples:
        >>> import torch
        >>> rng = torch.manual_seed(0)
        >>> input = torch.rand(1, 1, 3, 3)
        >>> aug = RandomAffine((-15., 20.), p=1.)
        >>> out = aug(input)
        >>> out, aug.transform_matrix
        (tensor([[[[0.3961, 0.7310, 0.1574],
                  [0.1781, 0.3074, 0.5648],
                  [0.4804, 0.8379, 0.4234]]]]), tensor([[[ 0.9923, -0.1241,  0.1319],
                 [ 0.1241,  0.9923, -0.1164],
                 [ 0.0000,  0.0000,  1.0000]]]))
        >>> aug.inverse(out)
        tensor([[[[0.3890, 0.6573, 0.1865],
                  [0.2063, 0.3074, 0.5459],
                  [0.3892, 0.7896, 0.4224]]]])
        >>> input
        tensor([[[[0.4963, 0.7682, 0.0885],
                  [0.1320, 0.3074, 0.6341],
                  [0.4901, 0.8964, 0.4556]]]])

    To apply the exact augmenation again, you may take the advantage of the previous parameter state:
        >>> input = torch.randn(1, 3, 32, 32)
        >>> aug = RandomAffine((-15., 20.), p=1.)
        >>> (aug(input) == aug(input, params=aug._params)).all()
        tensor(True)

    NFg      ?degrees	translatescaleshearresamplesame_on_batchalign_cornerspadding_modepkeepdimreturnc                    sB   t  j|	||
d t||||| _t|t||d| _d S )N)r   r   r   )r   r   r   )	super__init__rgAffineGenerator_param_generatorr	   getr
   flags)selfr   r   r   r   r   r   r   r   r   r   	__class__ \/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/_2d/geometric/affine.pyr   _   s   zRandomAffine.__init__inputparamsr"   c                 C   s   t t|d |j|jdt|d |j|jdt|d |j|jdt|d |j|jdtt|d |j|jdtt|d |j|jdS )Ntranslationsdevicedtypecenterr   angleshear_xshear_y)r   r   r,   r-   r   )r#   r(   r)   r"   r&   r&   r'   compute_transformationt   s   z#RandomAffine.compute_transformation	transformc                 C   sr   |j \}}}}t|tstdt| dt||d d d dd d f ||f|d j |d |d j dS )N*Expected the `transform` be a Tensor. Got .   r   r   r   )r   r   )shape
isinstancer   	TypeErrortyper   namelower)r#   r(   r)   r"   r3   _heightwidthr&   r&   r'   apply_transform~   s   
zRandomAffine.apply_transformsizec                 C   s@   t |tstdt| d| j|| jt||j|jd|dS )Nr4   r5   r+   )r)   r3   r"   )	r8   r   r9   r:   r@   _paramsr   r,   r-   )r#   r(   r"   r3   rA   r&   r&   r'   inverse_transform   s   
zRandomAffine.inverse_transform)N)NN)__name__
__module____qualname____doc__r	   BILINEARr;   r
   ZEROSr   r   floatr   r   strintboolr   r   r   r2   r@   rC   __classcell__r&   r&   r$   r'   r      sx    E$	
*



r   N)typingr   r   r   r   r   kornia.augmentationr   r   &kornia.augmentation._2d.geometric.baser   kornia.constantsr	   r
   kornia.corer   r   kornia.geometry.conversionsr   kornia.geometry.transformr   r   r   r&   r&   r&   r'   <module>   s   