o
    eG*                    @   s  d Z ddlmZmZmZ ddlmZmZ ddlZ	ddl
ZddlZddlZddl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 ZG dd dejZd/ddZdd Zdd Z dd Z!dd Z"G dd dejZ#G dd de#Z$G dd de#Z%G dd  d e#Z&e'eG d!d" d"e(Z)d#d$ 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 )0z
Augmenters that apply changes to images based on segmentation methods.

List of augmenters:

    * :class:`Superpixels`
    * :class:`Voronoi`
    * :class:`UniformVoronoi`
    * :class:`RegularGridVoronoi`
    * :class:`RelativeRegularGridVoronoi`

    )print_functiondivisionabsolute_import)ABCMetaabstractmethodN   )meta   )random)
parameters)dtypesc                 C   sj   |dur3t | jd | jd }||kr3|| }t| jd | }t| jd | }tj| ||f|d} | S )a'  Ensure that images do not exceed a required maximum sidelength.

    This downscales to `max_size` if any side violates that maximum.
    The other side is downscaled too so that the aspect ratio is maintained.

    **Supported dtypes**:

    See :func:`~imgaug.imgaug.imresize_single_image`.

    Parameters
    ----------
    image : ndarray
        Image to potentially downscale.

    max_size : int
        Maximum length of any side of the image.

    interpolation : string or int
        See :func:`~imgaug.imgaug.imresize_single_image`.

    Nr   r   interpolation)maxshapeintiaimresize_single_image)imagemax_sizer   sizeZresize_factorZ
new_heightZ	new_width r   ND:\Projects\ConvertPro\env\Lib\site-packages\imgaug/augmenters/segmentation.py_ensure_image_max_size"   s   r   c                       sF   e Zd ZdZ				d fdd		Zd
d Zedd Zdd Z  Z	S )Superpixelsao  Transform images parially/completely to their superpixel representation.

    This implementation uses skimage's version of the SLIC algorithm.

    .. note::

        This augmenter is fairly slow. See :ref:`performance`.

    **Supported dtypes**:

    if (image size <= max_size):

        * ``uint8``: yes; fully tested
        * ``uint16``: yes; tested
        * ``uint32``: yes; tested
        * ``uint64``: limited (1)
        * ``int8``: yes; tested
        * ``int16``: yes; tested
        * ``int32``: yes; tested
        * ``int64``: limited (1)
        * ``float16``: no (2)
        * ``float32``: no (2)
        * ``float64``: no (3)
        * ``float128``: no (2)
        * ``bool``: yes; tested

        - (1) Superpixel mean intensity replacement requires computing
              these means as ``float64`` s. This can cause inaccuracies for
              large integer values.
        - (2) Error in scikit-image.
        - (3) Loss of resolution in scikit-image.

    if (image size > max_size):

        minimum of (
            ``imgaug.augmenters.segmentation.Superpixels(image size <= max_size)``,
            :func:`~imgaug.augmenters.segmentation._ensure_image_max_size`
        )

    Parameters
    ----------
    p_replace : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Defines for any segment the probability that the pixels within that
        segment are replaced by their average color (otherwise, the pixels
        are not changed).
        Examples:

            * A probability of ``0.0`` would mean, that the pixels in no
              segment are replaced by their average color (image is not
              changed at all).
            * A probability of ``0.5`` would mean, that around half of all
              segments are replaced by their average color.
            * A probability of ``1.0`` would mean, that all segments are
              replaced by their average color (resulting in a voronoi
              image).

        Behaviour based on chosen datatypes for this parameter:

            * If a ``number``, then that ``number`` will always be used.
            * If ``tuple`` ``(a, b)``, then a random probability will be
              sampled from the interval ``[a, b]`` per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, it is expected to return
              values between ``0.0`` and ``1.0`` and will be queried *for each
              individual segment* to determine whether it is supposed to
              be averaged (``>0.5``) or not (``<=0.5``).
              Recommended to be some form of ``Binomial(...)``.

    n_segments : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Rough target number of how many superpixels to generate (the algorithm
        may deviate from this number). Lower value will lead to coarser
        superpixels. Higher values are computationally more intensive and
        will hence lead to a slowdown.

            * If a single ``int``, then that value will always be used as the
              number of segments.
            * If a ``tuple`` ``(a, b)``, then a value from the discrete
              interval ``[a..b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    max_size : int or None, optional
        Maximum image size at which the augmentation is performed.
        If the width or height of an image exceeds this value, it will be
        downscaled before the augmentation so that the longest side
        matches `max_size`.
        This is done to speed up the process. The final output image has the
        same size as the input image. Note that in case `p_replace` is below
        ``1.0``, the down-/upscaling will affect the not-replaced pixels too.
        Use ``None`` to apply no down-/upscaling.

    interpolation : int or str, optional
        Interpolation method to use during downscaling when `max_size` is
        exceeded. Valid methods are the same as in
        :func:`~imgaug.imgaug.imresize_single_image`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.Superpixels(p_replace=1.0, n_segments=64)

    Generate around ``64`` superpixels per image and replace all of them with
    their average color (standard superpixel image).

    >>> aug = iaa.Superpixels(p_replace=0.5, n_segments=64)

    Generate around ``64`` superpixels per image and replace half of them
    with their average color, while the other half are left unchanged (i.e.
    they still show the input image's content).

    >>> aug = iaa.Superpixels(p_replace=(0.25, 1.0), n_segments=(16, 128))

    Generate between ``16`` and ``128`` superpixels per image and replace
    ``25`` to ``100`` percent of them with their average color.

          ?      ?2   x      linearN
deprecatedc	           	         sT   t t| j||||d tj|dddd| _tj|dddddd| _|| _|| _	d S )	Nseednamerandom_statedeterministic	p_replaceTtuple_to_uniformlist_to_choice
n_segmentsr   NFvalue_ranger+   r,   Zallow_floats)
superr   __init__iaphandle_probability_paramr)   handle_discrete_paramr-   r   r   )	selfr)   r-   r   r   r%   r&   r'   r(   	__class__r   r   r2      s   

zSuperpixels.__init__c                 C   s*  |j d u r|S |j }tj|g dg d| d t|}|d| }| jj|f|d d}t|dd }t	t
||dd  D ]S\}	\}
}|
jdkrKq?| jj||	 f|d}t|dkr^q?|
j}t|
| j| j}
tjj|
||	 dd}| |
||}||jkrtj||dd	 | jd
}||j |	< q?|S )N)	booluint8uint16uint32uint64int8int16int32int64)
uint128uint256int128int256float16float32float64float96float128float256allowedZ
disallowedZ	augmenterr   r   r'   
   )r-   Zcompactnessr	   r   )imagesiadtgate_dtypeslen	duplicater-   draw_samplesnpclip	enumeratezipr   r)   r   r   r   r   r   skimageZsegmentationZslic_replace_segmentsr   r   )r6   batchr'   parentshooksrP   Z	nb_imagesrssZn_segments_samplesir   rsreplace_samples
orig_shapesegments	image_augr   r   r   _augment_batch_   sL   


"




zSuperpixels._augment_batch_c                 C   s   t |j\}}}t|}|jd }t|D ]J}	tj	j
|d |d|	f d}
t|
D ]5\}}||t|  dkra|j}|d|	f }|jjdv rYtt|}tt|||}n|}||||k< q,q|S )Nr	   r   .)Zintensity_imager   )r`   ub)rQ   Zget_value_range_of_dtypedtyperV   copyr   smxrangerZ   measureZregionpropsrX   rS   mean_intensitykindr   roundminr   )clsr   rd   rb   Z	min_valueZ_center_valueZ	max_valueZimage_spnb_channelscZregionsZridxregionrn   Z
image_sp_cvaluer   r   r   r[     s(   


zSuperpixels._replace_segmentsc                 C      | j | j| j| jgS z=See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`.)r)   r-   r   r   r6   r   r   r   get_parametersA     zSuperpixels.get_parameters)r   r   r!   r"   NNr#   r#   )
__name__
__module____qualname____doc__r2   rf   classmethodr[   rz   __classcell__r   r   r7   r   r   F   s     
<
#r   c           
      C   s   | j }|dkr| dtjf } t|dkr|dkr| d S | S | jdd \}}t|||\}}t| ||t|}t| |||}	|dkrG|	d S |	S )a  Average colors within voronoi cells of an image.

    Parameters
    ----------
    image : ndarray
        The image to convert to a voronoi image. May be ``HxW`` or
        ``HxWxC``. Note that for ``RGBA`` images the alpha channel
        will currently also by averaged.

    cell_coordinates : ndarray
        A ``Nx2`` float array containing the center coordinates of voronoi
        cells on the image. Values are expected to be in the interval
        ``[0.0, height-1.0]`` for the y-axis (x-axis analogous).
        If this array contains no coordinate, the image will not be
        changed.

    replace_mask : None or ndarray, optional
        Boolean mask of the same length as `cell_coordinates`, denoting
        for each cell whether its pixels are supposed to be replaced
        by the cell's average color (``True``) or left untouched (``False``).
        If this is set to ``None``, all cells will be replaced.

    Returns
    -------
    ndarray
        Voronoi image.

    r	   .r   ).r   )ndimrV   newaxisrS   r    _match_pixels_with_voronoi_cells_compute_avg_segment_colors_render_segments)
r   cell_coordinatesreplace_maskZ
input_dimsheightwidthpixel_coordsids_of_nearest_cellscell_colorsre   r   r   r   segment_voronoiH  s(   
r   c                 C   sD   ddl m} ||}t| |}|tjd }||d }||fS )Nr   )cKDTreer   r   )Zscipy.spatialr   _generate_pixel_coordsastyperV   rG   query)r   r   r   ZKDTreetreer   Zpixel_coords_subpixelr   r   r   r   r   }  s   
r   c                 C   s2   t t |t | \}}t j| | f S N)rV   meshgridarangeZc_ravel)r   r   xxyyr   r   r   r     s   r   c           
      C   s   | j d }tj||ftjd}tj|ftjd}t||D ]\}}|d d d }	||  | t|	 7  < ||  d7  < qt|dd }||d d tjf  }|	tj
S )Nr	   )ri   r   )r   rV   ZzerosrH   r<   rY   tuplerW   r   r   r:   )
r   r   ids_of_nearest_segmentsZnb_segmentsrs   r   Zcell_countersZpixel_coordZid_of_nearest_cellZpixel_coord_yxr   r   r   r     s   
r   c                 C   s   t |}| j\}}}|d ur| nd }|d u st |s&||d d f }n-t |d }	t t ||	d }
||d d f }| || df}||
d d f ||
< ||||f}|S )Nr   r   )rV   rj   r   anyZnonzerowhereisinreshape)r   r   Zavg_segment_colorsr   r   r   rs   	keep_maskdataZids_to_keepindices_to_keepZ
image_datar   r   r   r     s    

r   c                       sB   e Zd ZdZ				d fdd	Zd	d
 Zdd Zdd Z  ZS )Voronoia  Average colors of an image within Voronoi cells.

    This augmenter performs the following steps:

        1. Query `points_sampler` to sample random coordinates of cell
           centers. On the image.
        2. Estimate for each pixel to which voronoi cell (i.e. segment)
           it belongs. Each pixel belongs to the cell with the closest center
           coordinate (euclidean distance).
        3. Compute for each cell the average color of the pixels within it.
        4. Replace the pixels of `p_replace` percent of all cells by their
           average color. Do not change the pixels of ``(1 - p_replace)``
           percent of all cells. (The percentages are average values over
           many images. Some images may get more/less cells replaced by
           their average color.)

    This code is very loosely based on
    https://codegolf.stackexchange.com/questions/50299/draw-an-image-as-a-voronoi-map/50345#50345

    **Supported dtypes**:

    if (image size <= max_size):

        * ``uint8``: yes; fully tested
        * ``uint16``: no; not tested
        * ``uint32``: no; not tested
        * ``uint64``: no; not tested
        * ``int8``: no; not tested
        * ``int16``: no; not tested
        * ``int32``: no; not tested
        * ``int64``: no; not tested
        * ``float16``: no; not tested
        * ``float32``: no; not tested
        * ``float64``: no; not tested
        * ``float128``: no; not tested
        * ``bool``: no; not tested

    if (image size > max_size):

        minimum of (
            ``imgaug.augmenters.segmentation.Voronoi(image size <= max_size)``,
            :func:`~imgaug.augmenters.segmentation._ensure_image_max_size`
        )

    Parameters
    ----------
    points_sampler : IPointsSampler
        A points sampler which will be queried per image to generate the
        coordinates of the centers of voronoi cells.

    p_replace : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Defines for any segment the probability that the pixels within that
        segment are replaced by their average color (otherwise, the pixels
        are not changed).
        Examples:

            * A probability of ``0.0`` would mean, that the pixels in no
              segment are replaced by their average color (image is not
              changed at all).
            * A probability of ``0.5`` would mean, that around half of all
              segments are replaced by their average color.
            * A probability of ``1.0`` would mean, that all segments are
              replaced by their average color (resulting in a voronoi
              image).

        Behaviour based on chosen datatypes for this parameter:

            * If a ``number``, then that ``number`` will always be used.
            * If ``tuple`` ``(a, b)``, then a random probability will be
              sampled from the interval ``[a, b]`` per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, it is expected to return
              values between ``0.0`` and ``1.0`` and will be queried *for each
              individual segment* to determine whether it is supposed to
              be averaged (``>0.5``) or not (``<=0.5``).
              Recommended to be some form of ``Binomial(...)``.

    max_size : int or None, optional
        Maximum image size at which the augmentation is performed.
        If the width or height of an image exceeds this value, it will be
        downscaled before the augmentation so that the longest side
        matches `max_size`.
        This is done to speed up the process. The final output image has the
        same size as the input image. Note that in case `p_replace` is below
        ``1.0``, the down-/upscaling will affect the not-replaced pixels too.
        Use ``None`` to apply no down-/upscaling.

    interpolation : int or str, optional
        Interpolation method to use during downscaling when `max_size` is
        exceeded. Valid methods are the same as in
        :func:`~imgaug.imgaug.imresize_single_image`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> points_sampler = iaa.RegularGridPointsSampler(n_cols=20, n_rows=40)
    >>> aug = iaa.Voronoi(points_sampler)

    Create an augmenter that places a ``20x40`` (``HxW``) grid of cells on
    the image and replaces all pixels within each cell by the cell's average
    color. The process is performed at an image size not exceeding ``128`` px
    on any side (default). If necessary, the downscaling is performed using
    ``linear`` interpolation (default).

    >>> points_sampler = iaa.DropoutPointsSampler(
    >>>     iaa.RelativeRegularGridPointsSampler(
    >>>         n_cols_frac=(0.05, 0.2),
    >>>         n_rows_frac=0.1),
    >>>     0.2)
    >>> aug = iaa.Voronoi(points_sampler, p_replace=0.9, max_size=None)

    Create a voronoi augmenter that generates a grid of cells dynamically
    adapted to the image size. Larger images get more cells. On the x-axis,
    the distance between two cells is ``w * W`` pixels, where ``W`` is the
    width of the image and ``w`` is always ``0.1``. On the y-axis,
    the distance between two cells is ``h * H`` pixels, where ``H`` is the
    height of the image and ``h`` is sampled uniformly from the interval
    ``[0.05, 0.2]``. To make the voronoi pattern less regular, about ``20``
    percent of the cell coordinates are randomly dropped (i.e. the remaining
    cells grow in size). In contrast to the first example, the image is not
    resized (if it was, the sampling would happen *after* the resizing,
    which would affect ``W`` and ``H``). Not all voronoi cells are replaced
    by their average color, only around ``90`` percent of them. The
    remaining ``10`` percent's pixels remain unchanged.

    r   r!   r"   Nr#   c	           	         s^   t t| j||||d t|tsJ dt|f || _tj|dddd| _	|| _
|| _d S )Nr$   zFExpected 'points_sampler' to be an instance of IPointsSampler, got %s.r)   Tr*   )r1   r   r2   
isinstanceIPointsSamplertypepoints_samplerr3   r4   r)   r   r   )	r6   r   r)   r   r   r%   r&   r'   r(   r7   r   r   r2   R  s   

zVoronoi.__init__c           
      C   sl   |j d u r|S |j }tj|dgg d| d |t|}tt||D ]\}\}}	| ||	|j |< q$|S )Nr:   )r9   r;   r<   r=   rB   rC   r>   r?   r@   rA   rD   rE   rF   rG   rH   rI   rJ   rK   rL   )rP   rQ   rR   rT   rS   rX   rY   _augment_single_image)
r6   r\   r'   r]   r^   rP   r_   r`   r   ra   r   r   r   rf   f  s   
zVoronoi._augment_batch_c           	      C   s   | d}|j}t|| j| j}| j|g|d d }| jt	|f|d }|dk}t
|||}||jkrDtj||dd | jd}|S )Nr	   r   r   r   r   )rT   r   r   r   r   r   sample_pointsr)   rU   rS   r   r   r   )	r6   r   r'   r_   rc   r   r)   r   re   r   r   r   r   |  s    


zVoronoi._augment_single_imagec                 C   rw   rx   )r   r)   r   r   ry   r   r   r   rz     r{   zVoronoi.get_parameters)r   r!   r"   NNr#   r#   )	r|   r}   r~   r   r2   rf   r   rz   r   r   r   r7   r   r     s     r   c                       s*   e Zd ZdZ				d
 fdd		Z  ZS )UniformVoronoia  Uniformly sample Voronoi cells on images and average colors within them.

    This augmenter is a shortcut for the combination of
    :class:`~imgaug.augmenters.segmentation.Voronoi` with
    :class:`~imgaug.augmenters.segmentation.UniformPointsSampler`. Hence, it
    generates a fixed amount of ``N`` random coordinates of voronoi cells on
    each image. The cell coordinates are sampled uniformly using the image
    height and width as maxima.

    **Supported dtypes**:

    See :class:`~imgaug.augmenters.segmentation.Voronoi`.

    Parameters
    ----------
    n_points : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Number of points to sample on each image.

            * If a single ``int``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the discrete
              interval ``[a..b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    p_replace : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Defines for any segment the probability that the pixels within that
        segment are replaced by their average color (otherwise, the pixels
        are not changed).
        Examples:

            * A probability of ``0.0`` would mean, that the pixels in no
              segment are replaced by their average color (image is not
              changed at all).
            * A probability of ``0.5`` would mean, that around half of all
              segments are replaced by their average color.
            * A probability of ``1.0`` would mean, that all segments are
              replaced by their average color (resulting in a voronoi
              image).

        Behaviour based on chosen datatypes for this parameter:

            * If a ``number``, then that ``number`` will always be used.
            * If ``tuple`` ``(a, b)``, then a random probability will be
              sampled from the interval ``[a, b]`` per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, it is expected to return
              values between ``0.0`` and ``1.0`` and will be queried *for each
              individual segment* to determine whether it is supposed to
              be averaged (``>0.5``) or not (``<=0.5``).
              Recommended to be some form of ``Binomial(...)``.

    max_size : int or None, optional
        Maximum image size at which the augmentation is performed.
        If the width or height of an image exceeds this value, it will be
        downscaled before the augmentation so that the longest side
        matches `max_size`.
        This is done to speed up the process. The final output image has the
        same size as the input image. Note that in case `p_replace` is below
        ``1.0``, the down-/upscaling will affect the not-replaced pixels too.
        Use ``None`` to apply no down-/upscaling.

    interpolation : int or str, optional
        Interpolation method to use during downscaling when `max_size` is
        exceeded. Valid methods are the same as in
        :func:`~imgaug.imgaug.imresize_single_image`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.UniformVoronoi((100, 500))

    Sample for each image uniformly the number of voronoi cells ``N`` from the
    interval ``[100, 500]``. Then generate ``N`` coordinates by sampling
    uniformly the x-coordinates from ``[0, W]`` and the y-coordinates from
    ``[0, H]``, where ``H`` is the image height and ``W`` the image width.
    Then use these coordinates to group the image pixels into voronoi
    cells and average the colors within them. The process is performed at an
    image size not exceeding ``128`` px on any side (default). If necessary,
    the downscaling is performed using ``linear`` interpolation (default).

    >>> aug = iaa.UniformVoronoi(250, p_replace=0.9, max_size=None)

    Same as above, but always samples ``N=250`` cells, replaces only
    ``90`` percent of them with their average color (the pixels of the
    remaining ``10`` percent are not changed) and performs the transformation
    at the original image size (``max_size=None``).

    r   i  r   r!   r"   Nr#   c	           	   
      s(   t t| jt||||||||d d S N)r   r)   r   r   r%   r&   r'   r(   )r1   r   r2   UniformPointsSampler)	r6   n_pointsr)   r   r   r%   r&   r'   r(   r7   r   r   r2     s   

zUniformVoronoi.__init__)r   r   r!   r"   NNr#   r#   r|   r}   r~   r   r2   r   r   r   r7   r   r     s    mr   c                       s,   e Zd ZdZ					d fd	d
	Z  ZS )RegularGridVoronoiaI  Sample Voronoi cells from regular grids and color-average them.

    This augmenter is a shortcut for the combination of
    :class:`~imgaug.augmenters.segmentation.Voronoi`,
    :class:`~imgaug.augmenters.segmentation.RegularGridPointsSampler` and
    :class:`~imgaug.augmenters.segmentation.DropoutPointsSampler`. Hence, it
    generates a regular grid with ``R`` rows and ``C`` columns of coordinates
    on each image. Then, it drops ``p`` percent of the ``R*C`` coordinates
    to randomize the grid. Each image pixel then belongs to the voronoi
    cell with the closest coordinate.

    **Supported dtypes**:

    See :class:`~imgaug.augmenters.segmentation.Voronoi`.

    Parameters
    ----------
    n_rows : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Number of rows of coordinates to place on each image, i.e. the number
        of coordinates on the y-axis. Note that for each image, the sampled
        value is clipped to the interval ``[1..H]``, where ``H`` is the image
        height.

            * If a single ``int``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the discrete
              interval ``[a..b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    n_cols : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Number of columns of coordinates to place on each image, i.e. the
        number of coordinates on the x-axis. Note that for each image, the
        sampled value is clipped to the interval ``[1..W]``, where ``W`` is
        the image width.

            * If a single ``int``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the discrete
              interval ``[a..b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    p_drop_points : number or tuple of number or imgaug.parameters.StochasticParameter, optional
        The probability that a coordinate will be removed from the list
        of all sampled coordinates. A value of ``1.0`` would mean that (on
        average) ``100`` percent of all coordinates will be dropped,
        while ``0.0`` denotes ``0`` percent. Note that this sampler will
        always ensure that at least one coordinate is left after the dropout
        operation, i.e. even ``1.0`` will only drop all *except one*
        coordinate.

            * If a ``float``, then that value will be used for all images.
            * If a ``tuple`` ``(a, b)``, then a value ``p`` will be sampled
              from the interval ``[a, b]`` per image.
            * If a ``StochasticParameter``, then this parameter will be used to
              determine per coordinate whether it should be *kept* (sampled
              value of ``>0.5``) or shouldn't be kept (sampled value of
              ``<=0.5``). If you instead want to provide the probability as
              a stochastic parameter, you can usually do
              ``imgaug.parameters.Binomial(1-p)`` to convert parameter `p` to
              a 0/1 representation.

    p_replace : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Defines for any segment the probability that the pixels within that
        segment are replaced by their average color (otherwise, the pixels
        are not changed).
        Examples:

            * A probability of ``0.0`` would mean, that the pixels in no
              segment are replaced by their average color (image is not
              changed at all).
            * A probability of ``0.5`` would mean, that around half of all
              segments are replaced by their average color.
            * A probability of ``1.0`` would mean, that all segments are
              replaced by their average color (resulting in a voronoi
              image).

        Behaviour based on chosen datatypes for this parameter:

            * If a ``number``, then that number will always be used.
            * If ``tuple`` ``(a, b)``, then a random probability will be
              sampled from the interval ``[a, b]`` per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, it is expected to return
              values between ``0.0`` and ``1.0`` and will be queried *for each
              individual segment* to determine whether it is supposed to
              be averaged (``>0.5``) or not (``<=0.5``).
              Recommended to be some form of ``Binomial(...)``.

    max_size : int or None, optional
        Maximum image size at which the augmentation is performed.
        If the width or height of an image exceeds this value, it will be
        downscaled before the augmentation so that the longest side
        matches `max_size`.
        This is done to speed up the process. The final output image has the
        same size as the input image. Note that in case `p_replace` is below
        ``1.0``, the down-/upscaling will affect the not-replaced pixels too.
        Use ``None`` to apply no down-/upscaling.

    interpolation : int or str, optional
        Interpolation method to use during downscaling when `max_size` is
        exceeded. Valid methods are the same as in
        :func:`~imgaug.imgaug.imresize_single_image`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.RegularGridVoronoi(10, 20)

    Place a regular grid of ``10x20`` (``height x width``) coordinates on
    each image. Randomly drop on average ``20`` percent of these points
    to create a less regular pattern. Then use the remaining coordinates
    to group the image pixels into voronoi cells and average the colors
    within them. The process is performed at an image size not exceeding
    ``128`` px on any side (default). If necessary, the downscaling is
    performed using ``linear`` interpolation (default).

    >>> aug = iaa.RegularGridVoronoi(
    >>>     (10, 30), 20, p_drop_points=0.0, p_replace=0.9, max_size=None)

    Same as above, generates a grid with randomly ``10`` to ``30`` rows,
    drops none of the generates points, replaces only ``90`` percent of
    the voronoi cells with their average color (the pixels of the remaining
    ``10`` percent are not changed) and performs the transformation
    at the original image size (``max_size=None``).

    rO              r   r   r!   r"   Nr#   c              
      0   t t| jtt|||||||||	|
d d S r   )r1   r   r2   DropoutPointsSamplerRegularGridPointsSampler)r6   n_rowsn_colsp_drop_pointsr)   r   r   r%   r&   r'   r(   r7   r   r   r2        

zRegularGridVoronoi.__init__)
r   r   r   r   r!   r"   NNr#   r#   r   r   r   r7   r   r     s     r   c                       s,   e Zd ZdZ					d
 fdd		Z  ZS )RelativeRegularGridVoronoia"  Sample Voronoi cells from image-dependent grids and color-average them.

    This augmenter is a shortcut for the combination of
    :class:`~imgaug.augmenters.segmentation.Voronoi`,
    :class:`~imgaug.augmenters.segmentation.RegularGridPointsSampler` and
    :class:`~imgaug.augmenters.segmentation.DropoutPointsSampler`. Hence, it
    generates a regular grid with ``R`` rows and ``C`` columns of coordinates
    on each image. Then, it drops ``p`` percent of the ``R*C`` coordinates
    to randomize the grid. Each image pixel then belongs to the voronoi
    cell with the closest coordinate.

    .. note::

        In contrast to the other voronoi augmenters, this one uses
        ``None`` as the default value for `max_size`, i.e. the color averaging
        is always performed at full resolution. This enables the augmenter to
        make use of the additional points on larger images. It does
        however slow down the augmentation process.

    **Supported dtypes**:

    See :class:`~imgaug.augmenters.segmentation.Voronoi`.

    Parameters
    ----------
    n_rows_frac : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Relative number of coordinates to place on the y-axis. For a value
        ``y`` and image height ``H`` the number of actually placed coordinates
        (i.e. computed rows) is given by ``int(round(y*H))``.
        Note that for each image, the number of coordinates is clipped to the
        interval ``[1,H]``, where ``H`` is the image height.

            * If a single ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the interval
              ``[a, b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    n_cols_frac : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Relative number of coordinates to place on the x-axis. For a value
        ``x`` and image height ``W`` the number of actually placed coordinates
        (i.e. computed columns) is given by ``int(round(x*W))``.
        Note that for each image, the number of coordinates is clipped to the
        interval ``[1,W]``, where ``W`` is the image width.

            * If a single ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the interval
              ``[a, b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    p_drop_points : number or tuple of number or imgaug.parameters.StochasticParameter, optional
        The probability that a coordinate will be removed from the list
        of all sampled coordinates. A value of ``1.0`` would mean that (on
        average) ``100`` percent of all coordinates will be dropped,
        while ``0.0`` denotes ``0`` percent. Note that this sampler will
        always ensure that at least one coordinate is left after the dropout
        operation, i.e. even ``1.0`` will only drop all *except one*
        coordinate.

            * If a ``float``, then that value will be used for all images.
            * If a ``tuple`` ``(a, b)``, then a value ``p`` will be sampled
              from the interval ``[a, b]`` per image.
            * If a ``StochasticParameter``, then this parameter will be used to
              determine per coordinate whether it should be *kept* (sampled
              value of ``>0.5``) or shouldn't be kept (sampled value of
              ``<=0.5``). If you instead want to provide the probability as
              a stochastic parameter, you can usually do
              ``imgaug.parameters.Binomial(1-p)`` to convert parameter `p` to
              a 0/1 representation.

    p_replace : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Defines for any segment the probability that the pixels within that
        segment are replaced by their average color (otherwise, the pixels
        are not changed).
        Examples:

            * A probability of ``0.0`` would mean, that the pixels in no
              segment are replaced by their average color (image is not
              changed at all).
            * A probability of ``0.5`` would mean, that around half of all
              segments are replaced by their average color.
            * A probability of ``1.0`` would mean, that all segments are
              replaced by their average color (resulting in a voronoi
              image).

        Behaviour based on chosen datatypes for this parameter:

            * If a ``number``, then that ``number`` will always be used.
            * If ``tuple`` ``(a, b)``, then a random probability will be
              sampled from the interval ``[a, b]`` per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, it is expected to return
              values between ``0.0`` and ``1.0`` and will be queried *for each
              individual segment* to determine whether it is supposed to
              be averaged (``>0.5``) or not (``<=0.5``).
              Recommended to be some form of ``Binomial(...)``.

    max_size : int or None, optional
        Maximum image size at which the augmentation is performed.
        If the width or height of an image exceeds this value, it will be
        downscaled before the augmentation so that the longest side
        matches `max_size`.
        This is done to speed up the process. The final output image has the
        same size as the input image. Note that in case `p_replace` is below
        ``1.0``, the down-/upscaling will affect the not-replaced pixels too.
        Use ``None`` to apply no down-/upscaling.

    interpolation : int or str, optional
        Interpolation method to use during downscaling when `max_size` is
        exceeded. Valid methods are the same as in
        :func:`~imgaug.imgaug.imresize_single_image`.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.RelativeRegularGridVoronoi(0.1, 0.25)

    Place a regular grid of ``R x C`` coordinates on each image, where
    ``R`` is the number of rows and computed as ``R=0.1*H`` with ``H`` being
    the height of the input image. ``C`` is the number of columns and
    analogously estimated from the image width ``W`` as ``C=0.25*W``.
    Larger images will lead to larger ``R`` and ``C`` values.
    On average, ``20`` percent of these grid coordinates are randomly
    dropped to create a less regular pattern. Then, the remaining coordinates
    are used to group the image pixels into voronoi cells and the colors
    within them are averaged.

    >>> aug = iaa.RelativeRegularGridVoronoi(
    >>>     (0.03, 0.1), 0.1, p_drop_points=0.0, p_replace=0.9, max_size=512)

    Same as above, generates a grid with randomly ``R=r*H`` rows, where
    ``r`` is sampled uniformly from the interval ``[0.03, 0.1]`` and
    ``C=0.1*W`` rows. No points are dropped. The augmenter replaces only
    ``90`` percent of the voronoi cells with their average color (the pixels
    of the remaining ``10`` percent are not changed). Images larger than
    ``512`` px are temporarily downscaled (*before* sampling the grid points)
    so that no side exceeds ``512`` px. This improves performance, but
    degrades the quality of the resulting image.

    g?g333333?r   r   Nr"   r#   c              
      r   r   )r1   r   r2   r    RelativeRegularGridPointsSampler)r6   n_rows_fracn_cols_fracr   r)   r   r   r%   r&   r'   r(   r7   r   r   r2   ]  r   z#RelativeRegularGridVoronoi.__init__)
r   r   r   r   Nr"   NNr#   r#   r   r   r   r7   r   r     s     %r   c                   @   s   e Zd ZdZedd ZdS )r   zInterface for all point samplers.

    Point samplers return coordinate arrays of shape ``Nx2``.
    These coordinates can be used in other augmenters, see e.g.
    :class:`~imgaug.augmenters.segmentation.Voronoi`.

    c                 C   s   dS )aR  Generate coordinates of points on images.

        Parameters
        ----------
        images : ndarray or list of ndarray
            One or more images for which to generate points.
            If this is a ``list`` of arrays, each one of them is expected to
            have three dimensions.
            If this is an array, it must be four-dimensional and the first
            axis is expected to denote the image index. For ``RGB`` images
            the array would hence have to be of shape ``(N, H, W, 3)``.

        random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState
            A random state to use for any probabilistic function required
            during the point sampling.
            See :func:`~imgaug.random.RNG` for details.

        Returns
        -------
        ndarray
            An ``(N,2)`` ``float32`` array containing ``(x,y)`` subpixel
            coordinates, all of which being within the intervals
            ``[0.0, width]`` and ``[0.0, height]``.

        Nr   )r6   rP   r'   r   r   r   r   x  s    zIPointsSampler.sample_pointsN)r|   r}   r~   r   r   r   r   r   r   r   r   n  s    r   c                 C   s   t | dks
J dt| trAtdd | D s'J dddd | D f tdd | D s?J d	dd
d | D f d S t| sOJ dt| f | jdks^J d| j| j	f d S )Nr   z&Expected at least one image, got zero.c                 S   s   g | ]}t |qS r   )r   is_np_array.0r   r   r   r   
<listcomp>      z0_verify_sample_points_images.<locals>.<listcomp>z4Expected list of numpy arrays, got list of types %s.z, c                 S   s   g | ]}t t|qS r   )strr   r   r   r   r   r     s    c                 S   s   g | ]}|j d kqS )   )r   r   r   r   r   r     r   z@Expected each image to have three dimensions, got dimensions %s.c                 S   s   g | ]}t |jqS r   )r   r   r   r   r   r   r     r   z]Expected either a list of numpy arrays or a single numpy array of shape NxHxWxC. Got type %s.   zXExpected a four-dimensional array of shape NxHxWxC. Got shape %d dimensions (shape: %s).)
rS   r   listalljoinr   r   r   r   r   )rP   r   r   r   _verify_sample_points_images  s0   
r   c                   @   s\   e Zd ZdZdd Zdd Zdd Zedd	 Zed
d Z	edd Z
dd Zdd ZdS )r   a  Sampler that generates a regular grid of coordinates on an image.

    'Regular grid' here means that on each axis all coordinates have the
    same distance from each other. Note that the distance may change between
    axis.

    Parameters
    ----------
    n_rows : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Number of rows of coordinates to place on each image, i.e. the number
        of coordinates on the y-axis. Note that for each image, the sampled
        value is clipped to the interval ``[1..H]``, where ``H`` is the image
        height.

            * If a single ``int``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the discrete
              interval ``[a..b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    n_cols : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Number of columns of coordinates to place on each image, i.e. the
        number of coordinates on the x-axis. Note that for each image, the
        sampled value is clipped to the interval ``[1..W]``, where ``W`` is
        the image width.

            * If a single ``int``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the discrete
              interval ``[a..b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> sampler = iaa.RegularGridPointsSampler(
    >>>     n_rows=(5, 20),
    >>>     n_cols=50)

    Create a point sampler that generates regular grids of points. These grids
    contain ``r`` points on the y-axis, where ``r`` is sampled
    uniformly from the discrete interval ``[5..20]`` per image.
    On the x-axis, the grids always contain ``50`` points.

    c                 C   s4   t j|dddddd| _t j|dddddd| _d S )Nr   r.   TFr/   r   )r3   r5   r   r   )r6   r   r   r   r   r   r2     s   z!RegularGridPointsSampler.__init__c                 C   s0   t |}t| | ||\}}| |||S r   )iarandomRNGr   _draw_samples_generate_point_grids)r6   rP   r'   
n_rows_lst
n_cols_lstr   r   r   r     s   
z&RegularGridPointsSampler.sample_pointsc                 C   sH   | d}| jjt||d d}| jjt||d d}| |||S )Nr	   r   rN   r   )rT   r   rU   rS   r   _clip_rows_and_cols)r6   rP   r'   r_   r   r   r   r   r   r     s   
z&RegularGridPointsSampler._draw_samplesc                 C   sh   t dd |D }t dd |D }t |d |}t |d |}t |dd }t |dd }||fS )Nc                 S      g | ]}|j d  qS r   r   r   r   r   r   r     r   z@RegularGridPointsSampler._clip_rows_and_cols.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r     r   r   )rV   r@   rW   )rr   r   r   rP   heightswidthsr   r   r   r     s   z,RegularGridPointsSampler._clip_rows_and_colsc                 C   s4   g }t |||D ]\}}}|| ||| q|S r   )rY   append_generate_point_grid)rr   rP   r   r   Zgridsr   Zn_rows_iZn_cols_ir   r   r   r     s   z.RegularGridPointsSampler._generate_point_gridsc                 C   s   |j dd \}}|| }d|d  }||d  }|d |  kr'|d kr0n nt|g}	ntj|||d}	|| }
d|
d  }||
d  }|d |  krV|d kr_n nt|g}ntj|||d}t||	\}}	t| |	 gj}|S )Nr   r	   r   -C6?)num)r   rV   rG   Zlinspacer   Zvstackr   T)rr   r   r   r   r   r   Z	y_spacingZy_startZy_endr   Z	x_spacingZx_startZx_endr   gridr   r   r   r     s      z-RegularGridPointsSampler._generate_point_gridc                 C      d| j | jf S )Nz RegularGridPointsSampler(%s, %s))r   r   ry   r   r   r   __repr__#  s   z!RegularGridPointsSampler.__repr__c                 C      |   S r   r   ry   r   r   r   __str__&     z RegularGridPointsSampler.__str__N)r|   r}   r~   r   r2   r   r   r   r   r   r   r   r   r   r   r   r   r     s    2


r   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )r   aW
  Regular grid coordinate sampler; places more points on larger images.

    This is similar to ``RegularGridPointsSampler``, but the number of rows
    and columns is given as fractions of each image's height and width.
    Hence, more coordinates are generated for larger images.

    Parameters
    ----------
    n_rows_frac : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Relative number of coordinates to place on the y-axis. For a value
        ``y`` and image height ``H`` the number of actually placed coordinates
        (i.e. computed rows) is given by ``int(round(y*H))``.
        Note that for each image, the number of coordinates is clipped to the
        interval ``[1,H]``, where ``H`` is the image height.

            * If a single ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the interval
              ``[a, b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    n_cols_frac : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Relative number of coordinates to place on the x-axis. For a value
        ``x`` and image height ``W`` the number of actually placed coordinates
        (i.e. computed columns) is given by ``int(round(x*W))``.
        Note that for each image, the number of coordinates is clipped to the
        interval ``[1,W]``, where ``W`` is the image width.

            * If a single ``number``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the interval
              ``[a, b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> sampler = iaa.RelativeRegularGridPointsSampler(
    >>>     n_rows_frac=(0.01, 0.1),
    >>>     n_cols_frac=0.2)

    Create a point sampler that generates regular grids of points. These grids
    contain ``round(y*H)`` points on the y-axis, where ``y`` is sampled
    uniformly from the interval ``[0.01, 0.1]`` per image and ``H`` is the
    image height. On the x-axis, the grids always contain ``0.2*W`` points,
    where ``W`` is the image width.

    c                 C   sD   d}t j|dd| dfddd| _t j|dd| dfddd| _d S )Nr   r   r   r   T)r0   r+   r,   r   )r3   Zhandle_continuous_paramr   r   )r6   r   r   Zepsr   r   r   r2   `  s   z)RelativeRegularGridPointsSampler.__init__c                 C   s0   t |}t| | ||\}}t|||S r   )r   r   r   r   r   r   )r6   rP   r'   r   r   r   r   r   r   i  s   
z.RelativeRegularGridPointsSampler.sample_pointsc                 C   s   t |}|d}| jj||d d}| jj||d d}tdd |D }tdd |D }t|| }	t|| }
t	|	|
|\}	}
|	
tj|

tjfS )Nr	   r   rN   r   c                 S   r   r   r   r   r   r   r   r   z  r   zBRelativeRegularGridPointsSampler._draw_samples.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r   {  r   )rS   rT   r   rU   r   rV   r@   rp   r   r   r   )r6   rP   r'   n_augmentablesr_   r   r   r   r   r   r   r   r   r   r   r  s    
z.RelativeRegularGridPointsSampler._draw_samplesc                 C   r   )Nz(RelativeRegularGridPointsSampler(%s, %s))r   r   ry   r   r   r   r     s   z)RelativeRegularGridPointsSampler.__repr__c                 C   r   r   r   ry   r   r   r   r     r   z(RelativeRegularGridPointsSampler.__str__N)	r|   r}   r~   r   r2   r   r   r   r   r   r   r   r   r   *  s    5		r   c                   @   sX   e Zd ZdZdd Zedd Zdd Zdd	 Zd
d Z	edd Z
dd Zdd ZdS )r   a&  Remove a defined fraction of sampled points.

    Parameters
    ----------
    other_points_sampler : IPointsSampler
        Another point sampler that is queried to generate a list of points.
        The dropout operation will be applied to that list.

    p_drop : number or tuple of number or imgaug.parameters.StochasticParameter
        The probability that a coordinate will be removed from the list
        of all sampled coordinates. A value of ``1.0`` would mean that (on
        average) ``100`` percent of all coordinates will be dropped,
        while ``0.0`` denotes ``0`` percent. Note that this sampler will
        always ensure that at least one coordinate is left after the dropout
        operation, i.e. even ``1.0`` will only drop all *except one*
        coordinate.

            * If a ``float``, then that value will be used for all images.
            * If a ``tuple`` ``(a, b)``, then a value ``p`` will be sampled
              from the interval ``[a, b]`` per image.
            * If a ``StochasticParameter``, then this parameter will be used to
              determine per coordinate whether it should be *kept* (sampled
              value of ``>0.5``) or shouldn't be kept (sampled value of
              ``<=0.5``). If you instead want to provide the probability as
              a stochastic parameter, you can usually do
              ``imgaug.parameters.Binomial(1-p)`` to convert parameter `p` to
              a 0/1 representation.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> sampler = iaa.DropoutPointsSampler(
    >>>     iaa.RegularGridPointsSampler(10, 20),
    >>>     0.2)

    Create a point sampler that first generates points following a regular
    grid of ``10`` rows and ``20`` columns, then randomly drops ``20`` percent
    of these points.

    c                 C   s2   t |tsJ dt|f || _| || _d S )N^Expected to get an instance of IPointsSampler as argument 'other_points_sampler', got type %s.)r   r   r   other_points_sampler&_convert_p_drop_to_inverted_mask_paramp_drop)r6   r   r   r   r   r   r2     s   zDropoutPointsSampler.__init__c                 C   s  t |rtd| }|S t |rpt|dks"J dt|f |d |d k s6J d|d |d f d|d   krBdkrQn nd|d   krPdks]n J d|d |d f ttd|d  d|d  }|S t|tjry	 |S t	dt
|f )	Nr   r	   zKExpected 'p_drop' given as an iterable to contain exactly 2 values, got %d.r   zeExpected 'p_drop' given as iterable to contain exactly 2 values (a, b) with a < b. Got %.4f and %.4f.r   ziExpected 'p_drop' given as iterable to only contain values in the interval [0.0, 1.0], got %.4f and %.4f.zBExpected p_drop to be float or int or StochasticParameter, got %s.)r   Zis_single_numberr3   ZBinomialis_iterablerS   ZUniformr   ZStochasticParameter	Exceptionr   )rr   r   r   r   r   r     s>   

8"z;DropoutPointsSampler._convert_p_drop_to_inverted_mask_paramc                 C   sJ   t |}t| |d}| j||d }| ||d }| ||S )Nr	   r   r   )r   r   r   rT   r   r   r   _apply_dropout_masks)r6   rP   r'   r_   points_on_images
drop_masksr   r   r   r     s   

z"DropoutPointsSampler.sample_pointsc                    s*   | t|} fddt||D }|S )Nc                    s   g | ]
\}}  ||qS r   )_draw_samples_for_imager   points_on_imagera   ry   r   r   r     s    z6DropoutPointsSampler._draw_samples.<locals>.<listcomp>)rT   rS   rY   )r6   r   r'   r_   r   r   ry   r   r     s
   
z"DropoutPointsSampler._draw_samplesc                 C   s    | j t|f|}|dk}|S )Nr   )r   rU   rS   )r6   r   r'   Zdrop_samplesr   r   r   r   r     s
   z,DropoutPointsSampler._draw_samples_for_imagec                 C   st   g }t ||D ]0\}}t|dkr|}nt|s*t|d d }t|}d||< ||d d f }|| q|S )Nr   r   r	   T)rY   rS   rV   r   rj   r   )rr   r   Z
keep_masksZpoints_on_images_droppedr   r   Zpoi_droppedidxr   r   r   r     s   

z)DropoutPointsSampler._apply_dropout_masksc                 C   r   )NzDropoutPointsSampler(%s, %s))r   r   ry   r   r   r   r        zDropoutPointsSampler.__repr__c                 C   r   r   r   ry   r   r   r   r     r   zDropoutPointsSampler.__str__N)r|   r}   r~   r   r2   r   r   r   r   r   r   r   r   r   r   r   r   r     s    )


r   c                   @   sD   e Zd ZdZdd Zdd Zdd Zedd	 Zd
d Z	dd Z
dS )r   a}  Sample points uniformly on images.

    This point sampler generates `n_points` points per image. The x- and
    y-coordinates are both sampled from uniform distributions matching the
    respective image width and height.

    Parameters
    ----------
    n_points : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Number of points to sample on each image.

            * If a single ``int``, then that value will always be used.
            * If a ``tuple`` ``(a, b)``, then a value from the discrete
              interval ``[a..b]`` will be sampled per image.
            * If a ``list``, then a random value will be sampled from that
              ``list`` per image.
            * If a ``StochasticParameter``, then that parameter will be
              queried to draw one value per image.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> sampler = iaa.UniformPointsSampler(500)

    Create a point sampler that generates an array of ``500`` random points for
    each input image. The x- and y-coordinates of each point are sampled
    from uniform distributions.

    c                 C   s   t j|dddddd| _d S )Nr   r.   TFr/   )r3   r5   r   )r6   r   r   r   r   r2   +  s   zUniformPointsSampler.__init__c           	      C   sn   t |}t| |d}| t||d }t|}d| }|d dd|}|	|d}| 
|||S )Nr	   r   r   r   r   )r   r   r   rT   r   rS   rV   sumuniformr   $_convert_relative_coords_to_absolute)	r6   rP   r'   r_   n_points_imagewiseZn_points_totalZn_components_totalZcoords_relativeZcoords_relative_xyr   r   r   r   0  s   


z"UniformPointsSampler.sample_pointsc                 C   s$   | j j|f|d}t|dd }|S )NrN   r   )r   rU   rV   rW   )r6   r   r'   r   Zn_points_clippedr   r   r   r   ?  s
   
z"UniformPointsSampler._draw_samplesc                 C   s   g }d}t ||D ]I\}}|jdd \}}	|||| df }
|||| df }tt|
|	 d|	}tt|| d|}|tj||gdd ||7 }q	|S )Nr   r	   r   r   )Zaxis)rY   r   rV   rW   rp   r   stack)rr   Zcoords_rel_xyr   rP   Zcoords_absoluter`   r   Zn_points_imager   r   r   r   Zxx_intZyy_intr   r   r   r   E  s   
z9UniformPointsSampler._convert_relative_coords_to_absolutec                 C   s   d| j f S )NzUniformPointsSampler(%s))r   ry   r   r   r   r   V  s   zUniformPointsSampler.__repr__c                 C   r   r   r   ry   r   r   r   r   Y  r   zUniformPointsSampler.__str__N)r|   r}   r~   r   r2   r   r   r   r   r   r   r   r   r   r   r     s    
r   c                   @   s<   e Zd ZdZdd Zdd Zedd Zdd	 Zd
d Z	dS )SubsamplingPointsSamplera  Ensure that the number of sampled points is below a maximum.

    This point sampler will sample points from another sampler and
    then -- in case more points were generated than an allowed maximum --
    will randomly pick `n_points_max` of these.

    Parameters
    ----------
    other_points_sampler : IPointsSampler
        Another point sampler that is queried to generate a ``list`` of points.
        The dropout operation will be applied to that ``list``.

    n_points_max : int
        Maximum number of allowed points. If `other_points_sampler` generates
        more points than this maximum, a random subset of size `n_points_max`
        will be selected.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> sampler = iaa.SubsamplingPointsSampler(
    >>>     iaa.RelativeRegularGridPointsSampler(0.1, 0.2),
    >>>     50
    >>> )

    Create a points sampler that places ``y*H`` points on the y-axis (with
    ``y`` being ``0.1`` and ``H`` being an image's height) and ``x*W`` on
    the x-axis (analogous). Then, if that number of placed points exceeds
    ``50`` (can easily happen for larger images), a random subset of ``50``
    points will be picked and returned.

    c                 C   sN   t |tsJ dt|f || _t|dd | _| jdkr%td d S d S )Nr   r   r   zdGot n_points_max=0 in SubsamplingPointsSampler. This will result in no points ever getting returned.)	r   r   r   r   rV   rW   n_points_maxr   warn)r6   r   r   r   r   r   r2     s   
z!SubsamplingPointsSampler.__init__c                    sV   t |}t| |t|d } j||d } fddt||d d D S )Nr   r   c                    s    g | ]\}}  | j|qS r   )
_subsampler   r   ry   r   r   r     s    z:SubsamplingPointsSampler.sample_points.<locals>.<listcomp>)r   r   r   rT   rS   r   r   rY   )r6   rP   r'   r_   r   r   ry   r   r     s   

z&SubsamplingPointsSampler.sample_pointsc                 C   s8   t ||kr|S tt |}||d| }|| S )Nr   )rS   rV   r   Zpermutation)rr   r   r   r'   indicesr   r   r   r   r     s
   z#SubsamplingPointsSampler._subsamplec                 C   r   )Nz SubsamplingPointsSampler(%s, %d))r   r   ry   r   r   r   r     r   z!SubsamplingPointsSampler.__repr__c                 C   r   r   r   ry   r   r   r   r     r   z SubsamplingPointsSampler.__str__N)
r|   r}   r~   r   r2   r   r   r   r   r   r   r   r   r   r   ]  s    !
r   r   )0r   
__future__r   r   r   abcr   r   numpyrV   Zskimage.segmentationrZ   Zskimage.measuresixZ	six.movesmovesrk   Zimgaugr    r   r
   r   r   r3   r   rQ   r   Z	Augmenterr   r   r   r   r   r   r   r   r   r   add_metaclassobjectr   r   r   r   r   r   r   r   r   r   r   <module>   sN    $  
5
 W{ ( 7& b Q