a
    dK                     @   s   d dl mZ d dlmZmZmZmZmZmZm	Z	m
Z
mZ d dlZd dlmZ d dlmZ d dlZd dl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gZ"G dd deZ#eej$ej$dddZ%dS )    )zip_longest)	AnyDictIteratorListOptionalTupleTypeUnioncastN)Tensor)GeometricAugmentationBase2DIntensityAugmentationBase2DMixAugmentationBase
RandomCrop)MixAugmentationBaseV2)_AugmentationBase)	ParamItemSequentialBase)ApplyInverseInterfaceInputApplyInverse)override_parametersImageSequentialc                       sX  e Zd ZdZdddddddejee ee ee ee	ee
e	e	f f eee  edd fddZee	ee
e	e	f f e	ee
e	e	f ef d	d
dZd0ee
ee
eejf  ef dddZee
eejf  ee	 dddZd1eee  ee
eejf  dddZeee eej eeeef e
eee f dddZejee dddZee edddZd2eee eee
eef f ddd Zed!d"d#Zddi feeee  eeeef ee d$d%d&Zd3eed'd(d)Z di feeee  eeef ed*d+d,Z!ddi feee eee  eeef eee
eef f d-d.d/Z"  Z#S )4r   aT  Sequential for creating kornia image processing pipeline.

    Args:
        *args : a list of kornia augmentation and image operation modules.
        same_on_batch: apply the same transformation across the batch.
            If None, it will not overwrite the function-wise settings.
        keepdim: whether to keep the output shape the same as input (True) or broadcast it
            to the batch form (False). If None, it will not overwrite the function-wise settings.
        random_apply: randomly select a sublist (order agnostic) of args to
            apply transformation. The selection probablity aligns to the ``random_apply_weights``.
            If int, a fixed number of transformations will be selected.
            If (a,), x number of transformations (a <= x <= len(args)) will be selected.
            If (a, b), x number of transformations (a <= x <= b) will be selected.
            If True, the whole list of args will be processed as a sequence in a random order.
            If False, the whole list of args will be processed as a sequence in original order.
        random_apply_weights: a list of selection weights for each operation. The length shall be as
            same as the number of operations. By default, operations are sampled uniformly.

    .. note::
        Transformation matrix returned only considers the transformation applied in ``kornia.augmentation`` module.
        Those transformations in ``kornia.geometry`` will not be taken into account.

    Examples:
        >>> _ = torch.manual_seed(77)
        >>> import kornia
        >>> input, label = torch.randn(2, 3, 5, 6), torch.tensor([0, 1])
        >>> aug_list = ImageSequential(
        ...     kornia.color.BgrToRgb(),
        ...     kornia.augmentation.ColorJiggle(0.1, 0.1, 0.1, 0.1, p=1.0),
        ...     kornia.filters.MedianBlur((3, 3)),
        ...     kornia.augmentation.RandomAffine(360, p=1.0),
        ...     kornia.enhance.Invert(),
        ...     kornia.augmentation.RandomMixUp(p=1.0),
        ...     same_on_batch=True,
        ...     random_apply=10,
        ... )
        >>> out, lab = aug_list(input, label=label)
        >>> lab
        tensor([[0.0000, 1.0000, 0.1214],
                [1.0000, 0.0000, 0.1214]])
        >>> out.shape
        torch.Size([2, 3, 5, 6])

        Reproduce with provided params.
        >>> out2, lab2 = aug_list(input, label=label, params=aug_list._params)
        >>> torch.equal(out, out2), torch.equal(lab, lab2)
        (True, True)

    Perform ``OneOf`` transformation with ``random_apply=1`` and ``random_apply_weights`` in ``ImageSequential``.

        >>> import kornia
        >>> input = torch.randn(2, 3, 5, 6)
        >>> aug_list = ImageSequential(
        ...     kornia.color.BgrToRgb(),
        ...     kornia.augmentation.ColorJiggle(0.1, 0.1, 0.1, 0.1, p=1.0),
        ...     kornia.filters.MedianBlur((3, 3)),
        ...     kornia.augmentation.RandomAffine(360, p=1.0),
        ...     random_apply=1,
        ...     random_apply_weights=[0.5, 0.3, 0.2, 0.5]
        ... )
        >>> out= aug_list(input)
        >>> out.shape
        torch.Size([2, 3, 5, 6])
    NFraise)same_on_batchreturn_transformkeepdimrandom_applyrandom_apply_weightsif_unsupported_ops)argsr   r   r   r   r   r   returnc                   s   |d urt dt j||||d | |t|| _|d urnt|t| krnt dt| dt|  dt|ptt| f| _	d | _
t| _|| _d S )Nzh`return_transform` is deprecated. Please access `.transform_matrix` in `AugmentationSequential` instead.)r   r   r   zUThe length of `random_apply_weights` must be as same as the number of operations.Got z and .)
ValueErrorsuper__init___read_random_applylenr   torch	as_tensorZonesr   return_labelr   apply_inverse_funcr   )selfr   r   r   r   r   r   r    	__class__ l/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/augmentation/container/image.pyr%   Z   s$    
zImageSequential.__init__)r   
max_lengthr!   c                 C   sL  t |tfr|du rd}nt |tfr<|du r<||d f}nt |tfrV||d f}nt |tfrt|dkrt |d tfrt |d tfr|d |d d f}nJt |tfrt|dkrt |d tfr|d |d f}ntd| d|durHt |tfr8t|dkr8t |d tfr8t |d tfsHtd| d|S )	z'Process the scenarios for random apply.FT      r   zNon-readable random_apply. Got r"   z"Expect a tuple of (int, int). Got )
isinstanceboolinttupler'   r#   AssertionError)r,   r   r1   r/   r/   r0   r&   v   s:    

(


z"ImageSequential._read_random_applyT)with_mixr!   c                 C   s   t tjg | jdR   }| j }| |  }d||< tj	||||
  kd}d}|rt|dkrtdt|t| t|  k  rt	|   d|d< |tt| }d}| ||fS )zGet a forward sequence when random apply is in need.

        Note:
            Mix augmentations (e.g. RandomMixUp) will be only applied once even in a random forward.
        )r2   r   )replacementFr2   T)r6   r(   randintr   itemr   cloneget_mix_augmentation_indicesnamed_childrenZmultinomialsumr'   Zrandr5   floatZrandpermZget_children_by_indices)r,   r9   Znum_samplesZmultinomial_weightsmix_indicesindicesZ	mix_addedr/   r/   r0   get_random_forward_sequence   s     
&z+ImageSequential.get_random_forward_sequence)named_modulesr!   c                 C   s4   g }t |D ]"\}\}}t|tfr|| q|S )zGet all the mix augmentations since they are label-involved.

        Special operations needed for label-involved augmentations.
        )	enumerater4   r   append)r,   rF   rD   idx_childr/   r/   r0   r?      s
    z,ImageSequential.get_mix_augmentation_indices)paramsr!   c                 C   sZ   |d u rP|  |  }| jr(|  d S t|dkrHtdt| d|  S | |S )Nr   r2   zOMultiple mix augmentation is prohibited without enabling random_apply.Detected r"   )r?   r@   r   rE   r'   r#   Zget_children_by_params)r,   rL   rC   r/   r/   r0   get_forward_sequence   s    z$ImageSequential.get_forward_sequence)inputlabelmoduleparam
extra_argsr!   c                 C   s(   |d u r|  |j}| j|||||S N)get_submodulenamer+   Zapply_trans)r,   rN   rO   rP   rQ   rR   r/   r/   r0   apply_to_input   s    zImageSequential.apply_to_input)batch_shaper!   c                 C   s   |   }g }|D ]n\}}t|tr8||}t||}n2t|ttttfr`|	|}t||}n
t|d }t
||}|| q|S rS   )rM   r4   r   Zforward_parameters_precropr   r   r   r   r   forward_parameters_get_new_batch_shaperH   )r,   rW   rF   rL   rU   rP   Z	mod_paramrQ   r/   r/   r0   rX      s    




z"ImageSequential.forward_parametersc                 C   s,   |D ]"}|j ds |j dr dS qdS )zJCheck if current sequential contains label-involved operations like MixUp.ZRandomMixUp_ZRandomCutMix_TF)rU   
startswith)r,   rL   rQ   r/   r/   r0   contains_label_operations   s    z)ImageSequential.contains_label_operations)outputrO   r!   c                 C   s   | j r||fS |S rS   )r*   )r,   r\   rO   r/   r/   r0   __packup_output__   s    z!ImageSequential.__packup_output__)r!   c                 C   s   t d|S )zReturn identity matrix.   )korniaZeye_like)r,   rN   r/   r/   r0   identity_matrix   s    zImageSequential.identity_matrix)rN   rL   	recomputerR   r!   c              	   C   s  |du rt d| |}d}t||dur.|ng D ]\\}}}	t|tfr0t|ttfs0ttt	t
f |	j}
|
d }|j}z||}W n ty   Y n0 |r| |}t|j|dd}||| |	j|||< ntj|j|j|jd}|du r|n|| }|||}|jr||jkr| }q4t|tfr4t|tjjfrl|sltj|j|j|jd}n>ttt t!  |	j}|j"||||d}|du r||n|}|du r|n|| }q4|S )a+  Compute the transformation matrix according to the provided parameters.

        Args:
            input: the input tensor.
            params: params for the sequence.
            recompute: if to recompute the transformation matrix according to the params.
                default: False.
        Nzrequires params to be provided.
batch_probF)Zin_place)devicedtype)ra   rR   )#NotImplementedErrorrM   zipr4   r   r   r   r   r   strr   datashapeZtransform_tensorr#   r`   r   flagsZcompute_transformationr(   r)   Z_transform_matrixrc   rd   Ztransform_output_tensorr   Zsqueezer   r_   ZaugmentationZAugmentationSequentialr   r   r   get_transformation_matrix)r,   rN   rL   ra   rR   rF   Zres_matrJ   rP   rQ   ZpdataZto_applyZ	ori_shapematrj   Zmaybe_param_dataZ_matr/   r/   r0   rk      sD    
$

z)ImageSequential.get_transformation_matrix)strictr!   c                 C   sR   |   D ]D}t|tfr(||s( dS t|tfr6qt|trBq|r dS qdS )a  Check if all transformations are intensity-based.

        Args:
            strict: if strict is False, it will allow non-augmentation nn.Modules to be passed.
                e.g. `kornia.enhance.AdjustBrightness` will be recognized as non-intensity module
                if strict is set to True.

        Note: patch processing would break the continuity of labels (e.g. bbounding boxes, masks).
        FT)childrenr4   r   is_intensity_onlyr   )r,   rm   argr/   r/   r0   ro   6  s    

z!ImageSequential.is_intensity_only)rN   rL   rR   r!   c           	      C   s   |du r | j du rtd| j }tt| |ddd |ddd D ]\\}}}d}t|ttfrz||v rv|| n|}t|trqHt|tr|	 rqHt|tr|durt
tt t
t|j}|j|||d}qHt|tfrH| jj||||d}qHqH|S )zInverse transformation.

        Used to inverse a tensor according to the performed transformation by a forward pass, or with respect to
        provided parameters.
        NzrNo parameters available for inversing, please run a forward pass first or passing valid params into this function.r;   )rR   )_paramsr#   r   listrM   r4   r   r   r   ro   r   r   r   rh   inverser   r+   )	r,   rN   rL   rR   rU   rP   rQ   Zmaybe_paramZ
param_datar/   r/   r0   rs   M  s*    
4
zImageSequential.inverse)rN   rO   rL   rR   r!   c           
      C   s   |    |d u r0|}| j|dd\}}| |}| jd u rN|d upJ| || _|D ]`}| |j}	| j|||	||d\}}t|	t	t
ttfrt|j|	j}nt|jd }| | qR| ||S )N)r3      )Z	dim_range)rQ   rR   )Zclear_stateZautofill_dimrX   r*   r[   rT   rU   rV   r4   r   r   r   r   r   rq   Zupdate_paramsr]   )
r,   rN   rO   rL   rR   inprJ   Z	out_shaperQ   rP   r/   r/   r0   forwardq  s    

zImageSequential.forward)T)N)N)T)$__name__
__module____qualname____doc__nnModuler   r5   r
   r6   r   r   rB   rg   r%   r&   r   rE   r?   r   rM   r   r   r   rV   r(   SizerX   r[   r]   r`   rk   ro   rs   rv   __classcell__r/   r/   r-   r0   r      sx   D
("(
(

9'

)rQ   rW   r!   c                 C   sz   | j du r|S t| j tr2| j D ]}t||}q nDd| j v rv| j d d sN|S t|}| j d d |dd< t|}|S )zGet the new batch shape if the augmentation changes the image size.

    Note:
       Augmentations that change the image size must provide the parameter `output_size`.
    NZoutput_sizerb   r   )rh   r4   rr   rY   r(   r}   )rQ   rW   pZnew_batch_shaper/   r/   r0   rY     s    



rY   )&	itertoolsr   typingr   r   r   r   r   r   r	   r
   r   r(   Ztorch.nnr{   r   r_   Zkornia.augmentationr   r   r   r   Z kornia.augmentation._2d.mix.baser   Zkornia.augmentation.baser   Z"kornia.augmentation.container.baser   r   Z#kornia.augmentation.container.utilsr   r   Zkornia.augmentation.utilsr   __all__r   r}   rY   r/   r/   r/   r0   <module>   s    ,  t