o
    oi                     @   st   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 d dlmZ d dlmZmZmZ G dd de
Zd	S )
    )AnyDictOptionalTupleUnion)random_generator)GeometricAugmentationBase3D)Resample)Tensor)deg2radget_affine_matrix3dwarp_affine3dc                       s  e Zd ZdZdddejjddddfdeee	e
e	e	f e
e	e	e	f e
e
e	e	f e
e	e	f e
e	e	f f f deeee
e	e	e	f f  deeee
e	e	f e
e
e	e	f e
e	e	f e
e	e	f f f  dedee	e
e	e	f e
e	e	e	e	e	e	f e
e
e	e	f e
e	e	f e
e	e	f e
e	e	f e
e	e	f e
e	e	f f f d	eeeef d
ede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  ZS )RandomAffine3Dag  Apply affine transformation 3D volumes (5D tensor).

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

    Args:
        degrees: Range of yaw (x-axis), pitch (y-axis), roll (z-axis) to select from.
            If degrees is a number, then yaw, pitch, roll will be generated from the range of (-degrees, +degrees).
            If degrees is a tuple of (min, max), then yaw, pitch, roll will be generated from the range of (min, max).
            If degrees is a list of floats [a, b, c], then yaw, pitch, roll will be generated from (-a, a), (-b, b)
            and (-c, c).
            If degrees is a list of tuple ((a, b), (m, n), (x, y)), then yaw, pitch, roll will be generated from
            (a, b), (m, n) and (x, y).
            Set to 0 to deactivate rotations.
        translate: tuple of maximum absolute fraction for horizontal, vertical and
            depthical translations (dx,dy,dz). For example translate=(a, b, c), then
            horizontal shift will be randomly sampled in the range -img_width * a < dx < img_width * a
            vertical shift will be randomly sampled in the range -img_height * b < dy < img_height * b.
            depthical shift will be randomly sampled in the range -img_depth * c < dz < img_depth * c.
            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), (e, f)), the scale is randomly sampled from the range a <= scale_x <= b,
            c <= scale_y <= d, e <= scale_z <= f. Will keep original scale by default.
        shears: Range of degrees to select from.
            If shear is a number, a shear to the 6 facets in the range (-shear, +shear) will be applied.
            If shear is a tuple of 2 values, a shear to the 6 facets in the range (shear[0], shear[1]) will be applied.
            If shear is a tuple of 6 values, a shear to the i-th facet in the range (-shear[i], shear[i])
            will be applied.
            If shear is a tuple of 6 tuples, a shear to the i-th facet in the range (-shear[i, 0], shear[i, 1])
            will be applied.
        resample: resample mode from "nearest" (0) or "bilinear" (1).
        same_on_batch: apply the same transformation across the batch.
        align_corners: interpolation flag.
        keepdim: whether to keep the output shape the same as input (True) or broadcast it
          to the batch form (False). Default: False.

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

    Note:
        Input tensor must be float and normalized into [0, 1] for the best differentiability support.
        Additionally, this function accepts another transformation tensor (:math:`(B, 4, 4)`), then the
        applied transformation will be merged int to the input transformation tensor and returned.

    Examples:
        >>> import torch
        >>> rng = torch.manual_seed(0)
        >>> input = torch.rand(1, 1, 3, 3, 3)
        >>> aug = RandomAffine3D((15., 20., 20.), p=1.)
        >>> aug(input), aug.transform_matrix
        (tensor([[[[[0.4503, 0.4763, 0.1680],
                   [0.2029, 0.4267, 0.3515],
                   [0.3195, 0.5436, 0.3706]],
        <BLANKLINE>
                  [[0.5255, 0.3508, 0.4858],
                   [0.0795, 0.1689, 0.4220],
                   [0.5306, 0.7234, 0.6879]],
        <BLANKLINE>
                  [[0.2971, 0.2746, 0.3471],
                   [0.4924, 0.4960, 0.6460],
                   [0.3187, 0.4556, 0.7596]]]]]), tensor([[[ 0.9722, -0.0603,  0.2262, -0.1381],
                 [ 0.1131,  0.9669, -0.2286,  0.1486],
                 [-0.2049,  0.2478,  0.9469,  0.0102],
                 [ 0.0000,  0.0000,  0.0000,  1.0000]]]))

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

    NFg      ?degrees	translatescaleshearsresamplesame_on_batchalign_cornerspkeepdimreturnc
           
         sR   t  j|||	d || _|| _|| _|| _t||d| _t	
||||| _d S )N)r   r   r   )r   r   )super__init__r   r   r   r   r	   getflagsrgAffineGenerator3D_param_generator)
selfr   r   r   r   r   r   r   r   r   	__class__ \/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/_3d/geometric/affine.pyr   f   s   "zRandomAffine3D.__init__inputparamsr   c                 C   sd   t |d |d |d |d t|d t|d t|d t|d t|d	 t|d
 
|}|S )Ntranslationscenterr   anglessxysxzsyxsyzszxszy)r   r   tor    r%   r&   r   	transformr#   r#   r$   compute_transformation   s   





z%RandomAffine3D.compute_transformationr2   c                 C   sj   t |tstdt| t||d d d dd d f |jd |jd |jd f|d j |d dS )	Nz.Expected the transform to be a Tensor. Gotcha    r   r   )r   )
isinstancer
   	TypeErrortyper   shapenamelowerr1   r#   r#   r$   apply_transform   s   
zRandomAffine3D.apply_transform)N)__name__
__module____qualname____doc__r	   BILINEARr<   r   r
   floatr   r   strintboolr   r   r   r3   r>   __classcell__r#   r#   r!   r$   r      s    S
$	
6






 !*+

r   N)typingr   r   r   r   r   kornia.augmentationr   r   &kornia.augmentation._3d.geometric.baser   kornia.constantsr	   kornia.corer
   kornia.geometryr   r   r   r   r#   r#   r#   r$   <module>   s   