o
    oiV                     @   s   d dl mZ d dlmZmZmZmZmZmZ d dl	Z	d dl
mZmZmZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZmZmZ d d	lmZ d d
lmZ d dlm Z  eeeeef f Z!dededefddZ"G dd deZ#G dd de#Z$dS )    )Enum)AnyCallableDictOptionalTupleUnionN)	BernoulliDistributionRelaxedBernoulli)RandomGeneratorBase)_adapted_rsampling_adapted_sampling_transform_output_shapeoverride_parameters)ImageModule)Tensortensorzeros)Boxes)	Keypoints)is_autocast_enabledselfinputreturnc                 G   s   t dt| j d)zaDefine the computation performed at every call.

    Should be overridden by all subclasses.
    zModule [z3] is missing the required "apply_tranform" function)NotImplementedErrortype__name__r   r    r   L/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/base.py_apply_transform_unimplemented,   s   r!   c                       s  e Zd ZU dZdZ				d7dedededed	d
f
 fddZeZ	e
def ed< deded	d f fddZd	efddZded	efddZd
dddedee ded	efddZded	d
fddZd ed!eedf d	efd"d#Zd$eedf d	eeef fd%d&Zd'ejd(ejd	d
fd)d*Zd$eedf dededed	ef
d+d,Z	
	
d8d-eeeef  d.eeeef  ded	eeeef eeef f fd/d0Zd$eedf d	eeef fd1d2Z ded-eeef d.eeef d	efd3d4Z!d9ded-eeeef  ded	efd5d6Z"  Z#S ):_BasicAugmentationBasea  _BasicAugmentationBase base class for customized augmentation implementations.

    Plain augmentation base class without the functionality of transformation matrix calculations.
    By default, the random computations will be happened on CPU with ``torch.get_default_dtype()``.
    To change this behaviour, please use ``set_rng_device_and_dtype``.

    For automatically generating the corresponding ``__repr__`` with full customized parameters, you may need to
    implement ``_param_generator`` by inheriting ``RandomGeneratorBase`` for generating random parameters and
    put all static parameters inside ``self.flags``. You may take the advantage of ``PlainUniformGenerator`` to
    generate simple uniform parameters with less boilerplate code.

    Args:
        p: probability for applying an augmentation. This param controls the augmentation probabilities element-wise.
        p_batch: probability for applying an augmentation to a batch. This param controls the augmentation
          probabilities batch-wise.
        same_on_batch: apply the same transformation across the batch.
        keepdim: whether to keep the output shape the same as input ``True`` or broadcast it to
          the batch form ``False``.

    F      ?      ?pp_batchsame_on_batchkeepdimr   Nc                    s   t    || _|| _|| _|| _i | _|  |  |dks |dkr&t| j| _|dks.|dkr4t| j| _	d | _
i | _| tdt  d S )Ng        r$   cpu)super__init__r%   r&   r'   r(   _paramsr	   _p_gen_p_batch_gen_param_generatorflagsset_rng_device_and_dtypetorchdeviceget_default_dtype)r   r%   r&   r'   r(   	__class__r   r    r+   N   s   
z_BasicAugmentationBase.__init__.apply_transformargskwargsc                    s:   t jjj|i |\}}}}| || t j|i |S )z9Set the device and dtype for the random number generator.)r2   _C_nn	_parse_tor1   r*   to)r   r8   r9   r3   dtype_r5   r   r    r=   g   s   z_BasicAugmentationBase.toc                 C   s   d| j  d| j d| j }t| jtr| jd| }| j D ]!\}}t|tr8|d| d|j	
  7 }q!|d| d| 7 }q!| jj d| dS )Nzp=z
, p_batch=z, same_on_batch=z, =())r%   r&   r'   
isinstancer/   r   r0   itemsr   namelowerr6   r   )r   txtkvr   r   r    __repr__m   s   
z_BasicAugmentationBase.__repr__r   c                 C      |S Nr   r   r   r   r    __unpack_input__x   s   z'_BasicAugmentationBase.__unpack_input__Tshapematch_channelrO   rP   c                C      t )zStandardize input tensors.r   )r   r   rO   rP   r   r   r    transform_tensor{      z'_BasicAugmentationBase.transform_tensorc                 C   rQ   )z3Check if the input tensor is formatted as expected.rR   r   r   r   r    validate_tensor   s   z&_BasicAugmentationBase.validate_tensoroutputoutput_shapec                 C   s   | j rt||S |S )zStandardize output tensors.)r(   r   )r   rV   rW   r   r   r    transform_output_tensor   s   z._BasicAugmentationBase.transform_output_tensorbatch_shapec                 C   s   | j d ur|  || jS i S rL   )r/   r'   )r   rY   r   r   r    generate_parameters   s   
z*_BasicAugmentationBase.generate_parametersr3   r>   c                 C   s,   || _ || _| jdur| j|| dS dS )zChange the random generation device and dtype.

        Note:
            The generated random numbers are not reproducible across different devices and dtypes.

        N)r3   r>   r/   r1   )r   r3   r>   r   r   r    r1      s
   
z/_BasicAugmentationBase.set_rng_device_and_dtypec                 C   s   |dkrt dd }n|dkrt d}nt| jtfr#td| j|}ntd| j|}| dkri|dkr=t |d d }n'|dkrHt |d }nt| jtfrZt|d f| j|}n
t|d f| j|}|| }n||d }t	|j
dkr{|d S |S )N   r   )r[      ).r   )r   rC   r.   r   r   r   sumr-   repeatlenrO   )r   rY   r%   r&   r'   
batch_prob	elem_probr   r   r    __batch_prob_generator__   s(   

z/_BasicAugmentationBase.__batch_prob_generator__paramsr0   c                 K   s|   d|v r|d nd}|d u r| j n|}|d u r| jn|}|r)t||dd}|| _ n
|| _ t||dd}t||dd}||fS )Nsave_kwargsFT)in_place)r,   r0   r   )r   rc   r0   r9   rd   r   r   r    #_process_kwargs_to_params_and_flags   s   z:_BasicAugmentationBase._process_kwargs_to_params_and_flagsc                 C   s~   |  || j| j| j}|dk}| tt| 	 g|dd  R }|d u r+i }||d< t
|tjd}|d|i |S )Nr#   r[   r`   )r>   forward_input_shape)rb   r%   r&   r'   rZ   r2   Sizeintr]   itemr   longupdate)r   rY   r`   to_applyr,   
input_sizer   r   r    forward_parameters   s   ,z)_BasicAugmentationBase.forward_parametersc                 C   s   |  |||S rL   )r7   )r   r   rc   r0   r   r   r    
apply_func   s   z!_BasicAugmentationBase.apply_funcc           	      K   s   |  |}|j}| |}|j}|du r| |}d|vr(tdg|d  |d< | j|| jfi |\}}| |||}| jrE| 	||S |S )a  Perform forward operations.

        Args:
            input: the input tensor.
            params: the corresponding parameters for an operation.
                If None, a new parameter suite will be generated.
            **kwargs: key-value pairs to override the parameters and flags.

        Note:
            By default, all the overwriting parameters in kwargs will not be recorded
            as in ``self._params``. If you wish it to be recorded, you may pass
            ``save_kwargs=True`` additionally.

        Nr`   Tr   )
rM   rO   rS   ro   r   rf   r0   rp   r(   rX   )	r   r   rc   r9   	in_tensorinput_shaperY   r0   rV   r   r   r    forward   s   


z_BasicAugmentationBase.forward)r#   r$   FF)NNrL   )$r   
__module____qualname____doc__ONNX_EXPORTABLEfloatboolr+   r!   r7   r   r   __annotations__r   r=   strrJ   rM   r   rS   rU   r   ri   rX   r   rZ   r2   r3   r>   r1   rb   rf   ro   rp   rs   __classcell__r   r   r5   r    r"   4   s|   
 

"

%
"*0r"   c                   @   s  e Zd Z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ef dee def
d
dZ
	d*dedeeef deeef dee dedefddZ	d*dedeeef deeef dee dedefddZ	d*dedeeef deeef dee dedefddZ	d*dedeeef deeef dee dedefddZ	d*dedeeef deeef dee de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ef dee 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ef dee 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ef dee 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ef dee def
d%d&Z	d*d'edeeef deeeef  defd(d)ZdS )+_AugmentationBasea  _AugmentationBase base class for customized augmentation implementations.

    Advanced augmentation base class with the functionality of transformation matrix calculations.

    Args:
        p: probability for applying an augmentation. This param controls the augmentation probabilities
          element-wise for a batch.
        p_batch: probability for applying an augmentation to a batch. This param controls the augmentation
          probabilities batch-wise.
        same_on_batch: apply the same transformation across the batch.
        keepdim: whether to keep the output shape the same as input ``True`` or broadcast it
          to the batch form ``False``.

    Nr   rc   r0   	transformr   c                 C   rQ   rL   rR   r   r   rc   r0   r~   r   r   r    r7     rT   z!_AugmentationBase.apply_transformc                 C   rK   rL   r   r   r   r   r    apply_non_transform   s   	z%_AugmentationBase.apply_non_transformr9   c                 K   s  | j |d u r	| jn||fi |\}}|d }|dk}|j}| |}	| |	 | r6| j|	|||d}
n@| sD| j|	|||d}
n2| j|	|||d}
| j|	| |||d u rZ|n|| d}t	 ro|

|j}
|
|j}|
|f|}
| jr~t|
|n|
}
t	 r|

|j}
|
S Nr`   r#   r~   )rf   r,   rO   rS   rU   allr7   anyr   r   r   r>   	index_putr(   r   )r   r   rc   r0   r~   r9   r`   rm   	ori_shaperq   rV   appliedr   r   r    transform_inputs+  s:   


z"_AugmentationBase.transform_inputsc                 K   s   | j |d u r	| jn||fi |\}}|d }|dk}|j}|d }	| j||	dd}
| |
 | r=| j|
|||d}n1| sK| j|
|||d}n#| j|
|||d}| j|
| |||d u ra|n|| d}|	|f|}| j
rzt|||	d}|S |}|S )Nr`   r#   rg   FrN   r   )reference_shape)rf   r,   rO   rS   rU   r   apply_transform_maskr   apply_non_transform_maskr   r(   r   )r   r   rc   r0   r~   r9   r`   rm   r   rO   rq   rV   r   r   r   r    transform_masksU  s6   

z!_AugmentationBase.transform_masksc           
      K   s   t |tstdt| d| j|d u r| jn||fi |\}}|d }|dk}|  r;| j||||d}|S |	 sJ| j
||||d}|S | j
||||d}| j|| |||d u r`|n|| d}	t ru||j}|	|j}	||f|	}|S )NzOnly `Boxes` is supported. Got .r`   r#   r   )rC   r   RuntimeErrorr   rf   r,   ry   r   apply_transform_boxr   apply_non_transform_boxr   r>   r   
r   r   rc   r0   r~   r9   r`   rm   rV   r   r   r   r    transform_boxesy  s6   

z!_AugmentationBase.transform_boxesc           
      K   s   t |tstdt| d| j|d u r| jn||fi |\}}|d }|dk}| r9| j||||d}|S | sH| j	||||d}|S | j	||||d}| j|| |||d u r^|n|| d}	t
 rs||j}|	|j}	||f|	}|S )Nz#Only `Keypoints` is supported. Got r   r`   r#   r   )rC   r   r   r   rf   r,   r   apply_transform_keypointr   apply_non_transform_keypointr   r>   r   r   r   r   r    transform_keypoints  s6   

z%_AugmentationBase.transform_keypointsc           
      K   s   | j |d u r	| jn||fi |\}}|d }|dk}| r*| j||||d}|S | s9| j||||d}|S | j||||d}| j|| |||d u rO|n|| d}	||f|	}|S r   )rf   r,   r   apply_transform_classr   apply_non_transform_classr   r   r   r   r    transform_classes  s,   

z#_AugmentationBase.transform_classesc                 C   rQ   )zMProcess masks corresponding to the inputs that are no transformation applied.rR   r   r   r   r    r     rT   z*_AugmentationBase.apply_non_transform_maskc                 C   rQ   )z?Process masks corresponding to the inputs that are transformed.rR   r   r   r   r    r     rT   z&_AugmentationBase.apply_transform_maskc                 C   rK   )zMProcess boxes corresponding to the inputs that are no transformation applied.r   r   r   r   r    r     rT   z)_AugmentationBase.apply_non_transform_boxc                 C   rQ   )z?Process boxes corresponding to the inputs that are transformed.rR   r   r   r   r    r     rT   z%_AugmentationBase.apply_transform_boxc                 C   rK   )zQProcess keypoints corresponding to the inputs that are no transformation applied.r   r   r   r   r    r     rT   z._AugmentationBase.apply_non_transform_keypointc                 C   rQ   )zCProcess keypoints corresponding to the inputs that are transformed.rR   r   r   r   r    r     rT   z*_AugmentationBase.apply_transform_keypointc                 C   rK   )zRProcess class tags corresponding to the inputs that are no transformation applied.r   r   r   r   r    r     rT   z+_AugmentationBase.apply_non_transform_classc                 C   rQ   )zDProcess class tags corresponding to the inputs that are transformed.rR   r   r   r   r    r   $  rT   z'_AugmentationBase.apply_transform_classrq   c                 C   s    |d u r| j }| |||}|S rL   )r0   r   )r   rq   rc   r0   rV   r   r   r    rp   .  s   z_AugmentationBase.apply_funcrL   )r   rt   ru   rv   r   r   r{   r   r   r7   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rp   r   r   r   r    r}     s   








/


)


*


(


"
























r}   )%enumr   typingr   r   r   r   r   r   r2   torch.distributionsr	   r
   r   $kornia.augmentation.random_generatorr   kornia.augmentation.utilsr   r   r   r   kornia.corer   Moduler   r   r   kornia.geometry.boxesr   kornia.geometry.keypointsr   kornia.utilsr   TensorWithTransformMatr!   r"   r}   r   r   r   r    <module>   s      S