U
    ˆ±Ëh`  ã                   @  sš   d dl mZ d dlZd dl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 d dlmZ d d	lmZmZmZ d
gZG dd
„ d
eƒZdS )é    )ÚannotationsN)ÚAnyÚTupleÚcast)Úmodel_validator)ÚSelf)ÚBaseDropout)ÚNonNegativeIntRangeType)ÚBaseTransformInitSchema)Ú	ColorTypeÚScaleIntTypeÚTargetsÚ	XYMaskingc                
      s¸   e Zd ZdZejejejejfZ	G dd„ de
ƒZd&ddddddd	d
dœ‡ fdd„Zdddddœdd„Zddddœdd„Zedddœdd„ƒZddddddœd d!„Zd"d#œd$d%„Z‡  ZS )'r   a  Applies masking strips to an image, either horizontally (X axis) or vertically (Y axis),
    simulating occlusions. This transform is useful for training models to recognize images
    with varied visibility conditions. It's particularly effective for spectrogram images,
    allowing spectral and frequency masking to improve model robustness.

    At least one of `max_x_length` or `max_y_length` must be specified, dictating the mask's
    maximum size along each axis.

    Args:
        num_masks_x (int | tuple[int, int]): Number or range of horizontal regions to mask. Defaults to 0.
        num_masks_y (int | tuple[int, int]): Number or range of vertical regions to mask. Defaults to 0.
        mask_x_length (int | tuple[int, int]): Specifies the length of the masks along
            the X (horizontal) axis. If an integer is provided, it sets a fixed mask length.
            If a tuple of two integers (min, max) is provided,
            the mask length is randomly chosen within this range for each mask.
            This allows for variable-length masks in the horizontal direction.
        mask_y_length (int | tuple[int, int]): Specifies the height of the masks along
            the Y (vertical) axis. Similar to `mask_x_length`, an integer sets a fixed mask height,
            while a tuple (min, max) allows for variable-height masks, chosen randomly
            within the specified range for each mask. This flexibility facilitates creating masks of various
            sizes in the vertical direction.
        fill_value (int | float | list[int] | list[float] | str): Value to fill image masks. Defaults to 0.
        mask_fill_value (int | float | list[int] | list[float] | None): Value to fill masks in the mask.
            If `None`, uses mask is not affected. Default: `None`.
        p (float): Probability of applying the transform. Defaults to 0.5.

    Targets:
        image, mask, bboxes, keypoints

    Image types:
        uint8, float32

    Note: Either `max_x_length` or `max_y_length` or both must be defined.
    c                   @  sV   e Zd ZU ded< ded< ded< ded< ded< ded< ed	d
ddœdd„ƒZdS )zXYMasking.InitSchemar	   Únum_masks_xÚnum_masks_yÚmask_x_lengthÚmask_y_lengthr   Ú
fill_valueÚmask_fill_valueÚafter)Úmoder   ©Úreturnc                 C  s<   t | jtƒr8| jdkr8t | jtƒr8| jdkr8d}t|ƒ‚| S )Nr   zOAt least one of `mask_x_length` or `mask_y_length` Should be a positive number.)Ú
isinstancer   Úintr   Ú
ValueError)ÚselfÚmsg© r   úS/tmp/pip-unpacked-wheel-e8onvpoz/albumentations/augmentations/dropout/xy_masking.pyÚcheck_mask_lengthA   s    
ÿþ
ýüz&XYMasking.InitSchema.check_mask_lengthN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   r    r   r   r   r   Ú
InitSchema8   s   
r%   r   Nç      à?r   r   zbool | NoneÚfloat)r   r   r   r   r   r   Úalways_applyÚpc	           	        sh   t ƒ j||||d ttttf |ƒ| _ttttf |ƒ| _ttttf |ƒ| _ttttf |ƒ| _d S )N)r)   r(   r   r   )	ÚsuperÚ__init__r   r   r   r   r   r   r   )	r   r   r   r   r   r   r   r(   r)   ©Ú	__class__r   r   r+   M   s
    zXYMasking.__init__ztuple[int, int] | Noner   ÚstrÚNone)Úmask_lengthÚdimension_sizeÚdimension_namer   c                 C  s|   |dk	rxt |ttfƒrJ|d dk s.|d |krxt|› d|› d|› dƒ‚n.|dk sZ||krxt|› d|› d|› d|› ƒ‚dS )	zHValidate the mask length against the corresponding image dimension size.Nr   é   z range z is out of valid range [0, ú]ú z exceeds image )r   ÚtupleÚlistr   )r   r0   r1   r2   r   r   r   Úvalidate_mask_length_   s    ÿzXYMasking.validate_mask_lengthzdict[str, Any]zdict[str, np.ndarray])ÚparamsÚdatar   c           	      C  sz   |d d d… }|\}}|   | j|d¡ |   | j|d¡ | j| j|| jdd}| j| j|| jdd}t || ¡}d|iS )	NÚshapeé   r   r   Úx)ÚaxisÚyÚholes)r8   r   r   Úgenerate_masksr   r   ÚnpÚarray)	r   r9   r:   Úimage_shapeÚheightÚwidthZmasks_xZmasks_yr@   r   r   r   Úget_params_dependent_on_datao   s    z&XYMasking.get_params_dependent_on_dataztuple[int, int])r0   r   c                 C  s
   t j| Ž S )N)ÚrandomÚrandint)r0   r   r   r   Úgenerate_mask_size   s    zXYMasking.generate_mask_sizezlist[tuple[int, int, int, int]])Ú	num_masksrD   Ú
max_lengthr>   r   c                 C  sÔ   |d ks&|dks&t |ttfƒr*|dkr*g S g }t |tƒr<|nt |d |d ¡}|\}}t|ƒD ]n}	|  |¡}
|dkršt d||
 ¡}d}||
 | }}n"t d||
 ¡}d}|||
  }}| ||||f¡ q`|S )Nr   r3   r=   )r   r   r'   rH   rI   ÚrangerJ   Úappend)r   rK   rD   rL   r>   ÚmasksZnum_masks_integerrE   rF   Ú_ÚlengthZx_minZy_minZx_maxZy_maxr   r   r   rA   …   s     &"
zXYMasking.generate_masksztuple[str, ...]r   c                 C  s   dS )N)r   r   r   r   r   r   r   )r   r   r   r   Úget_transform_init_args_names£   s    z'XYMasking.get_transform_init_args_names)r   r   r   r   r   r   Nr&   )r!   r"   r#   Ú__doc__r   ZIMAGEÚMASKZ	KEYPOINTSZBBOXESZ_targetsr
   r%   r+   r8   rG   ÚstaticmethodrJ   rA   rR   Ú__classcell__r   r   r,   r   r      s$   #        ÷")Ú
__future__r   rH   Útypingr   r   r   ZnumpyrB   Zpydanticr   Ztyping_extensionsr   Z/albumentations.augmentations.dropout.transformsr   Zalbumentations.core.pydanticr	   Z(albumentations.core.transforms_interfacer
   Zalbumentations.core.typesr   r   r   Ú__all__r   r   r   r   r   Ú<module>   s   