o
    oi?;                     @   s   d dl 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 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ListOptionalTupleUnionN)random_generator)GeometricAugmentationBase2D)Resample)Tensorpadtensor)Boxes)	Keypoints)crop_by_indicescrop_by_transform_matget_perspective_transformc                       s  e Zd ZdZddddejjdddddf
d	eeef d
e	e
eeeef eeeeef f  de	e dedede
eeef dedededededdf fddZd5deedf de	eeef  dee fddZ	d6ded
e	ee  de	eeef  defddZdedeeef deeef defd d!Z	d5dedeeef deeef d"e	e def
 fd#d$Z	d5dedeeef deeef d"e	e def
 fd%d&Z	d5dedeeef deeef d"e	e def
d'd(Z		d6dedeeef d"e	e d	e	eeef  def
d)d*Z	d5dedeeef deeef d"e	e d+edef fd,d-Z	d5dedeeef deeef d"e	e d+edef fd.d/Z	d5dedeeef deeef d"e	e d+edef fd0d1Zd2eedf deeef f fd3d4Z  Z S )7
RandomCropa  Crop random patches of a tensor image on a given size.

    .. image:: _static/img/RandomCrop.png

    Args:
        size: Desired output size (out_h, out_w) of the crop.
            Must be Tuple[int, int], then out_h = size[0], out_w = size[1].
        padding: Optional padding on each border
            of the image. Default is None, i.e no padding. If a sequence of length
            4 is provided, it is used to pad left, top, right, bottom borders
            respectively. If a sequence of length 2 is provided, it is used to
            pad left/right, top/bottom borders, respectively.
        pad_if_needed: It will pad the image if smaller than the
            desired size to avoid raising an exception. Since cropping is done
            after padding, the padding seems to be done at a random offset.
        fill: Pixel fill value for constant fill. Default is 0. If a tuple of
            length 3, it is used to fill R, G, B channels respectively.
            This value is only used when the padding_mode is constant.
        padding_mode: Type of padding. Should be: constant, reflect, replicate.
        resample: the interpolation mode.
        same_on_batch: apply the same transformation across the batch.
        align_corners: interpolation flag.
        p: probability of applying the transformation for the whole batch.
        keepdim: whether to keep the output shape the same as input (True) or broadcast it
                 to the batch form (False).
        cropping_mode: The used algorithm to crop. ``slice`` will use advanced slicing to extract the tensor based
                       on the sampled indices. ``resample`` will use `warp_affine` using the affine transformation
                       to extract and resize at once. Use `slice` for efficiency, or `resample` for proper
                       differentiability.

    Shape:
        - Input: :math:`(C, H, W)` or :math:`(B, C, H, W)`, Optional: :math:`(B, 3, 3)`
        - Output: :math:`(B, C, out_h, out_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, 3, 3)`), then the
        applied transformation will be merged int to the input transformation tensor and returned.

    Examples:
        >>> import torch
        >>> _ = torch.manual_seed(0)
        >>> inputs = torch.arange(1*1*3*3.).view(1, 1, 3, 3)
        >>> aug = RandomCrop((2, 2), p=1., cropping_mode="resample")
        >>> out = aug(inputs)
        >>> out
        tensor([[[[3., 4.],
                  [6., 7.]]]])
        >>> aug.inverse(out, padding_mode="replicate")
        tensor([[[[3., 4., 4.],
                  [3., 4., 4.],
                  [6., 7., 7.]]]])

    To apply the exact augmenation again, you may take the advantage of the previous parameter state:
        >>> input = torch.randn(1, 3, 32, 32)
        >>> aug = RandomCrop((2, 2), p=1., cropping_mode="resample")
        >>> (aug(input) == aug(input, params=aug._params)).all()
        tensor(True)

    NFr   constantT      ?slicesizepaddingpad_if_neededfillpadding_moderesamplesame_on_batchalign_cornerspkeepdimcropping_modereturnc              	      sB   t  jd||	|
d t|| _|||||t|||d| _d S )Nr   )r   r   p_batchr    )r   r   r   r   r   r   r   r!   )super__init__rgCropGenerator_param_generatorr
   getflags)selfr   r   r   r   r   r   r   r   r   r    r!   	__class__ Z/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/_2d/geometric/crop.pyr%   ]   s   zRandomCrop.__init__shape.r*   c                 C   s  |d u r| j n|}t|dkrtd| dg d}|d d urt|d tr0|d gd }nVt|d trVt|d dkrV|d d |d d |d d |d d g}n0t|d tr|t|d dkr||d d |d d |d d |d d	 g}n
td
|d  d|d r|d d |d  |d d |d  f}|d dkrt|d |d |d< t|d |d |d< |d dkrt|d |d |d< t|d |d	 |d	< |S )N   zExpected BCHW. Got .)r   r   r   r   r      r         z9Expect `padding` to be a scalar, or length 2/4 list. Got r   r   )r*   lenAssertionError
isinstanceinttupleRuntimeErrormax)r+   r0   r*   r   needed_paddingr.   r.   r/   compute_paddingy   s*   ..(zRandomCrop.compute_paddinginputc                 C   sJ   |d u r| j n|}|d u r| |j}t|r#t|||d |d d}|S )Nr   r   )valuemode)r*   r@   r0   anyr   )r+   rA   r   r*   r.   r.   r/   precrop_padding   s   zRandomCrop.precrop_paddingparamsc                 C   s   |d dv rV|d  |}|d  |}t||}|ddsT|jdd  \}}|d \}	}
|	|ks6|
|krT|d d d	d	f  |
| 9  < |d d d
d
f  |	| 9  < |S td|d  d)Nr!   )r   r   srcdstr   Fr6   r   r   r4   Not supported type: r2   )tor   r)   r0   NotImplementedError)r+   rA   rF   r*   rG   rH   	transformhwh_outw_outr.   r.   r/   compute_transformation   s   
z!RandomCrop.compute_transformationrL   c                    s0   |d j |jd}||}t j||||dS )QProcess keypoints corresponding to the inputs that are no transformation applied.padding_sizedevicerA   rF   r*   rL   )rJ   rU   r   r$   apply_transform_keypointr+   rA   rF   r*   rL   rS   r,   r.   r/   rW      s   
z#RandomCrop.apply_transform_keypointc                    s&   |d }| |}t j||||dS )rR   rS   rV   )r   r$   apply_transform_boxrX   r,   r.   r/   rY      s   
zRandomCrop.apply_transform_boxc                 C   s  d }d|v rt |d tr|d jdd   }| |||}|d u r)| jn|}|d dkrrt |ts@tdt	| d|d d	krId
}n|d dkrRd}n|d dkr[d}n|d }t
|||d |d j ||d dS |d dkrt||d |d S td|d  d)NrS   r   dimr!   r   *Expected the `transform` be a Tensor. Got r2   r   r   zeros	replicateborderreflect
reflectionr   r   )rC   r   r   r   rG   rI   )r:   r   uniquecpusqueezetolistrE   r*   	TypeErrortyper   namelowerr   rK   )r+   rA   rF   r*   rL   rS   r   r.   r.   r/   apply_transform   s4   
zRandomCrop.apply_transformc                 C   s   |d dkrt d|d  d|d u rtdt|ts'tdt| d|d dkr0d	}n|d d
kr9d}n|d dkrBd}n|d }t||d d d dd d f ||d j ||d dS )Nr!   r   =`inverse` is only applicable for resample cropping mode. Got r2   z#`size` has to be a tuple. Got None.r\   r   r   r]   r^   r_   r`   ra   r3   r   )r   r   )	rK   r=   r:   r   rf   rg   r   rh   ri   )r+   rA   r*   rL   r   r   r.   r.   r/   inverse_transform   s.   
zRandomCrop.inverse_transformkwargsc                    s   |d dkrt d|d  dt j||||fi |}|d  s%|S |d jdd   }|d  |d	  |d
  |d  g}| ||S )Nr!   r   rk   r2   
batch_probrS   r   rZ   r4   r3   r5   )	rK   r$   inverse_inputsallrb   rc   rd   re   rE   )r+   rA   rF   r*   rL   rm   outrS   r,   r.   r/   ro     s   $zRandomCrop.inverse_inputsc                    sX   |d dkrt d|d  dt j||||fi |}|d  s%|S ||d S )Nr!   r   rk   r2   rn   rS   )rK   r$   inverse_boxesrp   unpadr+   rA   rF   r*   rL   rm   outputr,   r.   r/   rr     s   zRandomCrop.inverse_boxesc                    sb   |d dkrt d|d  dt j||||fi |}|d  s%|S ||d j|jdS )Nr!   r   rk   r2   rn   rS   rT   )rK   r$   inverse_keypointsrp   rs   rJ   rU   rt   r,   r.   r/   rv   -  s   zRandomCrop.inverse_keypointsbatch_shapec                    s   |  |}tg |d d |d |d  |d  |d |d  |d  R }tt|tjd|d d}t |}|	d|i |S )Nr3   r5   r   r4   )dtyper7   rS   )
r@   torchSizer   r<   longexpandr$   forward_parametersupdate)r+   rw   	input_padbatch_shape_newrS   _paramsr,   r.   r/   r}   @  s   

zRandomCrop.forward_parameters)N)NN)!__name__
__module____qualname____doc__r
   BILINEARrh   r   r;   r   r   boolstrfloatr%   r   r   r   r@   r   rE   rQ   r   rW   r   rY   rj   rl   ro   rr   rv   r}   __classcell__r.   r.   r,   r/   r      s   @
$	
0

*








&

&





.r   )typingr   r   r   r   r   r   ry   kornia.augmentationr   r&   &kornia.augmentation._2d.geometric.baser	   kornia.constantsr
   kornia.corer   r   r   kornia.geometry.boxesr   kornia.geometry.keypointsr   kornia.geometry.transformr   r   r   r   r.   r.   r.   r/   <module>   s    