o
    oiD                     @   s   d dl 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m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 dd
lmZ dgZG dd deZG dd deeZ dede	j!de	j!fddZ"dS )    )AnyDictIteratorListOptionalTupleUnioncastN)_AugmentationBase)override_parameters)ImageModuleModuleTensor	as_tensor)ImageModuleMixIneye_like   )ImageSequentialBase)	ParamItemImageSequentialc                   @   sX   e Zd ZU dZeed< edefddZejddeddfd	dZd
e	ddfddZ
dS )ImageModuleForSequentialMixInF_disable_featuresreturnc                 C   s   | j S Nr   )self r   W/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/container/image.pydisable_features&   s   z.ImageModuleForSequentialMixIn.disable_featuresTvalueNc                 C   s
   || _ d S r   r   )r   r    r   r   r   r   *      
argsc                 G   s    |D ]}t |tfrd|_qd S )NT)
isinstancer   r   )r   r"   argr   r   r   disable_item_features.   s
   z3ImageModuleForSequentialMixIn.disable_item_featuresT)__name__
__module____qualname__r   bool__annotations__propertyr   setterr   r%   r   r   r   r   r   #   s   
 r   c                       s  e Zd ZdZdddddddddedee d	ee d
eeee	eef f dee
e  dedededdf fddZd
eeee	eef f dedee	eef ef fddZd3dede	ee	eef  ef fddZdee	eef  de
e fddZd4dee
e  dee	eef  fddZdejde
e fdd Zd!edefd"d#Z			d5d!edee
e  d$ed%eeeef  dee f
d&d'Zd3d(edefd)d*Zdd+d,d-ed.ee
e  d/ed0edef
 fd1d2Z  ZS )6r   a  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 probability 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 = 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),
        ...     kornia.enhance.Invert(),
        ...     kornia.augmentation.RandomMixUpV2(p=1.0),
        ...     same_on_batch=True,
        ...     random_apply=10,
        ... )
        >>> out = aug_list(input)
        >>> out.shape
        torch.Size([2, 3, 5, 6])

        Reproduce with provided params.
        >>> out2 = aug_list(input, params=aug_list._params)
        >>> torch.equal(out, out2)
        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raiseT)same_on_batchkeepdimrandom_applyrandom_apply_weightsif_unsupported_opsr%   disable_sequential_featuresr"   r/   r0   r1   r2   r3   r%   r4   r   c          	         s   |r| j |  |rd| _t j|||d | |t|| _|d ur:t|t| kr:tdt| dt|  dt|pDt	
t| f| _|| _d S )NT)r/   r0   zUThe length of `random_apply_weights` must be as same as the number of operations.Got z and .)r%   r   super__init___read_random_applylenr1   
ValueErrorr   torchonesr2   r3   )	r   r/   r0   r1   r2   r3   r%   r4   r"   	__class__r   r   r7   t   s    

zImageSequential.__init__
max_lengthc                 C   sB  t |tfr|du rd}njt |tfr|du r||d f}nYt |tfr+||d f}nLt |tfrRt|dkrRt |d tfrRt |d tfrR|d |d d f}n%t |tfrot|dkrot |d tfro|d |d f}ntd| d|durt |tfrt|dkrt |d tfrt |d tfstd| d|S )	z'Process the scenarios for random apply.FTr      r   zNon-readable random_apply. Got r5   z"Expect a tuple of (int, int). Got )r#   r*   inttupler9   r:   AssertionError)r   r1   r?   r   r   r   r8      s6   
(
z"ImageSequential._read_random_applywith_mixc                 C   s   t | jtrttjg | jdR   }n
tdt| j | j	
 }| |  }d||< tj||||  kd}d}|rst|dkrstdt|t| t|  k  rst|   d|d< |tt| }d}| ||fS )	a
  Get a forward sequence when random apply is in need.

        Args:
            with_mix: if to require a mix augmentation for the sequence.

        Note:
            Mix augmentations (e.g. RandomMixUp) will be only applied once even in a random forward.

        )r   z'random apply should be a tuple. Gotcha r   )replacementFr   T)r#   r1   rB   rA   r;   randintitem	TypeErrortyper2   cloneget_mix_augmentation_indicesnamed_childrenmultinomialsumr9   randr*   floatrandpermget_children_by_indices)r   rD   num_samplesmultinomial_weightsmix_indicesindices	mix_addedr   r   r   get_random_forward_sequence   s$   
 
&z+ImageSequential.get_random_forward_sequencenamed_modulesc                 C   s   dd t |D S )zGet all the mix augmentations since they are label-involved.

        Special operations needed for label-involved augmentations.
        c                 S   s$   g | ]\}\}}t |tjr|qS r   )r#   KMixAugmentationBaseV2).0idx_childr   r   r   
<listcomp>   s   $ z@ImageSequential.get_mix_augmentation_indices.<locals>.<listcomp>)	enumerate)r   rZ   r   r   r   rL      s   z,ImageSequential.get_mix_augmentation_indicesparamsc                 C   sZ   |d u r(|  |  }| jr|  d S t|dkr$tdt| d|  S | |S )Nr   r   zOMultiple mix augmentation is prohibited without enabling random_apply.Detected z mix augmentations.)rL   rM   r1   rY   r9   r:   get_children_by_params)r   rc   rV   r   r   r   get_forward_sequence   s   
z$ImageSequential.get_forward_sequencebatch_shapec                 C   sd   |   }g }|D ]'\}}t|ttjtfr ||}t||}nt|d }t||}|	| q|S r   )
re   r#   r
   r[   r\   r   forward_parametersr   _get_new_batch_shapeappend)r   rf   rZ   rc   namemodule	mod_paramparamr   r   r   rg      s   


z"ImageSequential.forward_parametersinputc                 C   s
   t d|S )zReturn identity matrix.   r   )r   rn   r   r   r   identity_matrix   r!   zImageSequential.identity_matrix	recompute
extra_argsc              	   C   s  |du rt d|du ri }| |}d}t||dur|ng D ]\\}}}	t|tjfrt|	jtr|j}
z|	|}W n	 t
yF   Y nw |rZt|j|dd}|||	j|}n|jdurjt|j|j|jd}nt| d|du rw|n|| }|||
}|jr|
|jkr| }q t|tfrt|tjfr|st|j|j|jd}ntttt  |	j}|j||||d}|du r||n|}|du r|n|| }q |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.
            extra_args: Optional dictionary of extra arguments with specific options for different input types.
        Nzrequires params to be provided.F)in_place)devicedtypez3._transform_matrix is None while `recompute=False`.)rq   rr   )NotImplementedErrorre   zipr#   r[   GeometricAugmentationBase2Ddatadictshapetransform_tensorr:   r   flagsgenerate_transformation_matrix_transform_matrixr   rt   ru   RuntimeErrortransform_output_tensorr0   squeezer   AugmentationSequentialr	   r   r   r   get_transformation_matrixrp   )r   rn   rc   rq   rr   rZ   res_matr_   rk   rm   	ori_shaper}   matmaybe_param_data_matr   r   r   r      sH   
"
z)ImageSequential.get_transformation_matrixstrictc                 C   sT   |   D ]#}t|tfr||s dS t|tfrqt|tjr"q|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 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)childrenr#   r   is_intensity_onlyr[   IntensityAugmentationBase2D)r   r   r$   r   r   r   r   8  s   z!ImageSequential.is_intensity_onlytensorinput_names_to_handleoutput_typeinputsr   r   kwargsc                   sb   | j s&| j||dt j}||i |}|dkr!| || _|S || _|S t j|i |}|S )a  Overwrite the __call__ function to handle various inputs.

        Args:
            inputs: Inputs to operate on.
            input_names_to_handle: List of input names to convert, if None, handle all inputs.
            output_type: Desired output type ('tensor', 'numpy', or 'pil').
            kwargs: Additional arguments.

        Returns:
            Callable: Decorated function with converted input and output types.

        r   r   )r   convert_input_outputr6   __call___detach_tensor_to_cpu_output_image)r   r   r   r   r   decorated_forwardr   r=   r   r   r   P  s   zImageSequential.__call__r&   r   )NFN)r'   r(   r)   __doc__r   r   r*   r   rA   r   r   rQ   strr7   r8   r   rY   rL   r   re   r;   Sizerg   r   rp   r   r   r   r   r   __classcell__r   r   r=   r   r   4   s    B
	

("%(

:
rm   rf   r   c                 C   s   | j }|du r	|S t|tr|D ]}t||}q|S d|v rT|dd}|dur?| dkr2| n|d  }|dkr>|S n|S t|}|d d |dd< t|S |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`.

    Noutput_size
batch_probr   r   g      ?)	ry   r#   listrh   getnumelrH   r;   r   )rm   rf   ry   pr   probnew_batch_shaper   r   r   rh   r  s&   
 
rh   )#typingr   r   r   r   r   r   r   r	   r;   kornia.augmentationaugmentationr[   kornia.augmentation.baser
   kornia.augmentation.utilsr   kornia.corer   r   r   r   kornia.core.moduler   kornia.utilsr   baser   rc   r   __all__r   r   r   rh   r   r   r   r   <module>   s    (  @