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mZ 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mZmZ d d
lmZ dgZ G dd deZ!dS )    )AnyDictListOptionalTupleUnionN)random_generator)MixAugmentationBaseV2)DataKeyResample)Tensor	as_tensorconcatenatepadzeros)KORNIA_UNWRAP)Boxes)crop_by_indicescrop_by_transform_matget_perspective_transform)eye_likeRandomMosaicc                       sL  e Zd ZdZddddddddejjd	d
fdeee	e	f  dee	e	f dee
e
f de
deeeee	ef   de
dededeee	ef 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e dedeeef d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dedeeef deeef defd"d#Ze dedeeef d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	d0dedeeef deeef d(ee def
d)d*Z	d0dedeeef deeeef  defd+d,Z	d0dedeeef d-eeeef  defd.d/Z  Z S )1r   a  Mosaic augmentation.

    .. image:: https://raw.githubusercontent.com/kornia/data/main/random_mosaic.png

    Given a certain number of images, mosaic transform combines them into one output image.
    The output image is composed of the parts from each sub-image. To mess up each image individually,
    referring to :class:`kornia.augmentation.RandomJigsaw`.

    The mosaic transform steps are as follows:

         1. Concate selected images into a super-image.
         2. Crop out the outcome image according to the top-left corner and crop size.

    Args:
        output_size: the output tensor width and height after mosaicing.
        start_ratio_range: top-left (x, y) position for cropping the mosaic images.
        mosaic_grid: the number of images and image arrangement. e.g. (2, 2) means
            each output will mix 4 images in a 2x2 grid.
        min_bbox_size: minimum area of bounding boxes. Default to 0.
        data_keys: the input type sequential for applying augmentations.
            Accepts "input", "image", "mask", "bbox", "bbox_xyxy", "bbox_xywh", "keypoints",
            "class", "label".
        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``.
        padding_mode: Type of padding. Should be: constant, reflect, replicate.
        resample: the interpolation mode.
        align_corners: interpolation flag.
        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.

    Examples:
        >>> mosaic = RandomMosaic((300, 300), data_keys=["input", "bbox_xyxy"])
        >>> boxes = torch.tensor([[
        ...     [70, 5, 150, 100],
        ...     [60, 180, 175, 220],
        ... ]]).repeat(8, 1, 1)
        >>> input = torch.randn(8, 3, 224, 224)
        >>> out = mosaic(input, boxes)
        >>> out[0].shape, out[1].shape
        (torch.Size([8, 3, 300, 300]), torch.Size([8, 8, 4]))

    N)   r   )g333333?ffffff?g        r   FconstantTsliceoutput_sizemosaic_gridstart_ratio_rangemin_bbox_size	data_keyspkeepdimpadding_moderesamplealign_cornerscropping_modereturnc                    sL   t  j|dd||d || _t|||| _||||t|	|
|d| _d S )Ng      ?F)r!   p_batchsame_on_batchr"   r    )r   r   r   r#   r$   r%   r&   )	super__init__r   rgMosaicGenerator_param_generatorr   getflags)selfr   r   r   r   r    r!   r"   r#   r$   r%   r&   	__class__ V/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/_2d/mix/mosaic.pyr+   Q   s   zRandomMosaic.__init__inputparamsr0   c                 C      t NNotImplementedErrorr1   r6   r7   r0   r4   r4   r5   apply_transform_maskm      z!RandomMosaic.apply_transform_maskc                 C   s  |d dk}t |d |j|jd}t |d |j|jd}t |d |j|jd}tt|df|j|jd}|d |jjd	 d
}	tj	d	|jjd	 |jtj
d| }
d }t|d d	 D ]}t|d d
 D ]}| }|d d df | |d d d	d	f  ||
d	f< |d d df | |d d d	d
f  ||
d
f< | }||d d
  | }|j|d d d |f  |j|d d d d	f < |j|dd d	|j| < |d u r|j|  |j| < |}qet|tj|dd qeq[t|t}|j||	dd |j|d dd |S )N
batch_probg      ?src)devicedtypedstbatch_shapesr   )r   r   r      r   permutationT)inplacer   )r   rA   rB   r   lenrepeatdatashapetorcharangelongrangeclone_data	translater   r   mergeclampfilter_boxes_by_area)r1   r6   r7   r0   to_applysrc_boxdst_boxrD   offset
offset_endidxmaybe_out_boxesij_offset_box_idx	out_boxesr4   r4   r5   apply_transform_boxesp   s6   "..0
z"RandomMosaic.apply_transform_boxesc                 C   r8   r9   r:   r<   r4   r4   r5   apply_transform_keypoint   r>   z%RandomMosaic.apply_transform_keypointc                 C   s   t | jj d)Nz does not support `TAG` types.)RuntimeErrorr3   __name__r<   r4   r4   r5   apply_transform_class   s   z"RandomMosaic.apply_transform_classc           
      C   s   g }t |d d D ]2}g }t |d d D ]}|d d | | }||d d d |f  }	||	 q|t|d q
t|dS )Nr   r   rE   rH   rF   rG   )rQ   appendr   )
r1   r6   r7   r0   outr_   out_rowr`   img_idximager4   r4   r5   _compose_images   s   
zRandomMosaic._compose_imagesc                 C   sX   |d dkrt |d ||d |}|S |d dkr"td|S td|d  d)	Nr&   r$   r@   rC   r      Not supported type: .)r   tor   r;   )r1   r6   r7   r0   	transformr4   r4   r5   compute_transformation   s   
z#RandomMosaic.compute_transformationrt   c                 C   s   |d u r| j n|}|d dkrOt|tstdt| |d dkr&d}n|d dkr/d}n|d d	kr8d
}n|d }t|||d |d j ||d dS |d dkrat||d |d ddS t	d|d  d)Nr&   r$   z.Expected the transform to be a Tensor. Gotcha r#   r   r   	replicateborderreflect
reflectionr   r%   )moder#   r%   r   r@   r   )shape_compensationrq   rr   )
r0   
isinstancer   	TypeErrortyper   namelowerr   r;   )r1   r6   r7   r0   rt   r#   r4   r4   r5   _crop_images   s,   
zRandomMosaic._crop_imagesc                 C   s\   |d ur,|d d ur,t |d tttf }t|d|d |jd  d|d |jd  gS |S )Nr   r   rE   rG   rF   )r   r   intr   rM   )r1   r6   r7   r0   r   r4   r4   r5   apply_non_transform   s   .z RandomMosaic.apply_non_transformmaybe_flagsc                 C   sH   t |tttf }| j|||d}| j|||d}| j||||d}|S )N)r0   )r0   rt   )r   r   strr   ro   ru   r   )r1   r6   r7   r   r0   outputrt   r4   r4   r5   apply_transform   s
   zRandomMosaic.apply_transformr9   )!rh   
__module____qualname____doc__r   BILINEARr   r   r   r   floatr   r   r   r
   boolr+   r   r   r   r=   rN   no_gradr   re   rf   ri   ro   ru   r   r   r   __classcell__r4   r4   r2   r5   r   "   s    0

	
*,*!*,*	





)"typingr   r   r   r   r   r   rN   kornia.augmentationr   r,    kornia.augmentation._2d.mix.baser	   kornia.constantsr
   r   kornia.corer   r   r   r   r   kornia.core.checkr   kornia.geometry.boxesr   kornia.geometry.transformr   r   r   kornia.utilsr   __all__r   r4   r4   r4   r5   <module>   s    