
    bi]                        d Z ddlmZ ddlmZmZmZ ddlmZm	Z	 ddl
mc mc mZ ddlmZ ddlmZmZ dgZ G d	 de      Zy)
a  Implementation of grid-based dropout augmentation.

This module provides GridDropout, which creates a regular grid over the image and drops out
rectangular regions according to the specified grid pattern. Unlike random dropout methods,
grid dropout enforces a structured pattern of occlusions that can help models learn spatial
relationships and context across the entire image space.
    )annotations)	AnnotatedAnyLiteral)AfterValidatorFieldN)BaseDropout)check_range_boundsnondecreasingGridDropoutc                       e Zd ZdZ G d dej
                        Z	 	 	 	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZddZ xZS )	r   a  Apply GridDropout augmentation to images, masks, bounding boxes, and keypoints.

    GridDropout drops out rectangular regions of an image and the corresponding mask in a grid fashion.
    This technique can help improve model robustness by forcing the network to rely on a broader context
    rather than specific local features.

    Args:
        ratio (float): The ratio of the mask holes to the unit size (same for horizontal and vertical directions).
            Must be between 0 and 1. Default: 0.5.
        unit_size_range (tuple[int, int] | None): Range from which to sample grid size. Default: None.
            Must be between 2 and the image's shorter edge. If None, grid size is calculated based on image size.
        holes_number_xy (tuple[int, int] | None): The number of grid units in x and y directions.
            First value should be between 1 and image width//2,
            Second value should be between 1 and image height//2.
            Default: None. If provided, overrides unit_size_range.
        random_offset (bool): Whether to offset the grid randomly between 0 and (grid unit size - hole size).
            If True, entered shift_xy is ignored and set randomly. Default: True.
        fill (tuple[float, float] | float | Literal["random", "random_uniform", "inpaint_telea", "inpaint_ns"]):
            Value for the dropped pixels. Can be:
            - int or float: all channels are filled with this value
            - tuple: tuple of values for each channel
            - 'random': each pixel is filled with random values
            - 'random_uniform': each hole is filled with a single random color
            - 'inpaint_telea': uses OpenCV Telea inpainting method
            - 'inpaint_ns': uses OpenCV Navier-Stokes inpainting method
            Default: 0
        fill_mask (tuple[float, float] | float | None): Value for the dropped pixels in mask.
            If None, the mask is not modified. Default: None.
        shift_xy (tuple[int, int]): Offsets of the grid start in x and y directions from (0,0) coordinate.
            Only used when random_offset is False. Default: (0, 0).
        p (float): Probability of applying the transform. Default: 0.5.

    Targets:
        image, mask, bboxes, keypoints, volume, mask3d

    Image types:
        uint8, float32

    Note:
        - If both unit_size_range and holes_number_xy are None, the grid size is calculated based on the image size.
        - The actual number of dropped regions may differ slightly from holes_number_xy due to rounding.
        - Inpainting methods ('inpaint_telea', 'inpaint_ns') work only with grayscale or RGB images.
        - For 'random_uniform' fill, each grid cell gets a single random color, unlike 'random' where each pixel
            gets its own random value.

    Example:
        >>> import numpy as np
        >>> import albumentations as A
        >>> image = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
        >>> mask = np.random.randint(0, 2, (100, 100), dtype=np.uint8)
        >>> # Example with standard fill value
        >>> aug_basic = A.GridDropout(
        ...     ratio=0.3,
        ...     unit_size_range=(10, 20),
        ...     random_offset=True,
        ...     p=1.0
        ... )
        >>> # Example with random uniform fill
        >>> aug_random = A.GridDropout(
        ...     ratio=0.3,
        ...     unit_size_range=(10, 20),
        ...     fill="random_uniform",
        ...     p=1.0
        ... )
        >>> # Example with inpainting
        >>> aug_inpaint = A.GridDropout(
        ...     ratio=0.3,
        ...     unit_size_range=(10, 20),
        ...     fill="inpaint_ns",
        ...     p=1.0
        ... )
        >>> transformed = aug_random(image=image, mask=mask)
        >>> transformed_image, transformed_mask = transformed["image"], transformed["mask"]

    Reference:
        - Paper: https://arxiv.org/abs/2001.04086
        - OpenCV Inpainting methods: https://docs.opencv.org/master/df/d3d/tutorial_py_inpainting.html

    c                  T    e Zd ZU  edd      Zded<   ded<   ded	<   d
ed<   ded<   y)GridDropout.InitSchemar      )gtlefloatratioboolrandom_offsetzmAnnotated[tuple[int, int], AfterValidator(check_range_bounds(2, None)), AfterValidator(nondecreasing)] | Noneunit_size_rangezGAnnotated[tuple[int, int], AfterValidator(check_range_bounds(0, None))]shift_xyzNAnnotated[tuple[int, int], AfterValidator(check_range_bounds(1, None))] | Noneholes_number_xyN)__name__
__module____qualname__r   r   __annotations__     l/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/albumentations/augmentations/dropout/grid_dropout.py
InitSchemar   g   s2    a(u(	
 ZYggr   r!   c	                p    t         	|   |||       || _        || _        || _        || _        || _        y )N)fill	fill_maskp)super__init__r   r   r   r   r   )
selfr   r   r   r   r   r#   r$   r%   	__class__s
            r    r'   zGridDropout.__init__t   s?     	di1=
..* r   c                   |d   }| j                   r| j                   }nIt        j                  || j                  | j                   | j                        \  }}|d   |z  |d   |z  f}t        j
                  ||| j                  | j                  | j                  | j                        }|| j                  j                  dd      dS )a!  Get parameters dependent on the data.

        Args:
            params (dict[str, Any]): Dictionary containing parameters.
            data (dict[str, Any]): Dictionary containing data.

        Returns:
            dict[str, Any]: Dictionary with parameters for transformation.

        shaper   r   l    )holesseed)
r   fdropoutcalculate_grid_dimensionsr   random_generatorgenerate_grid_holesr   r   r   integers)r(   paramsdataimage_shapegridunit_height
unit_widthr,   s           r    get_params_dependent_on_dataz(GridDropout.get_params_dependent_on_data   s     Wo''D '/&H&H$$$$%%	'#K  Nk1;q>Z3OPD,,JJMM!!
 (=(=(F(Fq)(TUUr   )      ?TNN)r   r   r   Nr:   )r   r   r   r   r   tuple[int, int] | Noner   r;   r   ztuple[int, int]r#   z^tuple[float, ...] | float | Literal['random', 'random_uniform', 'inpaint_telea', 'inpaint_ns']r$   z tuple[float, ...] | float | Noner%   r   )r3   dict[str, Any]r4   r<   returnr<   )	r   r   r   __doc__r	   r!   r'   r9   __classcell__)r)   s   @r    r   r      s    N`h[++ h "2626$*op6:!! ! 0	!
 0! "! m! 4! !$ Vr   )r>   
__future__r   typingr   r   r   pydanticr   r   /albumentations.augmentations.dropout.functionalaugmentationsdropout
functionalr.   /albumentations.augmentations.dropout.transformsr	   albumentations.core.pydanticr
   r   __all__r   r   r   r    <module>rJ      s;    # * * * B B G J/PV+ PVr   