U
    h4                     @  s   d dl mZ d dlZd dlmZmZmZmZmZm	Z	 d dl
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 d dlmZmZmZ d dlmZ d	d
lmZ ddddgZG dd deZ G dd deZ!G dd deZ"G dd deZ#G dd deZ$dS )    )annotationsN)AnyListSequenceTupleUnioncast)FieldValidationInfofield_validator)InterpolationType)BaseTransformInitSchemaDualTransform)ScaleFloatTypeScaleIntTypeTargetsto_tuple   )
functionalRandomScaleLongestMaxSizeSmallestMaxSizeResizec                      s   e Zd ZdZejejejejfZ	G dd de
Zdejddfddd	d
d fddZddddZdd
dddddZdd
ddddddZddddddZdd
dddddZd dd!d"Z  ZS )#r   au  Randomly resize the input. Output image size is different from the input image size.

    Args:
        scale_limit (float or tuple[float, float]): scaling factor range. If scale_limit is a single float value, the
            range will be (-scale_limit, scale_limit). Note that the scale_limit will be biased by 1.
            If scale_limit is a tuple, like (low, high), sampling will be done from the range (1 + low, 1 + high).
            Default: (-0.1, 0.1).
        interpolation (OpenCV flag): flag that is used to specify the interpolation algorithm. Should be one of:
            cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_LANCZOS4.
            Default: cv2.INTER_LINEAR.
        p (float): probability of applying the transform. Default: 0.5.

    Targets:
        image, mask, bboxes, keypoints

    Image types:
        uint8, float32

    Note:
        - The output image size is different from the input image size.
        - Scale factor is sampled independently per image side (width and height).
        - Bounding box coordinates are scaled accordingly.
        - Keypoint coordinates are scaled accordingly.

    Mathematical formulation:
        Let (W, H) be the original image dimensions and (W', H') be the output dimensions.
        The scale factor s is sampled from the range [1 + scale_limit[0], 1 + scale_limit[1]].
        Then, W' = W * s and H' = H * s.

    Example:
        >>> import numpy as np
        >>> import albumentations as A
        >>> image = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
        >>> transform = A.RandomScale(scale_limit=0.1, p=1.0)
        >>> result = transform(image=image)
        >>> scaled_image = result['image']
        # scaled_image will have dimensions in the range [90, 110] x [90, 110]
        # (assuming the scale_limit of 0.1 results in a scaling factor between 0.9 and 1.1)

    c                   @  s:   e Zd ZU ded< ded< ededddddZd	S )
zRandomScale.InitSchemar   scale_limitr   interpolationztuple[float, float])vreturnc                 C  s   t |ddS )Ng      ?Zbiasr   )clsr    r    Q/tmp/pip-unpacked-wheel-e8onvpoz/albumentations/augmentations/geometric/resize.pycheck_scale_limitD   s    z(RandomScale.InitSchema.check_scale_limitN__name__
__module____qualname____annotations__r   classmethodr"   r    r    r    r!   
InitSchema@   s
   
r)   )gg?Ng      ?r   intbool | Nonefloat)r   r   always_applypc                   s.   t  j||d ttttf || _|| _d S N)r.   r-   )super__init__r   r   r,   r   r   )selfr   r   r-   r.   	__class__r    r!   r1   I   s    zRandomScale.__init__zdict[str, float]r   c                 C  s   dt j| j iS )Nscale)randomuniformr   r2   r    r    r!   
get_paramsT   s    zRandomScale.get_params
np.ndarrayr   )imgr6   paramsr   c                 K  s   t ||| jS N)
fgeometricr6   r   )r2   r<   r6   r=   r    r    r!   applyW   s    zRandomScale.apply)maskr6   r   r=   r   c                 K  s   t ||tjS r>   )r?   r6   cv2INTER_NEAREST)r2   rA   r6   r   r=   r    r    r!   apply_to_mask_   s    zRandomScale.apply_to_maskbboxesr=   r   c                 K  s   |S r>   r    r2   rF   r=   r    r    r!   apply_to_bboxesh   s    zRandomScale.apply_to_bboxes)	keypointsr6   r=   r   c                 K  s   t |||S r>   )r?   keypoints_scale)r2   rI   r6   r=   r    r    r!   apply_to_keypointsl   s    zRandomScale.apply_to_keypointszdict[str, Any]c                 C  s   | j t| jdddS )Ng      r   )r   r   )r   r   r   r9   r    r    r!   get_transform_init_argst   s    z#RandomScale.get_transform_init_args)r$   r%   r&   __doc__r   IMAGEMASKBBOXES	KEYPOINTS_targetsr   r)   rB   INTER_LINEARr1   r:   r@   rD   rH   rK   rL   __classcell__r    r    r3   r!   r      s   )	c                   @  s<   e Zd ZU ded< ded< ededddddd	Zd
S )MaxSizeInitSchemazint | list[int]max_sizer   r   r   r
   )r   infor   c                 C  sP   t |ttfr|n|g}|D ]}|dkst|j dqttttt f |S )Nr   z must be bigger or equal to 1.)	
isinstancelisttuple
ValueError
field_namer   r   r*   r   )r   r   rW   resultvaluer    r    r!   r"   |   s
    z#MaxSizeInitSchema.check_scale_limitNr#   r    r    r    r!   rU   x   s
   
rU   c                      s   e Zd ZdZejejejejfZ	G dd de
Zdejddfddd	d
d fddZddddddddZddddddZdddddddZddddZddddZ  ZS ) r   a  Rescale an image so that the longest side is equal to max_size, keeping the aspect ratio of the initial image.

    Args:
        max_size (int, Sequence[int]): Maximum size of the image after the transformation. When using a list or tuple,
            the max size will be randomly selected from the values provided.
        interpolation (OpenCV flag): interpolation method. Default: cv2.INTER_LINEAR.
        p (float): probability of applying the transform. Default: 1.

    Targets:
        image, mask, bboxes, keypoints

    Image types:
        uint8, float32

    Note:
        - If the longest side of the image is already less than or equal to max_size, the image will not be resized.
        - This transform will not crop the image. The resulting image may be smaller than max_size in both dimensions.
        - For non-square images, the shorter side will be scaled proportionally to maintain the aspect ratio.

    Example:
        >>> import albumentations as A
        >>> import cv2
        >>> transform = A.Compose([
        ...     A.LongestMaxSize(max_size=1024, interpolation=cv2.INTER_LINEAR),
        ...     A.PadIfNeeded(min_height=1024, min_width=1024, border_mode=cv2.BORDER_CONSTANT),
        ... ])
        >>> # Assume we have a 1500x800 image
        >>> transformed = transform(image=image)
        >>> transformed_image = transformed['image']
        >>> transformed_image.shape
        (1024, 546, 3)  # The longest side (1500) is scaled to 1024, and the other side is scaled proportionally

    c                   @  s   e Zd ZdS )zLongestMaxSize.InitSchemaNr$   r%   r&   r    r    r    r!   r)      s   r)      Nr   int | Sequence[int]r*   r+   r,   rV   r   r-   r.   c                   s   t  || || _|| _d S r>   r0   r1   r   rV   r2   rV   r   r-   r.   r3   r    r!   r1      s    zLongestMaxSize.__init__r;   r   r<   rV   r   r=   r   c                 K  s   t j|||dS N)rV   r   )r?   Zlongest_max_sizer2   r<   rV   r   r=   r    r    r!   r@      s    zLongestMaxSize.applyrE   c                 K  s   |S r>   r    rG   r    r    r!   rH      s    zLongestMaxSize.apply_to_bboxesrI   rV   r=   r   c                 K  s*   |d d d }|t | }t|||S Nshape   )maxr?   rJ   r2   rI   rV   r=   Zimage_shaper6   r    r    r!   rK      s    z!LongestMaxSize.apply_to_keypointsdict[str, int]r5   c                 C  s"   dt | jtr| jn
t| jiS NrV   rX   rV   r*   r7   choicer9   r    r    r!   r:      s    zLongestMaxSize.get_paramstuple[str, ...]c                 C  s   dS rf   r    r9   r    r    r!   get_transform_init_args_names   s    z,LongestMaxSize.get_transform_init_args_names)r$   r%   r&   rM   r   rN   rO   rP   rQ   rR   rU   r)   rB   rS   r1   r@   rH   rK   r:   rs   rT   r    r    r3   r!   r      s   "	c                      s   e Zd ZdZejejejejfZ	G dd de
Zdejddfddd	d
d fddZddddddddZddddddZdddddddZddddZddddZ  ZS ) r   a  Rescale an image so that minimum side is equal to max_size, keeping the aspect ratio of the initial image.

    Args:
        max_size (int, list of int): Maximum size of smallest side of the image after the transformation. When using a
            list, max size will be randomly selected from the values in the list.
        interpolation (OpenCV flag): Flag that is used to specify the interpolation algorithm. Should be one of:
            cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_LANCZOS4.
            Default: cv2.INTER_LINEAR.
        p (float): Probability of applying the transform. Default: 1.

    Targets:
        image, mask, bboxes, keypoints

    Image types:
        uint8, float32

    Note:
        - If the smallest side of the image is already less than or equal to max_size, the image will not be resized.
        - This transform will not crop the image. The resulting image may be larger than max_size in both dimensions.
        - For non-square images, the larger side will be scaled proportionally to maintain the aspect ratio.
        - Bounding boxes and keypoints are scaled accordingly.

    Mathematical Details:
        1. Let (W, H) be the original width and height of the image.
        2. The scaling factor s is calculated as:
           s = max_size / min(W, H)
        3. The new dimensions (W', H') are:
           W' = W * s
           H' = H * s
        4. The image is resized to (W', H') using the specified interpolation method.
        5. Bounding boxes and keypoints are scaled by the same factor s.

    Example:
        >>> import numpy as np
        >>> import albumentations as A
        >>> image = np.random.randint(0, 256, (100, 150, 3), dtype=np.uint8)
        >>> transform = A.SmallestMaxSize(max_size=120, p=1.0)
        >>> result = transform(image=image)
        >>> resized_image = result['image']
        # resized_image will have shape (120, 180, 3), as the smallest side (100)
        # is scaled to 120, and the larger side is scaled proportionally
    c                   @  s   e Zd ZdS )zSmallestMaxSize.InitSchemaNr_   r    r    r    r!   r)     s   r)   r`   Nr   ra   r*   r+   r,   rb   c                   s   t  || || _|| _d S r>   rc   rd   r3   r    r!   r1   
  s    zSmallestMaxSize.__init__r;   r   re   c                 K  s   t j|||dS rf   )r?   Zsmallest_max_sizerg   r    r    r!   r@     s    zSmallestMaxSize.applyrE   c                 K  s   |S r>   r    rG   r    r    r!   rH     s    zSmallestMaxSize.apply_to_bboxesrh   c                 K  s*   |d d d }|t | }t|||S ri   )minr?   rJ   rm   r    r    r!   rK   "  s    z"SmallestMaxSize.apply_to_keypointsrn   r5   c                 C  s"   dt | jtr| jn
t| jiS ro   rp   r9   r    r    r!   r:   -  s    zSmallestMaxSize.get_paramsrr   c                 C  s   dS rf   r    r9   r    r    r!   rs   0  s    z-SmallestMaxSize.get_transform_init_args_names)r$   r%   r&   rM   r   rN   rO   rQ   rP   rR   rU   r)   rB   rS   r1   r@   rH   rK   r:   rs   rT   r    r    r3   r!   r      s   +	c                      s   e Zd ZdZejejejejfZ	G dd de
Zejddfdddddd	 fd
dZddddddZdddddddZddddddZddddddZddddZ  ZS )r   aH  Resize the input to the given height and width.

    Args:
        height (int): desired height of the output.
        width (int): desired width of the output.
        interpolation (OpenCV flag): flag that is used to specify the interpolation algorithm. Should be one of:
            cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_LANCZOS4.
            Default: cv2.INTER_LINEAR.
        p (float): probability of applying the transform. Default: 1.

    Targets:
        image, mask, bboxes, keypoints

    Image types:
        uint8, float32

    c                   @  s:   e Zd ZU eddZded< eddZded< ded< dS )	zResize.InitSchemar   )ger*   heightwidthr   r   N)r$   r%   r&   r	   rv   r'   rw   r    r    r    r!   r)   I  s   
r)   Nr   r*   r+   r,   )rv   rw   r   r-   r.   c                   s&   t  j||d || _|| _|| _d S r/   )r0   r1   rv   rw   r   )r2   rv   rw   r   r-   r.   r3   r    r!   r1   N  s    zResize.__init__r;   r   )r<   r=   r   c                 K  s   t j|| j| jf| jdS N)r   )r?   resizerv   rw   r   )r2   r<   r=   r    r    r!   r@   [  s    zResize.apply)rA   argsr=   r   c                 O  s   t j|| j| jftjdS rx   )r?   ry   rv   rw   rB   rC   )r2   rA   rz   r=   r    r    r!   rD   ^  s    zResize.apply_to_maskrE   c                 K  s   |S r>   r    rG   r    r    r!   rH   a  s    zResize.apply_to_bboxes)rI   r=   r   c                 K  s6   |d d d \}}| j | }| j| }t|||S ri   )rw   rv   r?   rJ   )r2   rI   r=   rv   rw   Zscale_xZscale_yr    r    r!   rK   e  s    

zResize.apply_to_keypointsrr   r5   c                 C  s   dS )N)rv   rw   r   r    r9   r    r    r!   rs   k  s    z$Resize.get_transform_init_args_names)r$   r%   r&   rM   r   rN   rO   rQ   rP   rR   r   r)   rB   rS   r1   r@   rD   rH   rK   rs   rT   r    r    r3   r!   r   4  s   	)%
__future__r   r7   typingr   r   r   r   r   r   rB   ZnumpynpZpydanticr	   r
   r   Zalbumentations.core.pydanticr   Z(albumentations.core.transforms_interfacer   r   Zalbumentations.core.typesr   r   r   Zalbumentations.core.utilsr    r   r?   __all__r   rU   r   r   r   r    r    r    r!   <module>   s     dR[