o
    eK\                    @   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ZddlZddlZddlmZ ddlZddlmZmZmZ ddlmZ ddlmZ d	d
lmZ  e!ddd Z"e!ddd Z#e!ddd Z$e!ddd Z%dSddZ&dd Z'dd Z(dd Z)dd Z*dd  Z+d!d" Z,G d#d$ d$e-Z.e/eG d%d& d&e-Z0G d'd( d(e0e1Z2G d)d* d*e0e1Z3G d+d, d,e3Z4G d-d. d.e0Z5G d/d0 d0e0Z6G d1d2 d2e0Z7G d3d4 d4e7Z8G d5d6 d6e0Z9G d7d8 d8e9Z:G d9d: d:e-Z;G d;d< d<e9Z<G d=d> d>e-Z=G d?d@ d@e-Z>G dAdB dBe-Z?G dCdD dDe-Z@G dEdF dFe-ZAG dGdH dHe-ZBG dIdJ dJe-ZCG dKdL dLe0ZDdTdMdNZEG dOdP dPe0ZFG dQdR dRe0ZGdS )Ua  
Augmenters that don't apply augmentations themselves, but are needed
for meta usage.

List of augmenters:

    * :class:`Augmenter` (base class for all augmenters)
    * :class:`Sequential`
    * :class:`SomeOf`
    * :class:`OneOf`
    * :class:`Sometimes`
    * :class:`WithChannels`
    * :class:`Identity`
    * :class:`Noop`
    * :class:`Lambda`
    * :class:`AssertLambda`
    * :class:`AssertShape`
    * :class:`ChannelShuffle`

Note: :class:`~imgaug.augmenters.color.WithColorspace` is in ``color.py``.

    )print_functiondivisionabsolute_import)ABCMetaabstractmethodN)BatchUnnormalizedBatch_BatchInAugmentation   )
parameters)random   )basezimgaug.dtypes.clip_c                 C      t | ||S )zClip image in-place.)clip_augmented_images_image	min_value	max_value r   FD:\Projects\ConvertPro\env\Lib\site-packages\imgaug/augmenters/meta.pyclip_augmented_image_,      r   c                 C   r   )zClip image.)clip_augmented_imagesr   r   r   r   clip_augmented_image2   r   r   c                    s0   t | rtj|  | dS  fdd| D S )zClip images in-place.outc                    s   g | ]}t j| |d qS )r   )npclip.0r   r   r   r   r   
<listcomp>=   s    z*clip_augmented_images_.<locals>.<listcomp>)iais_np_arrayr   r   imagesr   r   r   r!   r   r   8   s
   
r   c                 C   s0   t | rt| } ndd | D } t| ||S )zClip images.c                 S      g | ]}t |qS r   r   copyr   r   r   r   r"   G       z)clip_augmented_images.<locals>.<listcomp>)r#   r$   r   r)   r   r%   r   r   r   r   A   s   
r   
sequentialc                 C   s  | du r|dkrt g d||f dS |S t| trCt| r9tdd | D }|s7J ddd	d | D  | S t | d||f dS t| rwt| d
krT|dkrT|S tdd | D }|smJ dddd | D  t | d||f dS td||t	| f )z/Normalize an augmenter list provided by a user.Nr+   z%s-%snamec                 S      g | ]}t |tqS r   
isinstance	Augmenterr    childr   r   r   r"   T       z(handle_children_list.<locals>.<listcomp>5Expected all children to be augmenters, got types %s., c                 S      g | ]}t t|qS r   strtyper    vr   r   r   r"   X       r   c                 S   r.   r   r/   r2   r   r   r   r"   ^   r4   c                 S   r7   r   r8   r;   r   r   r   r"   b   r=   z^Expected None, Augmenter or list/tuple as children list %s for augmenter with name %s, got %s.)

Sequentialr0   r1   r#   is_iterablealljoinlen	Exceptionr:   )lstZaugmenter_nameZlst_namedefaultZonly_augmentersr   r   r   handle_children_listK   sD   



rF   c                 C   sX   g }g }t | D ]\}}t|dsJ dt|f |js'|| || q||fS )zERemove from a list all objects that don't follow ``obj.empty==True``.emptyz3Expected object with property 'empty'. Got type %s.)	enumeratehasattrr:   rG   append)objsobjs_reducedidsiobjr   r   r   reduce_to_nonemptyj   s   

rP   c                 C   s(   t | }t||D ]\}}|||< q	|S )z&Inverse of :func:`reduce_to_nonempty`.)listzip)rK   rM   rL   Zobjs_invidxZobj_from_reducedr   r   r   invert_reduce_to_nonemptyx   s   
rT   c                 C   sp   t | r| jdksJ d| jf | jd S t | s%J dt| f t| dkr-dS dd | D }t|S )	zDCompute the maximum number of image channels among a list of images.   zNExpected 'images' to be 4-dimensional if provided as array. Got %d dimensions.   z5Expected 'images' to be an array or iterable, got %s.r   Nc                 S   s(   g | ]}t |jd kr|jd ndqS )rV   r
   r   rB   shaper    elr   r   r   r"      s   ( z3estimate_max_number_of_channels.<locals>.<listcomp>)r#   r$   ndimrX   r?   r:   rB   max)r&   channelsr   r   r   estimate_max_number_of_channels   s    

r^   c                 C   s"   t | r
t| S dd | D S )z@Copy the arrays of a single input array or list of input arrays.c                 S   r'   r   r(   )r    arrayr   r   r   r"      r*   zcopy_arrays.<locals>.<listcomp>)r#   r$   r   r)   )Zarraysr   r   r   copy_arrays   s   

r`   c                 C   s4   t | r| jdkr| dtjf S | S dd | D S )NrV   .c                 S   s(   g | ]}|j d kr|dtjf n|qS )r
   .)r[   r   newaxisr    arrr   r   r   r"      s    
z%_add_channel_axis.<locals>.<listcomp>)r#   r$   r[   r   ra   )Zarrsr   r   r   _add_channel_axis   s   

rd   c                 C   sL   t |r|jdkrt | r| d S dd | D S | S dd t| |D S )NrV   .r   c                 S   s   g | ]}|d  qS )re   r   rb   r   r   r   r"          z._remove_added_channel_axis.<locals>.<listcomp>c                 S   s&   g | ]\}}|j d kr|d n|qS )r
   re   )r[   )r    Z	arr_addedZarr_origr   r   r   r"      s    
)r#   r$   r[   rR   )Z
arrs_addedZ	arrs_origr   r   r   _remove_added_channel_axis   s   


rg   c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
_maybe_deterministic_ctxa  Context that resets an RNG to its initial state upon exit.

    This allows to execute some sampling functions and leave the code block
    with the used RNG in the same state as before.

    Parameters
    ----------
    random_state : imgaug.random.RNG or imgaug.augmenters.meta.Augmenter
        The RNG to reset. If this is an augmenter, then the augmenter's
        RNG will be used.

    deterministic : None or bool
        Whether to reset the RNG upon exit (``True``) or not (``False``).
        Allowed to be ``None`` iff `random_state` was an augmenter, in which
        case that augmenter's ``deterministic`` attribute will be used.

    Nc                 C   sD   |d u r|}|j | _ |j| _n|d usJ d|| _ || _d | _d S )Nz.Expected boolean as `deterministic`, got None.)random_statedeterministic	old_state)selfri   rj   	augmenterr   r   r   __init__   s   


z!_maybe_deterministic_ctx.__init__c                 C   s   | j r
| jj| _d S d S N)rj   ri   staterk   rl   r   r   r   	__enter__   s   z"_maybe_deterministic_ctx.__enter__c                 C   s   | j d ur| j | j_d S d S ro   )rk   ri   rp   )rl   Zexception_typeZexception_valueZexception_tracebackr   r   r   __exit__   s   
z!_maybe_deterministic_ctx.__exit__ro   )__name__
__module____qualname____doc__rn   rr   rs   r   r   r   r   rh      s
    
rh   c                       s@  e Zd ZdZ			dt fdd	ZduddZejd	d
ddvddZdwddZ	dd Z
dvddZdwddZdd ZdwddZdd ZdwddZdd Zdwd d!Zd"d# Z		dwd$d%Zdwd&d'Z		dwd(d)Zd*d+ Zd,d- Zd.d/ Zd0d1 Z	dvd2d3Zd4d5 Zd6d7 Ze	dwd8d9Zed:d; Z dxd<d=Z!d>d? Z"dyd@dAZ#dBdC Z$dDdE Z%dvdFdGZ&dHdI Z'edJdudKdLZ(dudMdNZ)dzdPdQZ*dzdRdSZ+	T	d{dUdVZ,	T	d{dWdXZ-e.dYdZ Z/d[d\ Z0d|d]d^Z1d}d_d`Z2d~dadbZ3d~dcddZ4	O	ddedfZ5edgdvdhdiZ6dvdjdkZ7dldm Z8dndo Z9dpdq Z:drds Z;  Z<S )r1   a"  
    Base class for Augmenter objects.
    All augmenters derive from this class.

    Parameters
    ----------
    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
        Seed to use for this augmenter's random number generator (RNG) or
        alternatively an RNG itself. Setting this parameter allows to
        control/influence the random number sampling of this specific
        augmenter without affecting other augmenters. Usually, there is no
        need to set this parameter.

            * If ``None``: The global RNG is used (shared by all
              augmenters).
            * If ``int``: The value will be used as a seed for a new
              :class:`~imgaug.random.RNG` instance.
            * If :class:`~imgaug.random.RNG`: The ``RNG`` instance will be
              used without changes.
            * If :class:`~imgaug.random.Generator`: A new
              :class:`~imgaug.random.RNG` instance will be
              created, containing that generator.
            * If :class:`~imgaug.random.bit_generator.BitGenerator`: Will
              be wrapped in a :class:`~imgaug.random.Generator`. Then
              similar behaviour to :class:`~imgaug.random.Generator`
              parameters.
            * If :class:`~imgaug.random.SeedSequence`: Will
              be wrapped in a new bit generator and
              :class:`~imgaug.random.Generator`. Then
              similar behaviour to :class:`~imgaug.random.Generator`
              parameters.
            * If :class:`~imgaug.random.RandomState`: Similar behaviour to
              :class:`~imgaug.random.Generator`. Outdated in numpy 1.17+.

        If a new bit generator has to be created, it will be an instance
        of :class:`numpy.random.SFC64`.

        Added in 0.4.0.

    name : None or str, optional
        Name given to the Augmenter instance. This name is used when
        converting the instance to a string, e.g. for ``print`` statements.
        It is also used for ``find``, ``remove`` or similar operations
        on augmenters with children.
        If ``None``, ``UnnamedX`` will be used as the name, where ``X``
        is the Augmenter's class name.

    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.

    N
deprecatedc                    s   t t|   |du st|sJ dt|f |du r&d| jjf | _n|| _|dkrCtj	ddd t
|sBJ dt|f nd	}|| _|dkrV|du sTJ d
|}|rc|du rctj | _nt|| _d| _dS )z Create a new Augmenter instance.Nz0Expected name to be None or string-like, got %s.z	Unnamed%srx   zThe parameter `deterministic` is deprecated in `imgaug.augmenters.meta.Augmenter`. Use `.to_deterministic()` to switch into deterministic mode.rU   )
stacklevelz/Expected deterministic to be a boolean, got %s.Fz*Cannot set both `seed` and `random_state`.T)superr1   rn   r#   	is_stringr:   	__class__rt   r-   warn_deprecatedis_single_boolrj   iarandomRNGcreate_pseudo_random_ri   	activatedrl   seedr-   ri   rj   r|   r   r   rn     s8   
zAugmenter.__init__Fc                 #   sr   t ttfrgtrtstr(ts(J dtf |r2|du s2J ddd  dd }|s^t	D ]\}} ||\}}| j
||d}||||}	|	V  q@dS d	dlm}
 t  fd
d}|
| ;}|jjd }|j| |dD ]#}|jd	 }|v sJ d| | \}}||||}	|= |	V  qW d   dS 1 sw   Y  dS )a  Augment multiple batches.

        In contrast to other ``augment_*`` method, this one **yields**
        batches instead of returning a full list. This is more suited
        for most training loops.

        This method also also supports augmentation on multiple cpu cores,
        activated via the `background` flag. If the `background` flag
        is activated, an instance of :class:`~imgaug.multicore.Pool` will
        be spawned using all available logical CPU cores and an
        ``output_buffer_size`` of ``C*10``, where ``C`` is the number of
        logical CPU cores. I.e. a maximum of ``C*10`` batches will be somewhere
        in the augmentation pipeline (or waiting to be retrieved by downstream
        functions) before this method temporarily stops the loading of new
        batches from `batches`.

        Parameters
        ----------
        batches : imgaug.augmentables.batches.Batch or imgaug.augmentables.batches.UnnormalizedBatch or iterable of imgaug.augmentables.batches.Batch or iterable of imgaug.augmentables.batches.UnnormalizedBatch
            A single batch or a list of batches to augment.

        hooks : None or imgaug.HooksImages, optional
            HooksImages object to dynamically interfere with the augmentation
            process.

        background : bool, optional
            Whether to augment the batches in background processes.
            If ``True``, hooks can currently not be used as that would require
            pickling functions.
            Note that multicore augmentation distributes the batches onto
            different CPU cores. It does *not* split the data *within* batches.
            It is therefore *not* sensible to use ``background=True`` to
            augment a single batch. Only use it for multiple batches.
            Note also that multicore augmentation needs some time to start. It
            is therefore not recommended to use it for very few batches.

        Yields
        -------
        imgaug.augmentables.batches.Batch or imgaug.augmentables.batches.UnnormalizedBatch or iterable of imgaug.augmentables.batches.Batch or iterable of imgaug.augmentables.batches.UnnormalizedBatch
            Augmented batches.

        z\Expected either (a) an iterable that is not an array or a string or (b) a generator. Got: %sNz@Hooks can not be used when background augmentation is activated.c                 S   s  t |tr| }| |jf|_|}d}nt |tr(| }| |jf|_|}d}nt|rD|jdv s:J d|j	f t|| fd}d}nt |t
rt|dkrXt| fd}d	}nt|d rit|| fd}d
}nnt |d tjr{t|| fd}d}n\t |d tjrt|| fd}d}nJt |d tjrt|| fd}d}n8t |d tjrt|| fd}d}n&t |d tjrt|| fd}d}ntdt|d f tdt|f |dvrtd|f  ||fS )Nimgaug.Batchimgaug.UnnormalizedBatch)rV   rU   zEExpected numpy array to have shape (N, H, W) or (N, H, W, C), got %s.)r&   datanumpy_arrayr   )r   
empty_listlist_of_numpy_arrays)heatmapsr   list_of_imgaug.HeatmapsOnImage)segmentation_mapsr   &list_of_imgaug.SegmentationMapsOnImage)	keypointsr   list_of_imgaug.KeypointsOnImage)bounding_boxesr   #list_of_imgaug.BoundingBoxesOnImage)polygonsr   list_of_imgaug.PolygonsOnImagezUnknown datatype in batch[0]. Expected numpy array or imgaug.HeatmapsOnImage or imgaug.SegmentationMapsOnImage or imgaug.KeypointsOnImage or imgaug.BoundingBoxesOnImage, or imgaug.PolygonsOnImage, got %s.a  Unknown datatype of batch. Expected imgaug.Batch or imgaug.UnnormalizedBatch or numpy array or list of (numpy array or imgaug.HeatmapsOnImage or imgaug.SegmentationMapsOnImage or imgaug.KeypointsOnImage or imgaug.BoundingBoxesOnImage or imgaug.PolygonsOnImage). Got %s.)r   r   zReceived an input in augment_batches() that was not an instance of imgaug.augmentables.batches.Batch or imgaug.augmentables.batches.UnnormalizedBatch, but instead %s. This is deprecated. Use augment() for such data or wrap it in a Batch instance.)r0   r   deepcopyr   r   to_normalized_batchr#   r$   r[   rX   rQ   rB   HeatmapsOnImageSegmentationMapsOnImageKeypointsOnImageBoundingBoxesOnImagePolygonsOnImagerC   r:   r}   )rS   batchZ
batch_copybatch_normalizedbatch_orig_dtr   r   r   _normalize_batch  sx   



	
z3Augmenter.augment_batches.<locals>._normalize_batchc                 S   s   |dkr| }|j d |_ |S |dkr| j d | _ || }|S |dkr(| j}|S |dkr0g }|S |dkr9| j}|S |dkrB| j}|S |dkrK| j}|S |d	krT| j}|S |d
kr]| j}|S |dksjJ dt|f | j}|S )Nr   r   r   r   r   r   r   r   r   r   r   zGot an unexpected type %s.)	r   Z$fill_from_augmented_normalized_batch
images_augheatmaps_augsegmentation_maps_augkeypoints_augbounding_boxes_augr:   polygons_aug)	batch_aug
batch_origr   batch_unnormalizedr   r   r   _unnormalize_batch  sF   	
z5Augmenter.augment_batches.<locals>._unnormalize_batchhooksr   c                  3   s8    t D ]\} } | |\}}||f| < |V  qd S ro   )rH   )rS   r   r   r   r   batchesZid_to_batch_origr   r   load_batches  s   z/Augmenter.augment_batches.<locals>.load_batches
   )output_buffer_sizez)Got idx %d from Pool, which is not known.)r0   r   r   r#   r?   r$   r{   Zis_generatorr:   rH   augment_batch_imgaug.multicore	multicoredictPoolpoolZ
_processesZimap_batchesr   )rl   r   r   
backgroundr   rS   r   r   r   r   r   r   r   r   r   r   r   r   r   augment_batchesG  sl   +
H



"zAugmenter.augment_batcheszaugment_batch_()a  `augment_batch()` was renamed to `augment_batch_()` as it changes all `*_unaug` attributes of batches in-place. Note that `augment_batch_()` has now a `parents` parameter. Calls of the style `augment_batch(batch, hooks)` must be changed to `augment_batch(batch, hooks=hooks)`.)commentc                 C   s   | j ||dS )zBAugment a single batch.

        Deprecated since 0.4.0.

        r   )r   )rl   r   r   r   r   r   augment_batch  s   zAugmenter.augment_batchc                 C   s  d}d}t |tr|}n&t |tr|}| }| }nt |tr(|}| }n
tdt|jf |j	}|durQ|D ]}|j
|j| |d}	t||j|	 q;|j	}g }
| jsh|D ]}|
| t||jd qXn"|dur|D ]}|j|j| || jd}|s|
| t||jd qnt|  |js| j|| j|dur|ng |d}W d   n1 sw   Y  |
D ]
}t||j|j q|dur|j	}|D ]}|j|j| |d}t||j| q|dur||}||}|S |dur||}|S |S )a  
        Augment a single batch in-place.

        Added in 0.4.0.

        Parameters
        ----------
        batch : imgaug.augmentables.batches.Batch or imgaug.augmentables.batches.UnnormalizedBatch or imgaug.augmentables.batch._BatchInAugmentation
            A single batch to augment.

            If :class:`imgaug.augmentables.batches.UnnormalizedBatch`
            or :class:`imgaug.augmentables.batches.Batch`, then the ``*_aug``
            attributes may be modified in-place, while the ``*_unaug``
            attributes will not be modified.
            If :class:`imgaug.augmentables.batches._BatchInAugmentation`,
            then all attributes may be modified in-place.

        parents : None or list of imgaug.augmenters.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as
            ``None``. It is set automatically for child augmenters.

        hooks : None or imgaug.HooksImages, optional
            HooksImages object to dynamically interfere with the augmentation
            process.

        Returns
        -------
        imgaug.augmentables.batches.Batch or imgaug.augmentables.batches.UnnormalizedBatch
            Augmented batch.

        NzBExpected UnnormalizedBatch, Batch or _BatchInAugmentation, got %s.)rm   parents)rm   r   rE   ri   r   r   )r0   r	   r   r   Zto_batch_in_augmentationr   
ValueErrorr:   rt   columns
preprocessvaluesetattr	attr_namer   rJ   Zis_activatedrh   rG   _augment_batch_ri   postprocessZ fill_from_batch_in_augmentation_Z%fill_from_augmented_normalized_batch_)rl   r   r   r   Zbatch_unnormZ
batch_normZbatch_inaugr   columnr   Zset_to_noner   Z
augm_valuer   r   r   r   )  s   %








	zAugmenter.augment_batch_c           
   	   C   s   |j }t|dk}| jp|}|D ]-}t|| t| d|j |j|||d}	t||j|	 W d   n1 s8w   Y  q|rG| jsG|	  |S )a  Augment a single batch in-place.

        This is the internal version of :func:`Augmenter.augment_batch_`.
        It is called from :func:`Augmenter.augment_batch_` and should usually
        not be called directly.
        This method may transform the batches in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        Added in 0.4.0.

        Parameters
        ----------
        batch : imgaug.augmentables.batches._BatchInAugmentation
            The normalized batch to augment. May be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_batch_`.

        hooks : imgaug.imgaug.HooksImages or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_batch_`.

        Returns
        ----------
        imgaug.augmentables.batches._BatchInAugmentation
            The augmented batch.

        r   Z	_augment_r   N)
r   rB   rj   rh   getattrr-   r   r   r   Zadvance_)
rl   r   ri   r   r   r   Zmultiple_columnsrj   r   r   r   r   r   r     s   (


zAugmenter._augment_batch_c                 C   sV   t |sJ dt|j f|jdv sJ d|jf t| | j|g|dd S )a  Augment a single image.

        Parameters
        ----------
        image : (H,W,C) ndarray or (H,W) ndarray
            The image to augment.
            Channel-axis is optional, but expected to be the last axis if
            present. In most cases, this array should be of dtype ``uint8``,
            which is supported by all augmenters. Support for other dtypes
            varies by augmenter -- see the respective augmenter-specific
            documentation for more details.

        hooks : None or imgaug.HooksImages, optional
            HooksImages object to dynamically interfere with the augmentation
            process.

        Returns
        -------
        ndarray
            The corresponding augmented image.

        zExpected to get a single numpy array of shape (H,W) or (H,W,C) for `image`. Got instead type %d. Use `augment_images(images)` to augment a list of multiple images.)r
   rV   zGExpected image to have shape (height, width, [channels]), got shape %s.r   r   )	r#   r$   r:   rt   r[   rX   iabase&_warn_on_suspicious_single_image_shapeaugment_images)rl   r   r   r   r   r   augment_image  s   
zAugmenter.augment_imagec                 C   s"   t | | jt|d||djS )a@  Augment a batch of images.

        Parameters
        ----------
        images : (N,H,W,C) ndarray or (N,H,W) ndarray or list of (H,W,C) ndarray or list of (H,W) ndarray
            Images to augment.
            The input can be a list of numpy arrays or a single array. Each
            array is expected to have shape ``(H, W, C)`` or ``(H, W)``,
            where ``H`` is the height, ``W`` is the width and ``C`` are the
            channels. The number of channels may differ between images.
            If a list is provided, the height, width and channels may differ
            between images within the provided batch.
            In most cases, the image array(s) should be of dtype ``uint8``,
            which is supported by all augmenters. Support for other dtypes
            varies by augmenter -- see the respective augmenter-specific
            documentation for more details.

        parents : None or list of imgaug.augmenters.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as
            ``None``. It is set automatically for child augmenters.

        hooks : None or imgaug.imgaug.HooksImages, optional
            :class:`~imgaug.imgaug.HooksImages` object to dynamically
            interfere with the augmentation process.

        Returns
        -------
        ndarray or list
            Corresponding augmented images.
            If the input was an ``ndarray``, the output is also an ``ndarray``,
            unless the used augmentations have led to different output image
            sizes (as can happen in e.g. cropping).

        Examples
        --------
        >>> import imgaug.augmenters as iaa
        >>> import numpy as np
        >>> aug = iaa.GaussianBlur((0.0, 3.0))
        >>> # create empty example images
        >>> images = np.zeros((2, 64, 64, 3), dtype=np.uint8)
        >>> images_aug = aug.augment_images(images)

        Create ``2`` empty (i.e. black) example numpy images and apply
        gaussian blurring to them.

        r&   r   r   )r   &_warn_on_suspicious_multi_image_shapesr   r   r   )rl   r&   r   r   r   r   r   r     s   
0zAugmenter.augment_imagesc                 C      |S )a(  Augment a batch of images in-place.

        This is the internal version of :func:`Augmenter.augment_images`.
        It is called from :func:`Augmenter.augment_images` and should usually
        not be called directly.
        It has to be implemented by every augmenter.
        This method may transform the images in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        .. note::

            This method exists mostly for legacy-support.
            Overwriting :func:`~imgaug.augmenters.meta.Augmenter._augment_batch`
            is now the preferred way of implementing custom augmentation
            routines.

        Parameters
        ----------
        images : (N,H,W,C) ndarray or list of (H,W,C) ndarray
            Images to augment.
            They may be changed in-place.
            Either a list of ``(H, W, C)`` arrays or a single ``(N, H, W, C)``
            array, where ``N`` is the number of images, ``H`` is the height of
            images, ``W`` is the width of images and ``C`` is the number of
            channels of images. In the case of a list as input, ``H``, ``W``
            and ``C`` may change per image.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_images`.

        hooks : imgaug.imgaug.HooksImages or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_images`.

        Returns
        ----------
        (N,H,W,C) ndarray or list of (H,W,C) ndarray
            The augmented images.

        r   rl   r&   ri   r   r   r   r   r   _augment_images<  s   .zAugmenter._augment_imagesc                 C      | j t|d||djS )a  Augment a batch of heatmaps.

        Parameters
        ----------
        heatmaps : imgaug.augmentables.heatmaps.HeatmapsOnImage or list of imgaug.augmentables.heatmaps.HeatmapsOnImage
            Heatmap(s) to augment. Either a single heatmap or a list of
            heatmaps.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as
            ``None``.
            It is set automatically for child augmenters.

        hooks : None or imaug.imgaug.HooksHeatmaps, optional
            :class:`~imgaug.imgaug.HooksHeatmaps` object to dynamically
            interfere with the augmentation process.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage or list of imgaug.augmentables.heatmaps.HeatmapsOnImage
            Corresponding augmented heatmap(s).

        )r   r   )r   r   r   )rl   r   r   r   r   r   r   augment_heatmapsl  s
   zAugmenter.augment_heatmapsc                 C   r   )a!  Augment a batch of heatmaps in-place.

        This is the internal version of :func:`Augmenter.augment_heatmaps`.
        It is called from :func:`Augmenter.augment_heatmaps` and should
        usually not be called directly.
        This method may augment heatmaps in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        .. note::

            This method exists mostly for legacy-support.
            Overwriting :func:`~imgaug.augmenters.meta.Augmenter._augment_batch`
            is now the preferred way of implementing custom augmentation
            routines.

        Parameters
        ----------
        heatmaps : list of imgaug.augmentables.heatmaps.HeatmapsOnImage
            Heatmaps to augment. They may be changed in-place.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_heatmaps`.

        hooks : imgaug.imgaug.HooksHeatmaps or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_heatmaps`.

        Returns
        ----------
        images : list of imgaug.augmentables.heatmaps.HeatmapsOnImage
            The augmented heatmaps.

        r   )rl   r   ri   r   r   r   r   r   _augment_heatmaps     #zAugmenter._augment_heatmapsc                 C   r   )a  Augment a batch of segmentation maps.

        Parameters
        ----------
        segmaps : imgaug.augmentables.segmaps.SegmentationMapsOnImage or list of imgaug.augmentables.segmaps.SegmentationMapsOnImage
            Segmentation map(s) to augment. Either a single segmentation map
            or a list of segmentation maps.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as
            ``None``. It is set automatically for child augmenters.

        hooks : None or imgaug.HooksHeatmaps, optional
            :class:`~imgaug.imgaug.HooksHeatmaps` object to dynamically
            interfere with the augmentation process.

        Returns
        -------
        imgaug.augmentables.segmaps.SegmentationMapsOnImage or list of imgaug.augmentables.segmaps.SegmentationMapsOnImage
            Corresponding augmented segmentation map(s).

        )r   r   )r   r   r   )rl   segmapsr   r   r   r   r   augment_segmentation_maps  s   z#Augmenter.augment_segmentation_mapsc                 C   r   )a  Augment a batch of segmentation in-place.

        This is the internal version of
        :func:`Augmenter.augment_segmentation_maps`.
        It is called from :func:`Augmenter.augment_segmentation_maps` and
        should usually not be called directly.
        This method may augment segmentation maps in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        .. note::

            This method exists mostly for legacy-support.
            Overwriting :func:`~imgaug.augmenters.meta.Augmenter._augment_batch`
            is now the preferred way of implementing custom augmentation
            routines.

        Parameters
        ----------
        segmaps : list of imgaug.augmentables.segmaps.SegmentationMapsOnImage
            Segmentation maps to augment. They may be changed in-place.

        parents : list of imgaug.augmenters.meta.Augmenter
            See
            :func:`~imgaug.augmenters.meta.Augmenter.augment_segmentation_maps`.

        hooks : imgaug.imgaug.HooksHeatmaps or None
            See
            :func:`~imgaug.augmenters.meta.Augmenter.augment_segmentation_maps`.

        Returns
        ----------
        images : list of imgaug.augmentables.segmaps.SegmentationMapsOnImage
            The augmented segmentation maps.

        r   )rl   r   ri   r   r   r   r   r   _augment_segmentation_maps  s   &z$Augmenter._augment_segmentation_mapsc                 C   r   )a
  Augment a batch of keypoints/landmarks.

        This is the corresponding function to :func:`Augmenter.augment_images`,
        just for keypoints/landmarks (i.e. points on images).
        Usually you will want to call :func:`Augmenter.augment_images` with
        a list of images, e.g. ``augment_images([A, B, C])`` and then
        ``augment_keypoints()`` with the corresponding list of keypoints on
        these images, e.g. ``augment_keypoints([Ak, Bk, Ck])``, where ``Ak``
        are the keypoints on image ``A``.

        Make sure to first convert the augmenter(s) to deterministic states
        before augmenting images and their corresponding keypoints,
        e.g. by

        >>> import imgaug.augmenters as iaa
        >>> from imgaug.augmentables.kps import Keypoint
        >>> from imgaug.augmentables.kps import KeypointsOnImage
        >>> A = B = C = np.zeros((10, 10), dtype=np.uint8)
        >>> Ak = Bk = Ck = KeypointsOnImage([Keypoint(2, 2)], (10, 10))
        >>> seq = iaa.Fliplr(0.5)
        >>> seq_det = seq.to_deterministic()
        >>> imgs_aug = seq_det.augment_images([A, B, C])
        >>> kps_aug = seq_det.augment_keypoints([Ak, Bk, Ck])

        Otherwise, different random values will be sampled for the image
        and keypoint augmentations, resulting in different augmentations (e.g.
        images might be rotated by ``30deg`` and keypoints by ``-10deg``).
        Also make sure to call :func:`Augmenter.to_deterministic` again for
        each new batch, otherwise you would augment all batches in the same
        way.

        Note that there is also :func:`Augmenter.augment`, which automatically
        handles the random state alignment.

        Parameters
        ----------
        keypoints_on_images : imgaug.augmentables.kps.KeypointsOnImage or list of imgaug.augmentables.kps.KeypointsOnImage
            The keypoints/landmarks to augment.
            Either a single instance of
            :class:`~imgaug.augmentables.kps.KeypointsOnImage` or a list of
            such instances. Each instance must contain the keypoints of a
            single image.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as
            ``None``. It is set automatically for child augmenters.

        hooks : None or imgaug.imgaug.HooksKeypoints, optional
            :class:`~imgaug.imgaug.HooksKeypoints` object to dynamically
            interfere with the augmentation process.

        Returns
        -------
        imgaug.augmentables.kps.KeypointsOnImage or list of imgaug.augmentables.kps.KeypointsOnImage
            Augmented keypoints.

        )r   r   )r   r   r   )rl   keypoints_on_imagesr   r   r   r   r   augment_keypoints  s   ;zAugmenter.augment_keypointsc                 C   r   )a  Augment a batch of keypoints in-place.

        This is the internal version of :func:`Augmenter.augment_keypoints`.
        It is called from :func:`Augmenter.augment_keypoints` and should
        usually not be called directly.
        This method may transform the keypoints in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        .. note::

            This method exists mostly for legacy-support.
            Overwriting :func:`~imgaug.augmenters.meta.Augmenter._augment_batch`
            is now the preferred way of implementing custom augmentation
            routines.

        Parameters
        ----------
        keypoints_on_images : list of imgaug.augmentables.kps.KeypointsOnImage
            Keypoints to augment. They may be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_keypoints`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_keypoints`.

        Returns
        ----------
        list of imgaug.augmentables.kps.KeypointsOnImage
            The augmented keypoints.

        r   )rl   r   ri   r   r   r   r   r   _augment_keypoints5  s   'zAugmenter._augment_keypointsc                 C   r   )a@  Augment a batch of bounding boxes.

        This is the corresponding function to
        :func:`Augmenter.augment_images`, just for bounding boxes.
        Usually you will want to call :func:`Augmenter.augment_images` with
        a list of images, e.g. ``augment_images([A, B, C])`` and then
        ``augment_bounding_boxes()`` with the corresponding list of bounding
        boxes on these images, e.g.
        ``augment_bounding_boxes([Abb, Bbb, Cbb])``, where ``Abb`` are the
        bounding boxes on image ``A``.

        Make sure to first convert the augmenter(s) to deterministic states
        before augmenting images and their corresponding bounding boxes,
        e.g. by

        >>> import imgaug.augmenters as iaa
        >>> from imgaug.augmentables.bbs import BoundingBox
        >>> from imgaug.augmentables.bbs import BoundingBoxesOnImage
        >>> A = B = C = np.ones((10, 10), dtype=np.uint8)
        >>> Abb = Bbb = Cbb = BoundingBoxesOnImage([
        >>>     BoundingBox(1, 1, 9, 9)], (10, 10))
        >>> seq = iaa.Fliplr(0.5)
        >>> seq_det = seq.to_deterministic()
        >>> imgs_aug = seq_det.augment_images([A, B, C])
        >>> bbs_aug = seq_det.augment_bounding_boxes([Abb, Bbb, Cbb])

        Otherwise, different random values will be sampled for the image
        and bounding box augmentations, resulting in different augmentations
        (e.g. images might be rotated by ``30deg`` and bounding boxes by
        ``-10deg``). Also make sure to call :func:`Augmenter.to_deterministic`
        again for each new batch, otherwise you would augment all batches in
        the same way.

        Note that there is also :func:`Augmenter.augment`, which automatically
        handles the random state alignment.

        Parameters
        ----------
        bounding_boxes_on_images : imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.bbs.BoundingBoxesOnImage
            The bounding boxes to augment.
            Either a single instance of
            :class:`~imgaug.augmentables.bbs.BoundingBoxesOnImage` or a list of
            such instances, with each one of them containing the bounding
            boxes of a single image.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as
            ``None``. It is set automatically for child augmenters.

        hooks : None or imgaug.imgaug.HooksKeypoints, optional
            :class:`~imgaug.imgaug.HooksKeypoints` object to dynamically
            interfere with the augmentation process.

        Returns
        -------
        imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.bbs.BoundingBoxesOnImage
            Augmented bounding boxes.

        )r   r   )r   r   r   )rl   bounding_boxes_on_imagesr   r   r   r   r   augment_bounding_boxes^  s   >z Augmenter.augment_bounding_boxesc                 C   r   )a
  Augment a batch of polygons.

        This is the corresponding function to :func:`Augmenter.augment_images`,
        just for polygons.
        Usually you will want to call :func:`Augmenter.augment_images`` with
        a list of images, e.g. ``augment_images([A, B, C])`` and then
        ``augment_polygons()`` with the corresponding list of polygons on these
        images, e.g. ``augment_polygons([A_poly, B_poly, C_poly])``, where
        ``A_poly`` are the polygons on image ``A``.

        Make sure to first convert the augmenter(s) to deterministic states
        before augmenting images and their corresponding polygons,
        e.g. by

        >>> import imgaug.augmenters as iaa
        >>> from imgaug.augmentables.polys import Polygon, PolygonsOnImage
        >>> A = B = C = np.ones((10, 10), dtype=np.uint8)
        >>> Apoly = Bpoly = Cpoly = PolygonsOnImage(
        >>>     [Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])],
        >>>     shape=(10, 10))
        >>> seq = iaa.Fliplr(0.5)
        >>> seq_det = seq.to_deterministic()
        >>> imgs_aug = seq_det.augment_images([A, B, C])
        >>> polys_aug = seq_det.augment_polygons([Apoly, Bpoly, Cpoly])

        Otherwise, different random values will be sampled for the image
        and polygon augmentations, resulting in different augmentations
        (e.g. images might be rotated by ``30deg`` and polygons by
        ``-10deg``). Also make sure to call ``to_deterministic()`` again for
        each new batch, otherwise you would augment all batches in the same
        way.

        Note that there is also :func:`Augmenter.augment`, which automatically
        handles the random state alignment.

        Parameters
        ----------
        polygons_on_images : imgaug.augmentables.polys.PolygonsOnImage or list of imgaug.augmentables.polys.PolygonsOnImage
            The polygons to augment.
            Either a single instance of
            :class:`~imgaug.augmentables.polys.PolygonsOnImage` or a list of
            such instances, with each one of them containing the polygons of
            a single image.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as
            ``None``. It is set automatically for child augmenters.

        hooks : None or imgaug.imgaug.HooksKeypoints, optional
            :class:`~imgaug.imgaug.HooksKeypoints` object to dynamically
            interfere with the augmentation process.

        Returns
        -------
        imgaug.augmentables.polys.PolygonsOnImage or list of imgaug.augmentables.polys.PolygonsOnImage
            Augmented polygons.

        )r   r   )r   r   r   )rl   polygons_on_imagesr   r   r   r   r   augment_polygons  s   <zAugmenter.augment_polygonsc                 C   r   )a`  Augment a batch of line strings.

        This is the corresponding function to
        :func:`Augmenter.augment_images``, just for line strings.
        Usually you will want to call :func:`Augmenter.augment_images` with
        a list of images, e.g. ``augment_images([A, B, C])`` and then
        ``augment_line_strings()`` with the corresponding list of line
        strings on these images, e.g.
        ``augment_line_strings([A_line, B_line, C_line])``, where ``A_line``
        are the line strings on image ``A``.

        Make sure to first convert the augmenter(s) to deterministic states
        before augmenting images and their corresponding line strings,
        e.g. by

        >>> import imgaug.augmenters as iaa
        >>> from imgaug.augmentables.lines import LineString
        >>> from imgaug.augmentables.lines import LineStringsOnImage
        >>> A = B = C = np.ones((10, 10), dtype=np.uint8)
        >>> A_line = B_line = C_line = LineStringsOnImage(
        >>>     [LineString([(0, 0), (1, 0), (1, 1), (0, 1)])],
        >>>     shape=(10, 10))
        >>> seq = iaa.Fliplr(0.5)
        >>> seq_det = seq.to_deterministic()
        >>> imgs_aug = seq_det.augment_images([A, B, C])
        >>> lines_aug = seq_det.augment_line_strings([A_line, B_line, C_line])

        Otherwise, different random values will be sampled for the image
        and line string augmentations, resulting in different augmentations
        (e.g. images might be rotated by ``30deg`` and line strings by
        ``-10deg``). Also make sure to call ``to_deterministic()`` again for
        each new batch, otherwise you would augment all batches in the same
        way.

        Note that there is also :func:`Augmenter.augment`, which automatically
        handles the random state alignment.

        Parameters
        ----------
        line_strings_on_images : imgaug.augmentables.lines.LineStringsOnImage or list of imgaug.augmentables.lines.LineStringsOnImage
            The line strings to augment.
            Either a single instance of
            :class:`~imgaug.augmentables.lines.LineStringsOnImage` or a list of
            such instances, with each one of them containing the line strings
            of a single image.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            Parent augmenters that have previously been called before the
            call to this function. Usually you can leave this parameter as None.
            It is set automatically for child augmenters.

        hooks : None or imgaug.imgaug.HooksKeypoints, optional
            :class:`~imgaug.imgaug.HooksKeypoints` object to dynamically
            interfere with the augmentation process.

        Returns
        -------
        imgaug.augmentables.lines.LineStringsOnImage or list of imgaug.augmentables.lines.LineStringsOnImage
            Augmented line strings.

        )line_stringsr   )r   r   Zline_strings_aug)rl   line_strings_on_imagesr   r   r   r   r   augment_line_strings  s   ?zAugmenter.augment_line_stringsc                 C   r   )a  Augment a batch of bounding boxes on images in-place.

        This is the internal version of
        :func:`Augmenter.augment_bounding_boxes`.
        It is called from :func:`Augmenter.augment_bounding_boxes` and should
        usually not be called directly.
        This method may transform the bounding boxes in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        .. note::

            This method exists mostly for legacy-support.
            Overwriting :func:`~imgaug.augmenters.meta.Augmenter._augment_batch`
            is now the preferred way of implementing custom augmentation
            routines.

        Added in 0.4.0.

        Parameters
        ----------
        bounding_boxes_on_images : list of imgaug.augmentables.bbs.BoundingBoxesOnImage
            Polygons to augment. They may be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_bounding_boxes`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_bounding_boxes`.

        Returns
        -------
        list of imgaug.augmentables.bbs.BoundingBoxesOnImage
            The augmented bounding boxes.

        r   rl   r   ri   r   r   r   r   r   _augment_bounding_boxes)  s   +z!Augmenter._augment_bounding_boxesc                 C   r   )a  Augment a batch of polygons on images in-place.

        This is the internal version of :func:`Augmenter.augment_polygons`.
        It is called from :func:`Augmenter.augment_polygons` and should
        usually not be called directly.
        This method may transform the polygons in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        .. note::

            This method exists mostly for legacy-support.
            Overwriting :func:`~imgaug.augmenters.meta.Augmenter._augment_batch`
            is now the preferred way of implementing custom augmentation
            routines.

        Parameters
        ----------
        polygons_on_images : list of imgaug.augmentables.polys.PolygonsOnImage
            Polygons to augment. They may be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        Returns
        -------
        list of imgaug.augmentables.polys.PolygonsOnImage
            The augmented polygons.

        r   )rl   r   ri   r   r   r   r   r   _augment_polygonsV  s   (zAugmenter._augment_polygonsc                 C   r   )a  Augment a batch of line strings in-place.

        This is the internal version of
        :func:`Augmenter.augment_line_strings`.
        It is called from :func:`Augmenter.augment_line_strings` and should
        usually not be called directly.
        This method may transform the line strings in-place.
        This method does not have to care about determinism or the
        Augmenter instance's ``random_state`` variable. The parameter
        ``random_state`` takes care of both of these.

        .. note::

            This method exists mostly for legacy-support.
            Overwriting :func:`~imgaug.augmenters.meta.Augmenter._augment_batch`
            is now the preferred way of implementing custom augmentation
            routines.

        Parameters
        ----------
        line_strings_on_images : list of imgaug.augmentables.lines.LineStringsOnImage
            Line strings to augment. They may be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_line_strings`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_line_strings`.

        Returns
        -------
        list of imgaug.augmentables.lines.LineStringsOnImage
            The augmented line strings.

        r   rl   r   ri   r   r   r   r   r   _augment_line_strings  s   )zAugmenter._augment_line_stringsc                 C      | j ||||dS )a  
        Augment BBs by applying keypoint augmentation to their corners.

        Added in 0.4.0.

        Parameters
        ----------
        bounding_boxes_on_images : list of imgaug.augmentables.bbs.BoundingBoxesOnImages or imgaug.augmentables.bbs.BoundingBoxesOnImages
            Bounding boxes to augment. They may be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        Returns
        -------
        list of imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage
            The augmented bounding boxes.

        r   _augment_cbaois_as_keypointsr   r   r   r   $_augment_bounding_boxes_as_keypoints  s
   z.Augmenter._augment_bounding_boxes_as_keypointsc                 C   s$   t j| j|||d}| ||||S )a  
        Augment polygons by applying keypoint augmentation to their vertices.

        .. warning::

            This method calls
            :func:`~imgaug.augmenters.meta.Augmenter._augment_keypoints` and
            expects it to do keypoint augmentation. The default for that
            method is to do nothing. It must therefore be overwritten,
            otherwise the polygon augmentation will also do nothing.

        Parameters
        ----------
        polygons_on_images : list of imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.polys.PolygonsOnImage
            Polygons to augment. They may be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        recoverer : None or imgaug.augmentables.polys._ConcavePolygonRecoverer
            An instance used to repair invalid polygons after augmentation.
            Must offer the method
            ``recover_from(new_exterior, old_polygon, random_state=0)``.
            If ``None`` then invalid polygons are not repaired.

        Returns
        -------
        list of imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.polys.PolygonsOnImage
            The augmented polygons.

        r   )	functoolspartialr   _apply_to_polygons_as_keypoints)rl   r   ri   r   r   	recovererfuncr   r   r   _augment_polygons_as_keypoints  s   (z(Augmenter._augment_polygons_as_keypointsc                 C   r   )a  
        Augment BBs by applying keypoint augmentation to their corners.

        Parameters
        ----------
        line_strings_on_images : list of imgaug.augmentables.lines.LineStringsOnImages or imgaug.augmentables.lines.LineStringsOnImages
            Line strings to augment. They may be changed in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_polygons`.

        Returns
        -------
        list of imgaug.augmentables.lines.LineStringsOnImages or imgaug.augmentables.lines.LineStringsOnImages
            The augmented line strings.

        r   r   r   r   r   r   "_augment_line_strings_as_keypoints  s
   z,Augmenter._augment_line_strings_as_keypointsc                 C   s    t j| j|||d}| ||S )aV  
        Augment bounding boxes by applying KP augmentation to their corners.

        Added in 0.4.0.

        Parameters
        ----------
        cbaois : list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.polys.PolygonsOnImage or list of imgaug.augmentables.lines.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.lines.LineStringsOnImage
            Coordinate-based augmentables to augment. They may be changed
            in-place.

        random_state : imgaug.random.RNG
            The random state to use for all sampling tasks during the
            augmentation.

        parents : list of imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_batch`.

        hooks : imgaug.imgaug.HooksKeypoints or None
            See :func:`~imgaug.augmenters.meta.Augmenter.augment_batch`.

        Returns
        -------
        list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.polys.PolygonsOnImage or list of imgaug.augmentables.lines.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.lines.LineStringsOnImage
            The augmented coordinate-based augmentables.

        r   )r   r   r   _apply_to_cbaois_as_keypoints)rl   cbaoisri   r   r   r   r   r   r   r     s   z&Augmenter._augment_cbaois_as_keypointsc           	      C   sx   ddl m} d}|durt|trdd |D }n| }| ||}|du r)|S |dur1| nd}|||||}|S )a]  
        Apply a callback to polygons in keypoint-representation.

        Added in 0.4.0.

        Parameters
        ----------
        polygons_on_images : list of imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.polys.PolygonsOnImage
            Polygons to augment. They may be changed in-place.

        func : callable
            The function to apply. Receives a list of
            :class:`~imgaug.augmentables.kps.KeypointsOnImage` instances as its
            only parameter.

        recoverer : None or imgaug.augmentables.polys._ConcavePolygonRecoverer
            An instance used to repair invalid polygons after augmentation.
            Must offer the method
            ``recover_from(new_exterior, old_polygon, random_state=0)``.
            If ``None`` then invalid polygons are not repaired.

        random_state : None or imgaug.random.RNG
            The random state to use for the recoverer.

        Returns
        -------
        list of imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.polys.PolygonsOnImage
            The augmented polygons.

        r
   )recover_psois_Nc                 S      g | ]}|  qS r   )r   )r    Zpsoir   r   r   r"   d  rf   z=Augmenter._apply_to_polygons_as_keypoints.<locals>.<listcomp>)Zaugmentables.polysr   r0   rQ   r   r   r)   )	clsr   r   r   ri   r   Z
psois_origZpsoisZrandom_state_recovererr   r   r   r   >  s"   !
	z)Augmenter._apply_to_polygons_as_keypointsc                 C   s*   ddl m}m} ||}||}|||S )a  
        Augment bounding boxes by applying KP augmentation to their corners.

        Added in 0.4.0.

        Parameters
        ----------
        cbaois : list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.polys.PolygonsOnImage or list of imgaug.augmentables.lines.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.lines.LineStringsOnImage
            Coordinate-based augmentables to augment. They may be changed
            in-place.

        func : callable
            The function to apply. Receives a list of
            :class:`~imgaug.augmentables.kps.KeypointsOnImage` instances as its
            only parameter.

        Returns
        -------
        list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.polys.PolygonsOnImage or list of imgaug.augmentables.lines.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.polys.PolygonsOnImage or imgaug.augmentables.lines.LineStringsOnImage
            The augmented coordinate-based augmentables.

        r
   )convert_cbaois_to_kpsois invert_convert_cbaois_to_kpsois_)Zaugmentables.utilsr   r   )r   r   r   r   r   ZkpsoisZ
kpsois_augr   r   r   r   z  s   
z'Augmenter._apply_to_cbaois_as_keypointsc                    sn  t |sJ dtt|f g d}dg|  tfdd D s.J dd f  fddD }t|d	ksFJ d
d| dv r_dvsRJ dd g}t|d	  n	dd}t
| d}tt }tj}	|	d	 dkp|	d	 dko|	d dk}
|
rd}n|s|dkrtd|s|dkr|du rtdt|	dd	dd	dd	dd	dd	ddd}| j||d}|r|S g }|dkrD ]}|dkrt|d}||d	  q|t|d|f  qn,|D ])}|dkrdv rt|d}||d	  q|v r'|t|d|f  qt|dkr3|d	 S t|S )a3  Augment a batch.

        This method is a wrapper around
        :class:`~imgaug.augmentables.batches.UnnormalizedBatch` and
        :func:`~imgaug.augmenters.meta.Augmenter.augment_batch`. Hence, it
        supports the same datatypes as
        :class:`~imgaug.augmentables.batches.UnnormalizedBatch`.

        If `return_batch` was set to ``False`` (the default), the method will
        return a tuple of augmentables. It will return the same types of
        augmentables (but in augmented form) as input into the method. This
        behaviour is partly specific to the python version:

        * In **python 3.6+** (if ``return_batch=False``):

            * Any number of augmentables may be provided as input.
            * None of the provided named arguments *has to be* `image` or
              `images` (but of coarse you *may* provide them).
            * The return order matches the order of the named arguments, e.g.
              ``x_aug, y_aug, z_aug = augment(X=x, Y=y, Z=z)``.

        * In **python <3.6** (if ``return_batch=False``):

            * One or two augmentables may be used as input, not more than that.
            * One of the input arguments has to be `image` or `images`.
            * The augmented images are *always* returned first, independent
              of the input argument order, e.g.
              ``a_aug, b_aug = augment(b=b, images=a)``. This also means
              that the output of the function can only be one of the
              following three cases: a batch, list/array of images,
              tuple of images and something (like images + segmentation maps).

        If `return_batch` was set to ``True``, an instance of
        :class:`~imgaug.augmentables.batches.UnnormalizedBatch` will be
        returned. The output is the same for all python version and any
        number or combination of augmentables may be provided.

        So, to keep code downward compatible for python <3.6, use one of the
        following three options:

          * Use ``batch = augment(images=X, ..., return_batch=True)``.
          * Call ``images = augment(images=X)``.
          * Call ``images, other = augment(images=X, <something_else>=Y)``.

        All augmentables must be provided as named arguments.
        E.g. ``augment(<array>)`` will crash, but ``augment(images=<array>)``
        will work.

        Parameters
        ----------
        image : None or (H,W,C) ndarray or (H,W) ndarray, optional
            The image to augment. Only this or `images` can be set, not both.
            If `return_batch` is ``False`` and the python version is below 3.6,
            either this or `images` **must** be provided.

        images : None or (N,H,W,C) ndarray or (N,H,W) ndarray or iterable of (H,W,C) ndarray or iterable of (H,W) ndarray, optional
            The images to augment. Only this or `image` can be set, not both.
            If `return_batch` is ``False`` and the python version is below 3.6,
            either this or `image` **must** be provided.

        heatmaps : None or (N,H,W,C) ndarray or imgaug.augmentables.heatmaps.HeatmapsOnImage or iterable of (H,W,C) ndarray or iterable of imgaug.augmentables.heatmaps.HeatmapsOnImage, optional
            The heatmaps to augment.
            If anything else than
            :class:`~imgaug.augmentables.heatmaps.HeatmapsOnImage`, then the
            number of heatmaps must match the number of images provided via
            parameter `images`. The number is contained either in ``N`` or the
            first iterable's size.

        segmentation_maps : None or (N,H,W) ndarray or imgaug.augmentables.segmaps.SegmentationMapsOnImage or iterable of (H,W) ndarray or iterable of imgaug.augmentables.segmaps.SegmentationMapsOnImage, optional
            The segmentation maps to augment.
            If anything else than
            :class:`~imgaug.augmentables.segmaps.SegmentationMapsOnImage`, then
            the number of segmaps must match the number of images provided via
            parameter `images`. The number is contained either in ``N`` or the
            first iterable's size.

        keypoints : None or list of (N,K,2) ndarray or tuple of number or imgaug.augmentables.kps.Keypoint or iterable of (K,2) ndarray or iterable of tuple of number or iterable of imgaug.augmentables.kps.Keypoint or iterable of imgaug.augmentables.kps.KeypointOnImage or iterable of iterable of tuple of number or iterable of iterable of imgaug.augmentables.kps.Keypoint, optional
            The keypoints to augment.
            If a tuple (or iterable(s) of tuple), then iterpreted as ``(x,y)``
            coordinates and must hence contain two numbers.
            A single tuple represents a single coordinate on one image, an
            iterable of tuples the coordinates on one image and an iterable of
            iterable of tuples the coordinates on several images. Analogous if
            :class:`~imgaug.augmentables.kps.Keypoint` instances are used
            instead of tuples.
            If an ndarray, then ``N`` denotes the number of images and ``K``
            the number of keypoints on each image.
            If anything else than
            :class:`~imgaug.augmentables.kps.KeypointsOnImage` is provided, then
            the number of keypoint groups must match the number of images
            provided via parameter `images`. The number is contained e.g. in
            ``N`` or in case of "iterable of iterable of tuples" in the first
            iterable's size.

        bounding_boxes : None or (N,B,4) ndarray or tuple of number or imgaug.augmentables.bbs.BoundingBox or imgaug.augmentables.bbs.BoundingBoxesOnImage or iterable of (B,4) ndarray or iterable of tuple of number or iterable of imgaug.augmentables.bbs.BoundingBox or iterable of imgaug.augmentables.bbs.BoundingBoxesOnImage or iterable of iterable of tuple of number or iterable of iterable imgaug.augmentables.bbs.BoundingBox, optional
            The bounding boxes to augment.
            This is analogous to the `keypoints` parameter. However, each
            tuple -- and also the last index in case of arrays -- has size
            ``4``, denoting the bounding box coordinates ``x1``, ``y1``,
            ``x2`` and ``y2``.

        polygons : None or (N,#polys,#points,2) ndarray or imgaug.augmentables.polys.Polygon or imgaug.augmentables.polys.PolygonsOnImage or iterable of (#polys,#points,2) ndarray or iterable of tuple of number or iterable of imgaug.augmentables.kps.Keypoint or iterable of imgaug.augmentables.polys.Polygon or iterable of imgaug.augmentables.polys.PolygonsOnImage or iterable of iterable of (#points,2) ndarray or iterable of iterable of tuple of number or iterable of iterable of imgaug.augmentables.kps.Keypoint or iterable of iterable of imgaug.augmentables.polys.Polygon or iterable of iterable of iterable of tuple of number or iterable of iterable of iterable of tuple of imgaug.augmentables.kps.Keypoint, optional
            The polygons to augment.
            This is similar to the `keypoints` parameter. However, each polygon
            may be made up of several ``(x,y) ``coordinates (three or more are
            required for valid polygons).
            The following datatypes will be interpreted as a single polygon on
            a single image:

              * ``imgaug.augmentables.polys.Polygon``
              * ``iterable of tuple of number``
              * ``iterable of imgaug.augmentables.kps.Keypoint``

            The following datatypes will be interpreted as multiple polygons
            on a single image:

              * ``imgaug.augmentables.polys.PolygonsOnImage``
              * ``iterable of imgaug.augmentables.polys.Polygon``
              * ``iterable of iterable of tuple of number``
              * ``iterable of iterable of imgaug.augmentables.kps.Keypoint``
              * ``iterable of iterable of imgaug.augmentables.polys.Polygon``

            The following datatypes will be interpreted as multiple polygons on
            multiple images:

              * ``(N,#polys,#points,2) ndarray``
              * ``iterable of (#polys,#points,2) ndarray``
              * ``iterable of iterable of (#points,2) ndarray``
              * ``iterable of iterable of iterable of tuple of number``
              * ``iterable of iterable of iterable of tuple of imgaug.augmentables.kps.Keypoint``

        line_strings : None or (N,#lines,#points,2) ndarray or imgaug.augmentables.lines.LineString or imgaug.augmentables.lines.LineStringOnImage or iterable of (#polys,#points,2) ndarray or iterable of tuple of number or iterable of imgaug.augmentables.kps.Keypoint or iterable of imgaug.augmentables.lines.LineString or iterable of imgaug.augmentables.lines.LineStringOnImage or iterable of iterable of (#points,2) ndarray or iterable of iterable of tuple of number or iterable of iterable of imgaug.augmentables.kps.Keypoint or iterable of iterable of imgaug.augmentables.lines.LineString or iterable of iterable of iterable of tuple of number or iterable of iterable of iterable of tuple of imgaug.augmentables.kps.Keypoint, optional
            The line strings to augment.
            See `polygons`, which behaves similarly.

        return_batch : bool, optional
            Whether to return an instance of
            :class:`~imgaug.augmentables.batches.UnnormalizedBatch`. If the
            python version is below 3.6 and more than two augmentables were
            provided (e.g. images, keypoints and polygons), then this must be
            set to ``True``. Otherwise an error will be raised.

        hooks : None or imgaug.imgaug.HooksImages, optional
            Hooks object to dynamically interfere with the augmentation process.

        Returns
        -------
        tuple or imgaug.augmentables.batches.UnnormalizedBatch
            If `return_batch` was set to ``True``, a instance of
            ``UnnormalizedBatch`` will be returned.
            If `return_batch` was set to ``False``, a tuple of augmentables
            will be returned, e.g. ``(augmented images, augmented keypoints)``.
            The datatypes match the input datatypes of the corresponding named
            arguments. In python <3.6, augmented images are always the first
            entry in the returned tuple. In python 3.6+ the order matches the
            order of the named arguments.

        Examples
        --------
        >>> import numpy as np
        >>> import imgaug as ia
        >>> import imgaug.augmenters as iaa
        >>> aug = iaa.Affine(rotate=(-25, 25))
        >>> image = np.zeros((64, 64, 3), dtype=np.uint8)
        >>> keypoints = [(10, 20), (30, 32)]  # (x,y) coordinates
        >>> images_aug, keypoints_aug = aug.augment(
        >>>     image=image, keypoints=keypoints)

        Create a single image and a set of two keypoints on it, then
        augment both by applying a random rotation between ``-25`` deg and
        ``+25`` deg. The sampled rotation value is automatically aligned
        between image and keypoints. Note that in python <3.6, augmented
        images will always be returned first, independent of the order of
        the named input arguments. So
        ``keypoints_aug, images_aug = aug.augment(keypoints=keypoints,
        image=image)`` would **not** be correct (but in python 3.6+ it would
        be).

        >>> import numpy as np
        >>> import imgaug as ia
        >>> import imgaug.augmenters as iaa
        >>> from imgaug.augmentables.bbs import BoundingBox
        >>> aug = iaa.Affine(rotate=(-25, 25))
        >>> images = [np.zeros((64, 64, 3), dtype=np.uint8),
        >>>           np.zeros((32, 32, 3), dtype=np.uint8)]
        >>> keypoints = [[(10, 20), (30, 32)],  # KPs on first image
        >>>              [(22, 10), (12, 14)]]  # KPs on second image
        >>> bbs = [
        >>>           [BoundingBox(x1=5, y1=5, x2=50, y2=45)],
        >>>           [BoundingBox(x1=4, y1=6, x2=10, y2=15),
        >>>            BoundingBox(x1=8, y1=9, x2=16, y2=30)]
        >>>       ]  # one BB on first image, two BBs on second image
        >>> batch_aug = aug.augment(
        >>>     images=images, keypoints=keypoints, bounding_boxes=bbs,
        >>>     return_batch=True)

        Create two images of size ``64x64`` and ``32x32``, two sets of
        keypoints (each containing two keypoints) and two sets of bounding
        boxes (the first containing one bounding box, the second two bounding
        boxes). These augmentables are then augmented by applying random
        rotations between ``-25`` deg and ``+25`` deg to them. The rotation
        values are sampled by image and aligned between all augmentables on
        the same image. The method finally returns an instance of
        :class:`~imgaug.augmentables.batches.UnnormalizedBatch` from which the
        augmented data can be retrieved via ``batch_aug.images_aug``,
        ``batch_aug.keypoints_aug``, and ``batch_aug.bounding_boxes_aug``.
        In python 3.6+, `return_batch` can be kept at ``False`` and the
        augmented data can be retrieved as
        ``images_aug, keypoints_aug, bbs_aug = augment(...)``.

        zExpected boolean as argument for 'return_batch', got type %s. Call augment() only with named arguments, e.g. augment(images=<array>).)r&   r   r   r   r   r   r   r   c                    s   g | ]}| v qS r   r   r    key)kwargsr   r   r"   x  rf   z%Augmenter.augment.<locals>.<listcomp>zaExpected augment() to be called with one of the following named arguments: %s. Got none of these.r6   c                    s   g | ]}| vr|qS r   r   r   )expected_keys_callr   r   r"   ~  r=   r   z>Got the following unknown keyword argument(s) in augment(): %sr&   zUYou may only provide the argument 'image' OR 'images' to augment(), not both of them.NstandardrV   r      Zkwargs_keysr
   a  Requested more than two outputs in augment(), but detected python version is below 3.6. More than two outputs are only supported for 3.6+ as earlier python versions offer no way to retrieve the order of the provided named arguments. To still use more than two outputs, add 'return_batch=True' as an argument and retrieve the outputs manually from the returned UnnormalizedBatch instance, e.g. via 'batch.images_aug' to get augmented images.a  Requested two outputs from augment() that were not 'images', but detected python version is below 3.6. For security reasons, only single-output requests or requests with two outputs of which one is 'images' are allowed in <3.6. 'images' will then always be returned first. If you don't want this, use 'return_batch=True' mode in augment(), which returns a single UnnormalizedBatch instance instead and supports any combination of outputs.r   r   r   r   r   r   r   r   z%s_aug)r#   r~   r9   r:   anyrA   rB   r   r   getr   rQ   keyssysversion_infor   r   r   r   rJ   tuple)rl   Zreturn_batchr   r   Zexpected_keysZunknown_argsr&   orderZnb_keysZvinfoZis_py36_or_newerr   r   resultr   attrr   )r   r   r   augment  s    U



$










zAugmenter.augmentc                 O   s   | j |i |S )z<Alias for :func:`~imgaug.augmenters.meta.Augmenter.augment`.)r	  )rl   argsr   r   r   r   __call__  s   zAugmenter.__call__c                 C   s   ddl m} |j| |||dS )a  Create a pool used for multicore augmentation.

        Parameters
        ----------
        processes : None or int, optional
            Same as in :func:`~imgaug.multicore.Pool.__init__`.
            The number of background workers. If ``None``, the number of the
            machine's CPU cores will be used (this counts hyperthreads as CPU
            cores). If this is set to a negative value ``p``, then
            ``P - abs(p)`` will be used, where ``P`` is the number of CPU
            cores. E.g. ``-1`` would use all cores except one (this is useful
            to e.g. reserve one core to feed batches to the GPU).

        maxtasksperchild : None or int, optional
            Same as for :func:`~imgaug.multicore.Pool.__init__`.
            The number of tasks done per worker process before the process
            is killed and restarted. If ``None``, worker processes will not
            be automatically restarted.

        seed : None or int, optional
            Same as for :func:`~imgaug.multicore.Pool.__init__`.
            The seed to use for child processes. If ``None``, a random seed
            will be used.

        Returns
        -------
        imgaug.multicore.Pool
            Pool for multicore augmentation.

        Examples
        --------
        >>> import numpy as np
        >>> import imgaug as ia
        >>> import imgaug.augmenters as iaa
        >>> from imgaug.augmentables.batches import Batch
        >>>
        >>> aug = iaa.Add(1)
        >>> images = np.zeros((16, 128, 128, 3), dtype=np.uint8)
        >>> batches = [Batch(images=np.copy(images)) for _ in range(100)]
        >>> with aug.pool(processes=-1, seed=2) as pool:
        >>>     batches_aug = pool.map_batches(batches, chunksize=8)
        >>> print(np.sum(batches_aug[0].images_aug[0]))
        49152

        Create ``100`` batches of empty images. Each batch contains
        ``16`` images of size ``128x128``. The batches are then augmented on
        all CPU cores except one (``processes=-1``). After augmentation, the
        sum of pixel values from the first augmented image is printed.

        >>> import numpy as np
        >>> import imgaug as ia
        >>> import imgaug.augmenters as iaa
        >>> from imgaug.augmentables.batches import Batch
        >>>
        >>> aug = iaa.Add(1)
        >>> images = np.zeros((16, 128, 128, 3), dtype=np.uint8)
        >>> def generate_batches():
        >>>     for _ in range(100):
        >>>         yield Batch(images=np.copy(images))
        >>>
        >>> with aug.pool(processes=-1, seed=2) as pool:
        >>>     batches_aug = pool.imap_batches(generate_batches(), chunksize=8)
        >>>     batch_aug = next(batches_aug)
        >>>     print(np.sum(batch_aug.images_aug[0]))
        49152

        Same as above. This time, a generator is used to generate batches
        of images. Again, the first augmented image's sum of pixels is printed.

        r   N)	processesmaxtasksperchildr   )r   r   r   )rl   r  r  r   r   r   r   r   r     s   GzAugmenter.poolc              	      s:  t  rCt jdkr fddt jd D  net jdkr& g nZt jdkr; ddddtjf g nEtd jf t t	sQJ d	t
 f t D ]*\}}t|jdkraqUt|jdkrw|ddddtjf  |< qUtd
||jf | jr| n|  }g } D ]}|||g||   qt	tj| }tdd |D }	tdd |D }
|
| }|	|t   }tj||df|d d jd}t|D ]E}t D ]>\}}t|D ]5}|| || |  }|	|t  |  }||jd  }|
| }||jd  }||||||ddf< qqq|S )aU  Augment images and draw the results as a single grid-like image.

        This method applies this augmenter to the provided images and returns
        a grid image of the results. Each cell in the grid contains a single
        augmented version of an input image.

        If multiple input images are provided, the row count is multiplied by
        the number of images and each image gets its own row.
        E.g. for ``images = [A, B]``, ``rows=2``, ``cols=3``::

            A A A
            B B B
            A A A
            B B B

        for ``images = [A]``, ``rows=2``, ``cols=3``::

            A A A
            A A A

        Parameters
        -------
        images : (N,H,W,3) ndarray or (H,W,3) ndarray or (H,W) ndarray or list of (H,W,3) ndarray or list of (H,W) ndarray
            List of images to augment and draw in the grid.
            If a list, then each element is expected to have shape ``(H, W)``
            or ``(H, W, 3)``. If a single array, then it is expected to have
            shape ``(N, H, W, 3)`` or ``(H, W, 3)`` or ``(H, W)``.

        rows : int
            Number of rows in the grid.
            If ``N`` input images are given, this value will automatically be
            multiplied by ``N`` to create rows for each image.

        cols : int
            Number of columns in the grid.

        Returns
        -------
        (Hg, Wg, 3) ndarray
            The generated grid image with augmented versions of the input
            images. Here, ``Hg`` and ``Wg`` reference the output size of the
            grid, and *not* the sizes of the input images.

        rU   c                    s   g | ]} | qS r   r   )r    rN   r   r   r   r"   ]  rf   z'Augmenter.draw_grid.<locals>.<listcomp>r   rV   r
   NzNUnexpected images shape, expected 2-, 3- or 4-dimensional array, got shape %s.z?Expected 'images' to be an ndarray or list of ndarrays. Got %s.zUUnexpected image shape at index %d, expected 2- or 3-dimensional array, got shape %s.c                 S      g | ]}|j d  qS )r   rX   r   r   r   r   r"   {  r*   c                 S   r  )r   r  r   r   r   r   r"   |  r*   dtyper   )r#   r$   rB   rX   ranger   ra   rC   r0   rQ   r:   rH   rj   to_deterministicrJ   r   	itertoolschainr\   zerosr  )rl   r&   rowscolsrN   r   ZdetaugsZ	augs_flatZcell_heightZ
cell_widthwidthheightgridrow_idxZimg_idxZcol_idx	image_augZcell_y1Zcell_y2Zcell_x1Zcell_x2r   r   r   	draw_grid.  sd   
-	zAugmenter.draw_gridc                 C   s   |  |||}t| dS )a  Augment images and plot the results as a single grid-like image.

        This calls :func:`~imgaug.augmenters.meta.Augmenter.draw_grid` and
        simply shows the results. See that method for details.

        Parameters
        ----------
        images : (N,H,W,3) ndarray or (H,W,3) ndarray or (H,W) ndarray or list of (H,W,3) ndarray or list of (H,W) ndarray
            List of images to augment and draw in the grid.
            If a list, then each element is expected to have shape ``(H, W)``
            or ``(H, W, 3)``. If a single array, then it is expected to have
            shape ``(N, H, W, 3)`` or ``(H, W, 3)`` or ``(H, W)``.

        rows : int
            Number of rows in the grid.
            If ``N`` input images are given, this value will automatically be
            multiplied by ``N`` to create rows for each image.

        cols : int
            Number of columns in the grid.

        N)r  r#   Zimshow)rl   r&   r  r  r  r   r   r   	show_grid  s   zAugmenter.show_gridc                    sL   |du s|dksJ d|f |du r  dd S  fddt|D S )aD  Convert this augmenter from a stochastic to a deterministic one.

        A stochastic augmenter samples pseudo-random values for each parameter,
        image and batch.
        A deterministic augmenter also samples new values for each parameter
        and image, but not batch. Instead, for consecutive batches it will
        sample the same values (provided the number of images and their sizes
        don't change).
        From a technical perspective this means that a deterministic augmenter
        starts each batch's augmentation with a random number generator in
        the same state (i.e. same seed), instead of advancing that state from
        batch to batch.

        Using determinism is useful to (a) get the same augmentations for
        two or more image batches (e.g. for stereo cameras), (b) to augment
        images and corresponding data on them (e.g. segmentation maps or
        bounding boxes) in the same way.

        Parameters
        ----------
        n : None or int, optional
            Number of deterministic augmenters to return.
            If ``None`` then only one :class:`~imgaug.augmenters.meta.Augmenter`
            instance will be returned.
            If ``1`` or higher, a list containing ``n``
            :class:`~imgaug.augmenters.meta.Augmenter` instances will be
            returned.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter or list of imgaug.augmenters.meta.Augmenter
            A single Augmenter object if `n` was None,
            otherwise a list of Augmenter objects (even if `n` was ``1``).

        Nr   z'Expected 'n' to be None or >=1, got %s.r   c                    s   g | ]}   qS r   )_to_deterministic)r    _rq   r   r   r"     rf   z.Augmenter.to_deterministic.<locals>.<listcomp>)r  smxrange)rl   nr   rq   r   r    s   $zAugmenter.to_deterministicc                 C   s   |   }| j |_d|_|S )a  Convert this augmenter from a stochastic to a deterministic one.

        Augmenter-specific implementation of
        :func:`~imgaug.augmenters.meta.to_deterministic`. This function is
        expected to return a single new deterministic
        :class:`~imgaug.augmenters.meta.Augmenter` instance of this augmenter.

        Returns
        -------
        det : imgaug.augmenters.meta.Augmenter
            Deterministic variation of this Augmenter object.

        Tr)   ri   derive_rng_rj   rl   augr   r   r   r!    s   zAugmenter._to_deterministicz&imgaug.augmenters.meta.Augmenter.seed_c                 C      | j ||d dS )zgOld name of :func:`~imgaug.augmenters.meta.Augmenter.seed_`.

        Deprecated since 0.4.0.

        entropydeterministic_tooN)seed_)rl   ri   r-  r   r   r   reseed     zAugmenter.reseedc                 C   sv   t |tsJ d| |du rtj }nt|}| jr|r$| | _|  D ]}|D ]}|j	|
 |d q,q(dS )ai
  Seed this augmenter and all of its children.

        This method assigns a new random number generator to the
        augmenter and all of its children (if it has any). The new random
        number generator is *derived* from the provided seed or RNG -- or from
        the global random number generator if ``None`` was provided.
        Note that as child RNGs are *derived*, they do not all use the same
        seed.

        If this augmenter or any child augmenter had a random number generator
        that pointed to the global random state, it will automatically be
        replaced with a local random state. This is similar to what
        :func:`~imgaug.augmenters.meta.Augmenter.localize_random_state`
        does.

        This method is useful when augmentations are run in the
        background (i.e. on multiple cores).
        It should be called before sending this
        :class:`~imgaug.augmenters.meta.Augmenter` instance to a
        background worker or once within each worker with different seeds
        (i.e., if ``N`` workers are used, the function should be called
        ``N`` times). Otherwise, all background workers will
        use the same seeds and therefore apply the same augmentations.
        Note that :func:`Augmenter.augment_batches` and :func:`Augmenter.pool`
        already do this automatically.

        Added in 0.4.0.

        Parameters
        ----------
        entropy : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
            A seed or random number generator that is used to derive new
            random number generators for this augmenter and its children.
            If an ``int`` is provided, it will be interpreted as a seed.
            If ``None`` is provided, the global random number generator will
            be used.

        deterministic_too : bool, optional
            Whether to also change the seed of an augmenter ``A``, if ``A``
            is deterministic. This is the case both when this augmenter
            object is ``A`` or one of its children is ``A``.

        Examples
        --------
        >>> import imgaug.augmenters as iaa
        >>> aug = iaa.Sequential([
        >>>     iaa.Crop(px=(0, 10)),
        >>>     iaa.Crop(px=(0, 10))
        >>> ])
        >>> aug.seed_(1)

        Seed an augmentation sequence containing two crop operations. Even
        though the same seed was used, the two operations will still sample
        different pixel amounts to crop as the child-specific seed is merely
        derived from the provided seed.

        z:Expected 'deterministic_too' to be a boolean, got type %s.Nr+  )r0   boolr   r   r   rj   r)   ri   get_children_listsr.  r'  )rl   r,  r-  ri   rD   r)  r   r   r   r.    s"   :



zAugmenter.seed_Tc                 C   s   |   }|j|d |S )a  Assign augmenter-specific RNGs to this augmenter and its children.

        See :func:`Augmenter.localize_random_state_` for more details.

        Parameters
        ----------
        recursive : bool, optional
            See
            :func:`~imgaug.augmenters.meta.Augmenter.localize_random_state_`.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter
            Copy of the augmenter and its children, with localized RNGs.

        	recursive)r   localize_random_state_)rl   r4  r)  r   r   r   localize_random_stateH	  s
   zAugmenter.localize_random_statec                 C   sB   | j  r| j  | _ |r|  D ]}|D ]}|j|d qq| S )a  Assign augmenter-specific RNGs to this augmenter and its children.

        This method iterates over this augmenter and all of its children and
        replaces any pointer to the global RNG with a new local (i.e.
        augmenter-specific) RNG.

        A random number generator (RNG) is used for the sampling of random
        values.
        The global random number generator exists exactly once throughout
        the library and is shared by many augmenters.
        A local RNG (usually) exists within exactly one augmenter and is
        only used by that augmenter.

        Usually there is no need to change global into local RNGs.
        The only noteworthy exceptions are

            * Whenever you want to use determinism (so that the global RNG is
              not accidentally reverted).
            * Whenever you want to copy RNGs from one augmenter to
              another. (Copying the global RNG would usually not be useful.
              Copying the global RNG from augmenter A to B, then executing A
              and then B would result in B's (global) RNG's state having
              already changed because of A's sampling. So the samples of
              A and B would differ.)

        The case of determinism is handled automatically by
        :func:`~imgaug.augmenters.meta.Augmenter.to_deterministic`.
        Only when you copy RNGs (via
        :func:`~imgaug.augmenters.meta.Augmenter.copy_random_state`),
        you need to call this function first.

        Parameters
        ----------
        recursive : bool, optional
            Whether to localize the RNGs of the augmenter's children too.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter
            Returns itself (with localized RNGs).

        r3  )ri   is_global_rngr'  r2  r5  )rl   r4  rD   r3   r   r   r   r5  `	  s   
+z Augmenter.localize_random_state_positionc                 C   s    |   }|j|||||d |S )aM  Copy the RNGs from a source augmenter sequence.

        Parameters
        ----------
        source : imgaug.augmenters.meta.Augmenter
            See :func:`~imgaug.augmenters.meta.Augmenter.copy_random_state_`.

        recursive : bool, optional
            See :func:`~imgaug.augmenters.meta.Augmenter.copy_random_state_`.

        matching : {'position', 'name'}, optional
            See :func:`~imgaug.augmenters.meta.Augmenter.copy_random_state_`.

        matching_tolerant : bool, optional
            See :func:`~imgaug.augmenters.meta.Augmenter.copy_random_state_`.

        copy_determinism : bool, optional
            See :func:`~imgaug.augmenters.meta.Augmenter.copy_random_state_`.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter
            Copy of the augmenter itself (with copied RNGs).

        )r4  matchingmatching_tolerantcopy_determinism)r   copy_random_state_)rl   sourcer4  r9  r:  r;  r)  r   r   r   copy_random_state	  s   zAugmenter.copy_random_statec                 C   sj  |r|g|j dd n|g}|r| g| j dd n| g}d}|dkr{dd |D }	dd |D }
t|	t|k p?t|
t|k }|rGtd |
D ]/}||	v ro|	| j rZt||	| j |
| _|rn|	| j|
| _qI|sxtd	|f qI| S |d
krt|t|kr|stdt	||D ]\}}|j rt||j |_|r|j|_q| S td|f )a  Copy the RNGs from a source augmenter sequence (in-place).

        .. note::

            The source augmenters are not allowed to use the global RNG.
            Call
            :func:`~imgaug.augmenters.meta.Augmenter.localize_random_state_`
            once on the source to localize all random states.

        Parameters
        ----------
        source : imgaug.augmenters.meta.Augmenter
            The source augmenter(s) from where to copy the RNG(s).
            The source may have children (e.g. the source can be a
            :class:`~imgaug.augmenters.meta.Sequential`).

        recursive : bool, optional
            Whether to copy the RNGs of the source augmenter *and*
            all of its children (``True``) or just the source
            augmenter (``False``).

        matching : {'position', 'name'}, optional
            Defines the matching mode to use during recursive copy.
            This is used to associate source augmenters with target augmenters.
            If ``position`` then the target and source sequences of augmenters
            are turned into flattened lists and are associated based on
            their list indices. If ``name`` then the target and source
            augmenters are matched based on their names (i.e.
            ``augmenter.name``).

        matching_tolerant : bool, optional
            Whether to use tolerant matching between source and target
            augmenters. If set to ``False``: Name matching will raise an
            exception for any target augmenter which's name does not appear
            among the source augmenters. Position matching will raise an
            exception if source and target augmenter have an unequal number
            of children.

        copy_determinism : bool, optional
            Whether to copy the ``deterministic`` attributes from source to
            target augmenters too.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter
            The augmenter itself.

        TflatzYou called copy_random_state_() with a source that uses global RNGs. Call localize_random_state_() on the source first or initialize your augmenters with local random states, e.g. via Dropout(..., random_state=1234).r-   c                 S      i | ]}|j |qS r   r,   r    r)  r   r   r   
<dictcomp>
  rf   z0Augmenter.copy_random_state_.<locals>.<dictcomp>c                 S   rA  r   r,   rB  r   r   r   rC  	
  rf   zMatching mode 'name' with recursive=True was chosen in copy_random_state_, but either the source or target augmentation sequence contains multiple augmenters with the same name.z6Augmenter name '%s' not found among source augmenters.r8  z@Source and target augmentation sequences have different lengths.zFUnknown matching method '%s'. Valid options are 'name' and 'position'.)
get_all_childrenrB   r#   warnri   r7  rC   r)   rj   rR   )rl   r=  r4  r9  r:  r;  Zsource_augsZtarget_augsZglobal_rs_exc_msgZsource_augs_dictZtarget_augs_dictZdifferent_lengthsr-   Z
source_augZ
target_augr   r   r   r<  	  sp   A
zAugmenter.copy_random_state_c                 C   s   t  )a  Get the parameters of this augmenter.

        Returns
        -------
        list
            List of parameters of arbitrary types (usually child class
            of :class:`~imgaug.parameters.StochasticParameter`, but not
            guaranteed to be).

        )NotImplementedErrorrq   r   r   r   get_parameters7
  s   zAugmenter.get_parametersc                 C      g S )a)  Get a list of lists of children of this augmenter.

        For most augmenters, the result will be a single empty list.
        For augmenters with children it will often be a list with one
        sublist containing all children. In some cases the augmenter will
        contain multiple distinct lists of children, e.g. an if-list and an
        else-list. This will lead to a result consisting of a single list
        with multiple sublists, each representing the respective sublist of
        children.

        E.g. for an if/else-augmenter that executes the children ``A1``,
        ``A2`` if a condition is met and otherwise executes the children
        ``B1``, ``B2``, ``B3`` the result will be
        ``[[A1, A2], [B1, B2, B3]]``.

        IMPORTANT: While the topmost list may be newly created, each of the
        sublist must be editable inplace resulting in a changed children list
        of the augmenter. E.g. if an Augmenter
        ``IfElse(condition, [A1, A2], [B1, B2, B3])`` returns
        ``[[A1, A2], [B1, B2, B3]]``
        for a call to
        :func:`~imgaug.augmenters.meta.Augmenter.get_children_lists` and
        ``A2`` is removed inplace from ``[A1, A2]``, then the children lists
        of ``IfElse(...)`` must also change to ``[A1], [B1, B2, B3]``. This
        is used in
        :func:`~imgaug.augmeneters.meta.Augmenter.remove_augmenters_`.

        Returns
        -------
        list of list of imgaug.augmenters.meta.Augmenter
            One or more lists of child augmenter.
            Can also be a single empty list.

        r   rq   r   r   r   r2  E
  r   zAugmenter.get_children_listsc                 C   s\   g }|   D ]%}|D ] }|| |j|d}t|dkr*|r%|| q
|| q
q|S )a~  Get all children of this augmenter as a list.

        If the augmenter has no children, the returned list is empty.

        Parameters
        ----------
        flat : bool
            If set to ``True``, the returned list will be flat.

        Returns
        -------
        list of imgaug.augmenters.meta.Augmenter
            The children as a nested or flat list.

        r?  r   )r2  rJ   rD  rB   extend)rl   r@  r  rD   r)  childrenr   r   r   rD  n
  s   

zAugmenter.get_all_childrenc           	      C   s   |du rg }g }|| |r| |  || g }|  D ]"}|D ]}|j|||d}t|dkr<|r7|| q| | qq|S )a  Find augmenters that match a condition.

        This function will compare this augmenter and all of its children
        with a condition. The condition is a lambda function.

        Parameters
        ----------
        func : callable
            A function that receives a
            :class:`~imgaug.augmenters.meta.Augmenter` instance and a list of
            parent :class:`~imgaug.augmenters.meta.Augmenter` instances and
            must return ``True``, if that augmenter is valid match or
            ``False`` otherwise.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            List of parent augmenters.
            Intended for nested calls and can usually be left as ``None``.

        flat : bool, optional
            Whether to return the result as a flat list (``True``)
            or a nested list (``False``). In the latter case, the nesting
            matches each augmenters position among the children.

        Returns
        ----------
        list of imgaug.augmenters.meta.Augmenter
            Nested list if `flat` was set to ``False``.
            Flat list if `flat` was set to ``True``.

        Examples
        --------
        >>> import imgaug.augmenters as iaa
        >>> aug = iaa.Sequential([
        >>>     iaa.Fliplr(0.5, name="fliplr"),
        >>>     iaa.Flipud(0.5, name="flipud")
        >>> ])
        >>> print(aug.find_augmenters(lambda a, parents: a.name == "fliplr"))

        Return the first child augmenter (``Fliplr`` instance).

        N)r   r@  r   )rJ   r2  find_augmentersrB   rI  )	rl   r   r   r@  r  
subparentsrD   r)  foundr   r   r   rK  
  s$   *



zAugmenter.find_augmentersc                 C   s   | j |g||dS )a&  Find augmenter(s) by name.

        Parameters
        ----------
        name : str
            Name of the augmenter(s) to search for.

        regex : bool, optional
            Whether `name` parameter is a regular expression.

        flat : bool, optional
            See :func:`~imgaug.augmenters.meta.Augmenter.find_augmenters`.

        Returns
        -------
        augmenters : list of imgaug.augmenters.meta.Augmenter
            Nested list if `flat` was set to ``False``.
            Flat list if `flat` was set to ``True``.

        )regexr@  )find_augmenters_by_names)rl   r-   rN  r@  r   r   r   find_augmenters_by_name
  s   z!Augmenter.find_augmenters_by_namec                    s4   |r fdd}| j ||dS | j  fdd|dS )a  Find augmenter(s) by names.

        Parameters
        ----------
        names : list of str
            Names of the augmenter(s) to search for.

        regex : bool, optional
            Whether `names` is a list of regular expressions.
            If it is, an augmenter is considered a match if *at least* one
            of these expressions is a match.

        flat : boolean, optional
            See :func:`~imgaug.augmenters.meta.Augmenter.find_augmenters`.

        Returns
        -------
        augmenters : list of imgaug.augmenters.meta.Augmenter
            Nested list if `flat` was set to ``False``.
            Flat list if `flat` was set to ``True``.

        c                    s"    D ]}t || jr dS qdS )NTF)rematchr-   )r)  _parentspatternnamesr   r   comparer
  s
   z4Augmenter.find_augmenters_by_names.<locals>.comparerr?  c                    s
   | j  v S ro   r,   )r)  r   rU  r   r   <lambda>
  s   
 z4Augmenter.find_augmenters_by_names.<locals>.<lambda>)rK  )rl   rV  rN  r@  rW  r   rU  r   rO  
  s   z"Augmenter.find_augmenters_by_namesc                 C   s\   |durt d |}|| g r|std|rt S dS |s!| n|  }|j|g d |S )ai  Remove this augmenter or children that match a condition.

        Parameters
        ----------
        func : callable
            Condition to match per augmenter.
            The function must expect the augmenter itself and a list of parent
            augmenters and returns ``True`` if that augmenter is supposed to
            be removed, or ``False`` otherwise.
            E.g. ``lambda a, parents: a.name == "fliplr" and len(parents) == 1``
            removes an augmenter with name ``fliplr`` if it is the direct child
            of the augmenter upon which ``remove_augmenters()`` was initially
            called.

        copy : bool, optional
            Whether to copy this augmenter and all if its children before
            removing. If ``False``, removal is performed in-place.

        identity_if_topmost : bool, optional
            If ``True`` and the condition (lambda function) leads to the
            removal of the topmost augmenter (the one this function is called
            on initially), then that topmost augmenter will be replaced by an
            instance of :class:`~imgaug.augmenters.meta.Noop` (i.e. an
            augmenter that doesn't change its inputs). If ``False``, ``None``
            will be returned in these cases.
            This can only be ``False`` if copy is set to ``True``.

        noop_if_topmost : bool, optional
            Deprecated since 0.4.0.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter or None
            This augmenter after the removal was performed.
            ``None`` is returned if the condition was matched for the
            topmost augmenter, `copy` was set to ``True`` and `noop_if_topmost`
            was set to ``False``.

        Examples
        --------
        >>> import imgaug.augmenters as iaa
        >>> seq = iaa.Sequential([
        >>>     iaa.Fliplr(0.5, name="fliplr"),
        >>>     iaa.Flipud(0.5, name="flipud"),
        >>> ])
        >>> seq = seq.remove_augmenters(lambda a, parents: a.name == "fliplr")

        This removes the augmenter ``Fliplr`` from the ``Sequential``
        object's children.

        NzMParameter 'noop_if_topmost' is deprecated. Use 'identity_if_topmost' instead.zdInplace removal of topmost augmenter requested, which is currently not possible. Set 'copy' to True.)r   )r#   r}   rC   Identityr   remove_augmenters_)rl   r   r)   Zidentity_if_topmostZnoop_if_topmostr)  r   r   r   remove_augmenters  s   5

zAugmenter.remove_augmentersrZ  c                 C   r*  )zjOld name for :func:`~imgaug.meta.Augmenter.remove_augmenters_`.

        Deprecated since 0.4.0.

        )r   r   N)rZ  )rl   r   r   r   r   r   remove_augmenters_inplaceJ  r0  z#Augmenter.remove_augmenters_inplacec           	      C   s   |du rg n|}|| g }|   D ]4}g }t|D ]\}}|||r)|||f qt|D ]\}\}}||| = q.|D ]}||| q<qdS )a  Remove in-place children of this augmenter that match a condition.

        This is functionally identical to
        :func:`~imgaug.augmenters.meta.remove_augmenters` with
        ``copy=False``, except that it does not affect the topmost augmenter
        (the one on which this function is initially called on).

        Added in 0.4.0.

        Parameters
        ----------
        func : callable
            See :func:`~imgaug.augmenters.meta.Augmenter.remove_augmenters`.

        parents : None or list of imgaug.augmenters.meta.Augmenter, optional
            List of parent :class:`~imgaug.augmenters.meta.Augmenter` instances
            that lead to this augmenter. If ``None``, an empty list will be
            used. This parameter can usually be left empty and will be set
            automatically for children.

        Examples
        --------
        >>> import imgaug.augmenters as iaa
        >>> seq = iaa.Sequential([
        >>>     iaa.Fliplr(0.5, name="fliplr"),
        >>>    iaa.Flipud(0.5, name="flipud"),
        >>> ])
        >>> seq.remove_augmenters_(lambda a, parents: a.name == "fliplr")

        This removes the augmenter ``Fliplr`` from the ``Sequential``
        object's children.

        N)r2  rH   rJ   rZ  )	rl   r   r   rL  rD   	to_removerN   r)  Zcount_removedr   r   r   rZ  U  s   "

zAugmenter.remove_augmenters_c                 C   
   t | S )zCreate a shallow copy of this Augmenter instance.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter
            Shallow copy of this Augmenter instance.

        )copy_moduler)   rq   r   r   r   r)     s   
	zAugmenter.copyc                 C   r^  )zCreate a deep copy of this Augmenter instance.

        Returns
        -------
        imgaug.augmenters.meta.Augmenter
            Deep copy of this Augmenter instance.

        )r_  r   rq   r   r   r   r     s   
zAugmenter.deepcopyc                 C   s   |   S ro   __str__rq   r   r   r   __repr__  s   zAugmenter.__repr__c                 C   s4   |   }ddd |D }d| jj| j|| jf S )Nr6   c                 S   r   r   r`  )r    paramr   r   r   r"     rf   z%Augmenter.__str__.<locals>.<listcomp>z.%s(name=%s, parameters=[%s], deterministic=%s))rG  rA   r|   rt   r-   rj   )rl   params
params_strr   r   r   ra    s
   zAugmenter.__str__NNrx   rx   )NFro   )NN)FN)NNN)T)Tr8  TF)FNT)FT)TTN)=rt   ru   rv   rw   rn   r   r#   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   r	  r  r   r  r   r  r!  r/  r.  r6  r5  r>  r<  r   rG  r2  rD  rK  rP  rO  r[  r\  rZ  r)   r   rb  ra  __classcell__r   r   r   r   r1      s    <
+ O
x
B
"7
0
%
(A)

DB
E-*+"
0#;

  ?
T`
*
	
M
4
%
~

)

=
$
H

0r1   c                   @   sP   e Zd ZdZ			dddZdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dS )r>   a  List augmenter containing child augmenters to apply to inputs.

    This augmenter is simply a list of other augmenters. To augment an image
    or any other data, it iterates over its children and applies each one
    of them independently to the data. (This also means that the second
    applied augmenter will already receive augmented input data and augment
    it further.)

    This augmenter offers the option to apply its children in random order
    using the `random_order` parameter. This should often be activated as
    it greatly increases the space of possible augmentations.

    .. note::

        You are *not* forced to use :class:`~imgaug.augmenters.meta.Sequential`
        in order to use other augmenters. Each augmenter can be used on its
        own, e.g the following defines an augmenter for horizontal flips and
        then augments a single image:

        >>> import numpy as np
        >>> import imgaug.augmenters as iaa
        >>> image = np.zeros((32, 32, 3), dtype=np.uint8)
        >>> aug = iaa.Fliplr(0.5)
        >>> image_aug = aug.augment_image(image)

    **Supported dtypes**:

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

    Parameters
    ----------
    children : imgaug.augmenters.meta.Augmenter or list of imgaug.augmenters.meta.Augmenter or None, optional
        The augmenters to apply to images.

    random_order : bool, optional
        Whether to apply the child augmenters in random order.
        If ``True``, the order will be randomly sampled once per batch.

    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 numpy as np
    >>> import imgaug.augmenters as iaa
    >>> imgs = [np.random.rand(10, 10)]
    >>> seq = iaa.Sequential([
    >>>     iaa.Fliplr(0.5),
    >>>     iaa.Flipud(0.5)
    >>> ])
    >>> imgs_aug = seq.augment_images(imgs)

    Create a :class:`~imgaug.augmenters.meta.Sequential` that always first
    applies a horizontal flip augmenter and then a vertical flip augmenter.
    Each of these two augmenters has a ``50%`` probability of actually
    flipping the image.

    >>> seq = iaa.Sequential([
    >>>     iaa.Fliplr(0.5),
    >>>     iaa.Flipud(0.5)
    >>> ], random_order=True)
    >>> imgs_aug = seq.augment_images(imgs)

    Create a :class:`~imgaug.augmenters.meta.Sequential` that sometimes first
    applies a horizontal flip augmenter (followed by a vertical flip
    augmenter) and sometimes first a vertical flip augmenter (followed by a
    horizontal flip augmenter). Again, each of them has a ``50%`` probability
    of actually flipping the image.

    NFrx   c                 C   s   t j| ||||d |d u rt| g  n9t|t r"t| |g n,t|rEtdd |D s>J dddd |D  t| | n	tdt	|f t
|s\J dt	|f || _d S )	Nr   r-   ri   rj   c                 S   r.   r   r/   r2   r   r   r   r"     r*   z'Sequential.__init__.<locals>.<listcomp>r5   r6   c                 S   r7   r   r8   r;   r   r   r   r"      r=   8Expected None or Augmenter or list of Augmenter, got %s.,Expected random_order to be boolean, got %s.)r1   rn   rQ   r0   r#   r?   r@   rA   rC   r:   r~   random_order)rl   rJ  rm  r   r-   ri   rj   r   r   r   rn     s2   


zSequential.__init__c                 C   s|   | | ||- | jr|t| }ntt| }|D ]}| | j||| g |d}qW d    |S 1 s7w   Y  |S )Nr   )propagation_hooks_ctxrm  permutationrB   r#  r$  r   )rl   r   ri   r   r   r  indexr   r   r   r   ,  s   
zSequential._augment_batch_c                 C   8   dd | D }|   }||d d < | j |_d|_|S )Nc                 S   r   r   r  rB  r   r   r   r"   <  rf   z0Sequential._to_deterministic.<locals>.<listcomp>Tr&  rl   r  seqr   r   r   r!  ;     zSequential._to_deterministicc                 C      | j gS z=See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`.)rm  rq   r   r   r   rG  C     zSequential.get_parametersc                 C      |  | dS )zAdd an augmenter to the list of child augmenters.

        Parameters
        ----------
        imgaug.augmenters.meta.Augmenter
            The augmenter to add.

        NrJ   rl   rm   r   r   r   addG     	zSequential.addc                 C      | gS ASee :func:`~imgaug.augmenters.meta.Augmenter.get_children_lists`.r   rq   r   r   r   r2  R     zSequential.get_children_listsc                 C   s4   d dd | D }d}|| jj| j| j|| jf S )Nr6   c                 S   r   r   r`  rB  r   r   r   r"   W  rf   z&Sequential.__str__.<locals>.<listcomp>z=%s(name=%s, random_order=%s, children=[%s], deterministic=%s))rA   r|   rt   r-   rm  rj   rl   Zaugs_strrT  r   r   r   ra  V  s   zSequential.__str__)NFNNrx   rx   )rt   ru   rv   rw   rn   r   r!  rG  r|  r2  ra  r   r   r   r   r>     s    a
r>   c                   @   st   e Zd ZdZ			dddZedd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )SomeOfa  List augmenter that applies only some of its children to inputs.

    This augmenter is similar to :class:`~imgaug.augmenters.meta.Sequential`,
    but may apply only a fixed or random subset of its child augmenters to
    inputs. E.g. the augmenter could be initialized with a list of 20 child
    augmenters and then apply 5 randomly chosen child augmenters to images.

    The subset of augmenters to apply (and their order) is sampled once
    *per image*. If `random_order` is ``True``, the order will be sampled once
    *per batch* (similar to :class:`~imgaug.augmenters.meta.Sequential`).

    This augmenter currently does not support replacing (i.e. picking the same
    child multiple times) due to implementation difficulties in connection
    with deterministic augmenters.

    **Supported dtypes**:

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

    Parameters
    ----------
    n : int or tuple of int or list of int or imgaug.parameters.StochasticParameter or None, optional
        Count of augmenters to apply.

            * If ``int``, then exactly `n` of the child augmenters are applied
              to every image.
            * If tuple of two ``int`` s ``(a, b)``, then a random value will
              be uniformly sampled per image from the discrete interval
              ``[a..b]`` and denote the number of child augmenters to pick
              and apply. ``b`` may be set to ``None``, which is then equivalent
              to ``(a..C)`` with ``C`` denoting the number of children that
              the augmenter has.
            * If ``StochasticParameter``, then ``N`` numbers will be sampled
              for ``N`` images. The parameter is expected to be discrete.
            * If ``None``, then the total number of available children will be
              used (i.e. all children will be applied).

    children : imgaug.augmenters.meta.Augmenter or list of imgaug.augmenters.meta.Augmenter or None, optional
        The augmenters to apply to images.
        If this is a list of augmenters, it will be converted to a
        :class:`~imgaug.augmenters.meta.Sequential`.

    random_order : boolean, optional
        Whether to apply the child augmenters in random order.
        If ``True``, the order will be randomly sampled once per batch.

    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
    >>> imgs = [np.random.rand(10, 10)]
    >>> seq = iaa.SomeOf(1, [
    >>>     iaa.Fliplr(1.0),
    >>>     iaa.Flipud(1.0)
    >>> ])
    >>> imgs_aug = seq.augment_images(imgs)

    Apply either ``Fliplr`` or ``Flipud`` to images.

    >>> seq = iaa.SomeOf((1, 3), [
    >>>     iaa.Fliplr(1.0),
    >>>     iaa.Flipud(1.0),
    >>>     iaa.GaussianBlur(1.0)
    >>> ])
    >>> imgs_aug = seq.augment_images(imgs)

    Apply one to three of the listed augmenters (``Fliplr``, ``Flipud``,
    ``GaussianBlur``) to images. They are always applied in the
    provided order, i.e. first ``Fliplr``, second ``Flipud``, third
    ``GaussianBlur``.

    >>> seq = iaa.SomeOf((1, None), [
    >>>     iaa.Fliplr(1.0),
    >>>     iaa.Flipud(1.0),
    >>>     iaa.GaussianBlur(1.0)
    >>> ], random_order=True)
    >>> imgs_aug = seq.augment_images(imgs)

    Apply one to all of the listed augmenters (``Fliplr``, ``Flipud``,
    ``GaussianBlur``) to images. They are applied in random order, i.e.
    sometimes ``GaussianBlur`` first, followed by ``Fliplr``, sometimes
    ``Fliplr`` followed by ``Flipud`` followed by ``Blur`` etc.
    The order is sampled once per batch.

    NFrx   c                 C   s   t j| ||||d |d u rt| g  n9t|t r"t| |g n,t|rEtdd |D s>J dddd |D  t| | n	tdt	|f | 
|\| _| _t|seJ dt	|f || _d S )	Nrj  c                 S   r.   r   r/   r2   r   r   r   r"     r*   z#SomeOf.__init__.<locals>.<listcomp>r5   r6   c                 S   r7   r   r8   r;   r   r   r   r"     r=   rk  rl  )r1   rn   rQ   r0   r#   r?   r@   rA   rC   r:   _handle_arg_nr%  n_moder~   rm  )rl   r%  rJ  rm  r   r-   ri   rj   r   r   r   rn     s4   


zSomeOf.__init__c                 C   s  t |rt|}d}||fS |d u rd }d}||fS t |rxt|dks/J dt|f t |d rJ|d d u rJt|d d f}d}||fS t |d rlt |d rltt|d t|d }d}||fS td	d
d |D f t|tj	rd}||fS tdt
|f )Nrj   Noner
   z<Expected iterable 'n' to contain exactly two values, got %d.r   r   
(int,None)
stochasticz3Expected tuple of (int, None) or (int, int), got %sc                 S      g | ]}t |qS r   r:   rY   r   r   r   r"   	  rf   z(SomeOf._handle_arg_n.<locals>.<listcomp>zDExpected int, (int, None), (int, int) or StochasticParameter, got %s)r#   Zis_single_numberintr?   rB   iapDiscreteUniformrC   r0   ZStochasticParameterr:   )r   r%  r  r   r   r   r    s>   

	zSomeOf._handle_arg_nc                 C   s   | j dkr| jg| S | j dkrt| g| S | j dkr/t| jd t| }|j|f|dS | j dkr=| jj|f|dS td| j f )Nrj   r  r  r   ri   r  zInvalid n_mode: %s)r  r%  rB   r  r  draw_samplesrC   )rl   	nb_imagesri   rc  r   r   r   _get_n  s   



zSomeOf._get_nc                 C   s*   | j stt| }|S |t| }|S ro   )rm  r   arangerB   ro  )rl   ri   augmenter_orderr   r   r   _get_augmenter_order  s
   zSomeOf._get_augmenter_orderc                    sx     ||} fdd|D }tj|t ftjd}t|D ]\}}|dkr/d||d|f< q|D ]}|| q2|S )Nc                    s   g | ]	}t |t qS r   )minrB   )r    r%  rq   r   r   r"   '      z0SomeOf._get_augmenter_active.<locals>.<listcomp>r  r   r   )r  r   r  rB   r1  rH   shuffle)rl   nb_rowsri   nnaugmenter_activer  Zn_truerowr   rq   r   _get_augmenter_active$  s   zSomeOf._get_augmenter_activec           
      C   s   | | ||E | |}| |j|}|D ],}|d d |f  d }t|dkrB||}	| | j|	|| g |d}	|||	}q|W  d    S 1 sOw   Y  d S )Nr   r   )	rn  r  r  r  ZnonzerorB   subselect_rows_by_indicesr   !invert_subselect_rows_by_indices_)
rl   r   ri   r   r   r  r  Zaugmenter_indexactive	batch_subr   r   r   r   1  s(   
	
$zSomeOf._augment_batch_c                 C   rq  )Nc                 S   r   r   rr  rB  r   r   r   r"   V  rf   z,SomeOf._to_deterministic.<locals>.<listcomp>Tr&  rs  r   r   r   r!  U  ru  zSomeOf._to_deterministicc                 C   rv  rw  )r%  rq   r   r   r   rG  ]  rx  zSomeOf.get_parametersc                 C   ry  )zAdd an augmenter to the list of child augmenters.

        Parameters
        ----------
        augmenter : imgaug.augmenters.meta.Augmenter
            The augmenter to add.

        Nrz  r{  r   r   r   r|  a  r}  z
SomeOf.addc                 C   r~  r  r   rq   r   r   r   r2  l  r  zSomeOf.get_children_listsc                 C   s@   d dd | D }d}|| jj| jt| jt| j|| jf S )Nr6   c                 S   r   r   r`  rB  r   r   r   r"   q  rf   z"SomeOf.__str__.<locals>.<listcomp>zE%s(name=%s, n=%s, random_order=%s, augmenters=[%s], deterministic=%s))rA   r|   rt   r-   r9   r%  rm  rj   r  r   r   r   ra  p  s   zSomeOf.__str__)NNFNNrx   rx   )rt   ru   rv   rw   rn   rh  r  r  r  r  r   r!  rG  r|  r2  ra  r   r   r   r   r  a  s"    r
!
$r  c                       &   e Zd ZdZ		d fdd	Z  ZS )OneOfa  Augmenter that always executes exactly one of its children.

    **Supported dtypes**:

    See :class:`imgaug.augmenters.meta.SomeOf`.

    Parameters
    ----------
    children : imgaug.augmenters.meta.Augmenter or list of imgaug.augmenters.meta.Augmenter
        The choices of augmenters to apply.

    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
    >>> images = [np.ones((10, 10), dtype=np.uint8)]  # dummy example images
    >>> seq = iaa.OneOf([
    >>>     iaa.Fliplr(1.0),
    >>>     iaa.Flipud(1.0)
    >>> ])
    >>> images_aug = seq.augment_images(images)

    Flip each image either horizontally or vertically.

    >>> images = [np.ones((10, 10), dtype=np.uint8)]  # dummy example images
    >>> seq = iaa.OneOf([
    >>>     iaa.Fliplr(1.0),
    >>>     iaa.Sequential([
    >>>         iaa.GaussianBlur(1.0),
    >>>         iaa.Dropout(0.05),
    >>>         iaa.AdditiveGaussianNoise(0.1*255)
    >>>     ]),
    >>>     iaa.Noop()
    >>> ])
    >>> images_aug = seq.augment_images(images)

    Either flip each image horizontally, or add blur+dropout+noise or do
    nothing.

    Nrx   c              	      s"   t t| jd|d||||d d S )Nr   F)r%  rJ  rm  r   r-   ri   rj   )rz   r  rn   )rl   rJ  r   r-   ri   rj   r   r   r   rn     s   

zOneOf.__init__rf  rt   ru   rv   rw   rn   ri  r   r   r   r   r  {  s
    :r  c                       sP   e Zd ZdZ			d fdd	Zdd Zd	d
 Zdd Zdd Zdd Z	  Z
S )	Sometimesa  Apply child augmenter(s) with a probability of `p`.

    Let ``C`` be one or more child augmenters given to
    :class:`~imgaug.augmenters.meta.Sometimes`.
    Let ``p`` be the fraction of images (or other data) to augment.
    Let ``I`` be the input images (or other data).
    Let ``N`` be the number of input images (or other entities).
    Then (on average) ``p*N`` images of ``I`` will be augmented using ``C``.

    **Supported dtypes**:

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

    Parameters
    ----------
    p : float or imgaug.parameters.StochasticParameter, optional
        Sets the probability with which the given augmenters will be applied to
        input images/data. E.g. a value of ``0.5`` will result in ``50%`` of
        all input images (or other augmentables) being augmented.

    then_list : None or imgaug.augmenters.meta.Augmenter or list of imgaug.augmenters.meta.Augmenter, optional
        Augmenter(s) to apply to `p%` percent of all images.
        If this is a list of augmenters, it will be converted to a
        :class:`~imgaug.augmenters.meta.Sequential`.

    else_list : None or imgaug.augmenters.meta.Augmenter or list of imgaug.augmenters.meta.Augmenter, optional
        Augmenter(s) to apply to ``(1-p)`` percent of all images.
        These augmenters will be applied only when the ones in `then_list`
        are *not* applied (either-or-relationship).
        If this is a list of augmenters, it will be converted to a
        :class:`~imgaug.augmenters.meta.Sequential`.

    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.Sometimes(0.5, iaa.GaussianBlur(0.3))

    Apply ``GaussianBlur`` to ``50%`` of all input images.

    >>> aug = iaa.Sometimes(0.5, iaa.GaussianBlur(0.3), iaa.Fliplr(1.0))

    Apply ``GaussianBlur`` to ``50%`` of all input images. Apply ``Fliplr``
    to the other ``50%`` of all input images.

          ?Nrx   c                    sR   t t| j||||d t|d| _t|| jdd d| _t|| jdd d| _	d S )Nrj  pthen)rE   else)
rz   r  rn   r  handle_probability_paramr  rF   r-   	then_list	else_list)rl   r  r  r  r   r-   ri   rj   r   r   r   rn     s   


zSometimes.__init__c                 C   s   | | ||Z | jj|jf|d}t|dkd }t|dkd }||g}| j| jg}	t||	D ]$\}
}|d urWt	|dkrW|
|
}|j||| g |d}||
|}q3|W  d    S 1 sdw   Y  d S )Nr  r   r   r   )rn  r  r  r  r   wherer  r  rR   rB   r  r   r  )rl   r   ri   r   r   ZsamplesZindices_then_listZindices_else_listZindice_listsZaugmenter_listsindicesZ
augmentersr  r   r   r   r     s,   
$zSometimes._augment_batch_c                 C   sV   |   }|jd ur|j n|j|_|jd ur|j n|j|_d|_| j |_|S rg  )r)   r  r  r  rj   ri   r'  r(  r   r   r   r!  ;  s   



zSometimes._to_deterministicc                 C   rv  rw  )r  rq   r   r   r   rG  G  rx  zSometimes.get_parametersc                 C   s4   g }| j dur|| j  | jdur|| j |S )r  N)r  rJ   r  )rl   r  r   r   r   r2  K  s   

zSometimes.get_children_listsc                 C   s&   d}|| j j| j| j| j| j| jf S )Nz?%s(p=%s, name=%s, then_list=%s, else_list=%s, deterministic=%s))r|   rt   r  r-   r  r  rj   rl   rT  r   r   r   ra  T  s   zSometimes.__str__)r  NNNNrx   rx   )rt   ru   rv   rw   rn   r   r!  rG  r2  ra  ri  r   r   r   r   r    s    K 	r  c                       s   e Zd ZdZ			d fdd	Zdd Zedd	 Zed
d Zedd Z	edd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Z  ZS )WithChannelsa	  Apply child augmenters to specific channels.

    Let ``C`` be one or more child augmenters given to this augmenter.
    Let ``H`` be a list of channels.
    Let ``I`` be the input images.
    Then this augmenter will pick the channels ``H`` from each image
    in ``I`` (resulting in new images) and apply ``C`` to them.
    The result of the augmentation will be merged back into the original
    images.

    **Supported dtypes**:

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

    Parameters
    ----------
    channels : None or int or list of int, optional
        Sets the channels to be extracted from each image.
        If ``None``, all channels will be used. Note that this is not
        stochastic - the extracted channels are always the same ones.

    children : imgaug.augmenters.meta.Augmenter or list of imgaug.augmenters.meta.Augmenter or None, optional
        One or more augmenters to apply to images, after the channels
        are extracted.

    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.WithChannels([0], iaa.Add(10))

    Assuming input images are RGB, then this augmenter will add ``10`` only to
    the first channel, i.e. it will make images appear more red.

    Nrx   c                    s   t t| j||||d |d u rd | _n3t|r|g| _n)t|r>tdd |D }|s:J ddd |D f || _n	tdt	|f t
|| jd| _d S )Nrj  c                 S   r'   r   r#   is_single_integerr    Zchannelr   r   r   r"     s    
z)WithChannels.__init__.<locals>.<listcomp>z&Expected integers as channels, got %s.c                 S   r  r   r  r  r   r   r   r"     rf   z7Expected None, int or list of ints as channels, got %s.r  )rz   r  rn   r]   r#   r  r?   r@   rC   r:   rF   r-   rJ  )rl   r]   rJ  r   r-   ri   rj   Z	only_intsr   r   r   rn     s,   



zWithChannels.__init__c           	      C   s>  | j d urt| j dkr|S || || | }|jd ur&| |j|_| jj||| g |d}|jd urX| |j|j | 	|j|j | 
|j|j | |j|j|_|jD ]}|jdkrvt||j}| |j|}t||j| q[|jd ur| |j|j|_W d    |S W d    |S 1 sw   Y  |S )Nr   r   r&   )r]   rB   rn  r   r&   _reduce_images_to_channelsrJ  r   _assert_lengths_not_changed_assert_shapes_not_changed_assert_dtypes_not_changed_recover_images_arrayr   r-   r   r   _replace_unaugmented_cellsr   r   !_invert_reduce_images_to_channels)	rl   r   ri   r   r   Zbatch_cpr   Z	value_oldr   r   r   r   r     sF   
	




&
&&zWithChannels._augment_batch_c                 C   s,   t |t |ksJ dt |t |f d S )NzhExpected that number of images does not change during augmentation, but got %d vs. originally %d images.)rB   r   r   r&   r   r   r   r    s   z(WithChannels._assert_lengths_not_changedc                 C   s~   t |rt |r|jdd |jdd k}ntdd t||D }|s=J dtdd |D tdd |D f d S )Nr   rV   c                 S   s,   g | ]\}}|j d d |j d d kqS r   r
   r  r    r  r   r   r   r   r"     s     z;WithChannels._assert_shapes_not_changed.<locals>.<listcomp>z\Heights/widths of images changed in WithChannels from %s to %s, but expected to be the same.c                 S      g | ]	}|j d d qS r  r  r   r   r   r   r"     r  c                 S   r  r  r  r    r  r   r   r   r"     r  )r#   r$   rX   r@   rR   r9   )r   r   r&   Zshapes_samer   r   r   r    s   z'WithChannels._assert_shapes_not_changedc                 C   sr   t |rt |r|jj|jjk}ntdd t||D }|s7J dtdd |D tdd |D f d S )Nc                 S   s    g | ]\}}|j j|j jkqS r   r  r-   r  r   r   r   r"     s    z;WithChannels._assert_dtypes_not_changed.<locals>.<listcomp>zTdtypes of images changed in WithChannels from %s to %s, but expected to be the same.c                 S      g | ]}|j jqS r   r  r   r   r   r   r"     rf   c                 S   r  r   r  r  r   r   r   r"     rf   )r#   r$   r  r-   r@   rR   r9   )r   r   r&   Zdtypes_samer   r   r   r    s   z'WithChannels._assert_dtypes_not_changedc                 C   s   t |r
t|S |S ro   )r#   r$   r   r_   r  r   r   r   r    s   

z"WithChannels._recover_images_arrayc                    s8    j d u r|S t|r|d j f S  fdd|D S )N.c                    s   g | ]	}|d  j f qS ).r]   r   rq   r   r   r"     r  z;WithChannels._reduce_images_to_channels.<locals>.<listcomp>)r]   r#   r$   )rl   r&   r   rq   r   r    s
   

z'WithChannels._reduce_images_to_channelsc                 C   s4   | j d u r|S t||D ]\}}||d| j f< q|S )N.)r]   rR   )rl   r   r&   r   r  r   r   r   r     s
   
z.WithChannels._invert_reduce_images_to_channelsc                    sR   | j d u r|S t| j  dd |D } fdd|D }dd t|||D }|S )Nc                 S   s(   g | ]}t |jd kr|jd  ndqS )r
   r   rW   )r    Zaugmr   r   r   r"   .  s     z;WithChannels._replace_unaugmented_cells.<locals>.<listcomp>c                    s   g | ]} | qS r   r   )r    nb_channelsZnb_channels_to_augr   r   r"   4  s    c                 S   s"   g | ]\}}}|d kr|n|qS )r  r   )r    Zaugmentable_augZaugmentableZfraction_augmentedr   r   r   r"   6  s    )r]   rB   rR   )rl   Zaugmentables_augaugmentablesZnb_channels_lstZfraction_augmented_lstr  r   r  r   r  )  s   



z'WithChannels._replace_unaugmented_cellsc                 C   s*   |   }|j |_d|_| j |_|S rg  )r)   rJ  r  rj   ri   r'  r(  r   r   r   r!  <  s
   zWithChannels._to_deterministicc                 C   rv  rw  r  rq   r   r   r   rG  C  rx  zWithChannels.get_parametersc                 C   rv  r  )rJ  rq   r   r   r   r2  G  rx  zWithChannels.get_children_listsc                 C   s"   d}|| j j| j| j| j| jf S )Nz7%s(channels=%s, name=%s, children=%s, deterministic=%s))r|   rt   r]   r-   rJ  rj   r  r   r   r   ra  K  s
   zWithChannels.__str__)NNNNrx   rx   )rt   ru   rv   rw   rn   r   rh  r  r  r  r  r  r  r  r!  rG  r2  ra  ri  r   r   r   r   r  ^  s,    @-



	r  c                       6   e Zd ZdZ		d
 fdd	Zdd Zdd	 Z  ZS )rY  a  Augmenter that does not change the input data.

    This augmenter is useful e.g. during validation/testing as it allows
    to re-use the training code without actually performing any augmentation.

    Added in 0.4.0.

    **Supported dtypes**:

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

    Parameters
    ----------
    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.Identity()

    Create an augmenter that does not change inputs.

    Nrx   c                       t t| j||||d d S Nrj  )rz   rY  rn   r   r   r   r   rn        

zIdentity.__init__c                 C   r   ro   r   )rl   r   ri   r   r   r   r   r   r     s   zIdentity._augment_batch_c                 C   rH  rw  r   rq   r   r   r   rG       zIdentity.get_parametersrf  rt   ru   rv   rw   rn   r   rG  ri  r   r   r   r   rY  T  s    5rY  c                       r  )Noopa  Alias for augmenter :class:`Identity`.

    It is recommended to now use :class:`Identity`. :class:`Noop` might be
    deprecated in the future.

    **Supported dtypes**:

    See :class:`~imgaug.augmenters.meta.Identity`.

    Parameters
    ----------
    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.Noop()

    Create an augmenter that does not change inputs.

    Nrx   c                    r  r  )rz   r  rn   r   r   r   r   rn     r  zNoop.__init__rf  r  r   r   r   r   r    s
    &r  c                       sn   e Zd ZdZ						d fdd	Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dd Zdd Z  ZS )Lambdaa  Augmenter that calls a lambda function for each input batch.

    This is useful to add missing functions to a list of augmenters.

    **Supported dtypes**:

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

    Parameters
    ----------
    func_images : None or callable, optional
        The function to call for each batch of images.
        It must follow the form::

            function(images, random_state, parents, hooks)

        and return the changed images (may be transformed in-place).
        This is essentially the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_images`.
        If this is ``None`` instead of a function, the images will not be
        altered.

    func_heatmaps : None or callable, optional
        The function to call for each batch of heatmaps.
        It must follow the form::

            function(heatmaps, random_state, parents, hooks)

        and return the changed heatmaps (may be transformed in-place).
        This is essentially the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_heatmaps`.
        If this is ``None`` instead of a function, the heatmaps will not be
        altered.

    func_segmentation_maps : None or callable, optional
        The function to call for each batch of segmentation maps.
        It must follow the form::

            function(segmaps, random_state, parents, hooks)

        and return the changed segmaps (may be transformed in-place).
        This is essentially the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_segmentation_maps`.
        If this is ``None`` instead of a function, the segmentatio maps will
        not be altered.

    func_keypoints : None or callable, optional
        The function to call for each batch of keypoints.
        It must follow the form::

            function(keypoints_on_images, random_state, parents, hooks)

        and return the changed keypoints (may be transformed in-place).
        This is essentially the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_keypoints`.
        If this is ``None`` instead of a function, the keypoints will not be
        altered.

    func_bounding_boxes : "keypoints" or None or callable, optional
        The function to call for each batch of bounding boxes.
        It must follow the form::

            function(bounding_boxes_on_images, random_state, parents, hooks)

        and return the changed bounding boxes (may be transformed in-place).
        This is essentially the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_bounding_boxes`.
        If this is ``None`` instead of a function, the bounding boxes will not
        be altered.
        If this is the string ``"keypoints"`` instead of a function, the
        bounding boxes will automatically be augmented by transforming their
        corner vertices to keypoints and calling `func_keypoints`.

        Added in 0.4.0.

    func_polygons : "keypoints" or None or callable, optional
        The function to call for each batch of polygons.
        It must follow the form::

            function(polygons_on_images, random_state, parents, hooks)

        and return the changed polygons (may be transformed in-place).
        This is essentially the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_polygons`.
        If this is ``None`` instead of a function, the polygons will not
        be altered.
        If this is the string ``"keypoints"`` instead of a function, the
        polygons will automatically be augmented by transforming their
        corner vertices to keypoints and calling `func_keypoints`.

    func_line_strings : "keypoints" or None or callable, optional
        The function to call for each batch of line strings.
        It must follow the form::

            function(line_strings_on_images, random_state, parents, hooks)

        and return the changed line strings (may be transformed in-place).
        This is essentially the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_line_strings`.
        If this is ``None`` instead of a function, the line strings will not
        be altered.
        If this is the string ``"keypoints"`` instead of a function, the
        line strings will automatically be augmented by transforming their
        corner vertices to keypoints and calling `func_keypoints`.

        Added in 0.4.0.

    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
    >>>
    >>> def func_images(images, random_state, parents, hooks):
    >>>     images[:, ::2, :, :] = 0
    >>>     return images
    >>>
    >>> aug = iaa.Lambda(
    >>>     func_images=func_images
    >>> )

    Replace every second row in input images with black pixels. Leave
    other data (e.g. heatmaps, keypoints) unchanged.

    >>> def func_images(images, random_state, parents, hooks):
    >>>     images[:, ::2, :, :] = 0
    >>>     return images
    >>>
    >>> def func_heatmaps(heatmaps, random_state, parents, hooks):
    >>>     for heatmaps_i in heatmaps:
    >>>         heatmaps.arr_0to1[::2, :, :] = 0
    >>>     return heatmaps
    >>>
    >>> def func_keypoints(keypoints_on_images, random_state, parents, hooks):
    >>>     return keypoints_on_images
    >>>
    >>> aug = iaa.Lambda(
    >>>     func_images=func_images,
    >>>     func_heatmaps=func_heatmaps,
    >>>     func_keypoints=func_keypoints
    >>> )

    Replace every second row in images with black pixels, set every second
    row in heatmaps to zero and leave other data (e.g. keypoints)
    unchanged.

    Nr   rx   c                    sF   t t| j||	|
|d || _|| _|| _|| _|| _|| _|| _	d S r  )
rz   r  rn   func_imagesfunc_heatmapsfunc_segmentation_mapsfunc_keypointsfunc_bounding_boxesfunc_polygonsfunc_line_strings)rl   r  r  r  r  r  r  r  r   r-   ri   rj   r   r   r   rn   x  s   

zLambda.__init__c                 C   s   | j d ur|  ||||S |S ro   )r  r   r   r   r   r     s   
zLambda._augment_imagesc                 C   l   | j d ur4|  ||||}t|sJ dt|f tdd |D }|s2J ddd |D f |S |S )NzcExpected callback function for heatmaps to return list of imgaug.HeatmapsOnImage instances, got %s.c                 S      g | ]}t |tjqS r   )r0   r#   r   rY   r   r   r   r"         z,Lambda._augment_heatmaps.<locals>.<listcomp>c                 S   r  r   r  rY   r   r   r   r"     rf   )r  r#   r?   r:   r@   )rl   r   ri   r   r   r  Zonly_heatmapsr   r   r   r     s&   
zLambda._augment_heatmapsc                 C   r  )NzvExpected callback function for segmentation maps to return list of imgaug.SegmentationMapsOnImage() instances, got %s.c                 S   r  r   )r0   r#   r   rY   r   r   r   r"     r  z5Lambda._augment_segmentation_maps.<locals>.<listcomp>c                 S   r  r   r  rY   r   r   r   r"     rf   )r  r#   r?   r:   r@   )rl   r   ri   r   r   r  Zonly_segmapsr   r   r   r     s&   
z!Lambda._augment_segmentation_mapsc                 C   r  )NzvExpected callback function for keypoints to return list of imgaug.augmentables.kps.KeypointsOnImage instances, got %s.c                 S   r  r   )r0   r#   r   rY   r   r   r   r"     r  z-Lambda._augment_keypoints.<locals>.<listcomp>c                 S   r  r   r  rY   r   r   r   r"     rf   )r  r#   r?   r:   r@   )rl   r   ri   r   r   r  Zonly_keypointsr   r   r   r     s&   
zLambda._augment_keypointsc                 C   s   ddl m} | jdkr| j||||| dS | jd urJ| ||||}t|s1J dt|f tdd |D }|sHJ ddd |D f |S |S )	Nr   )_ConcavePolygonRecovererr   )r   vExpected callback function for polygons to return list of imgaug.augmentables.polys.PolygonsOnImage instances, got %s.c                 S   r  r   )r0   r#   r   rY   r   r   r   r"     r  z,Lambda._augment_polygons.<locals>.<listcomp>c                 S   r  r   r  rY   r   r   r   r"     rf   )Zimgaug.augmentables.polysr  r  r   r#   r?   r:   r@   )rl   r   ri   r   r   r  r  Zonly_polygonsr   r   r   r     s2   

zLambda._augment_polygonsc                 C   s   | j dkr| ||||S | j d urA|  ||||}t|s(J dt|f tdd |D }|s?J ddd |D f |S |S )Nr   z}Expected callback function for line strings to return list of imgaug.augmentables.lines.LineStringsOnImage instances, got %s.c                 S   r  r   )r0   r#   ZLineStringsOnImagerY   r   r   r   r"     r  z0Lambda._augment_line_strings.<locals>.<listcomp>z~Expected callback function for line strings to return list of imgaug.augmentables.lines.LineStringsOnImages instances, got %s.c                 S   r  r   r  rY   r   r   r   r"     rf   )r  r   r#   r?   r:   r@   )rl   r   ri   r   r   r  Zonly_lsr   r   r   r     s.   

zLambda._augment_line_stringsc           	      C   s   | j dkr| ||||S | j d urj|  ||||}t|s(J dt|f tdd |D }|s?J ddd |D f |D ]&}|jD ] }|j|jkrW|j|j|_|_|j	|j
krf|j
|j	|_	|_
qFqA|S |S )Nr   zExpected callback function for bounding boxes to return list of imgaug.augmentables.bbs.BoundingBoxesOnImage instances, got %s.c                 S   r  r   )r0   r#   r   rY   r   r   r   r"     r  z2Lambda._augment_bounding_boxes.<locals>.<listcomp>r  c                 S   r  r   r  rY   r   r   r   r"     rf   )r  r   r#   r?   r:   r@   r   x1Zx2y1y2)	rl   r   ri   r   r   r  Zonly_bbsZbboiZbbr   r   r   r     s>   


zLambda._augment_bounding_boxesc                 C   rH  rw  r   rq   r   r   r   rG    r  zLambda.get_parameters)NNNNr   r   r   NNrx   rx   )rt   ru   rv   rw   rn   r   r   r   r   r   r   r   rG  ri  r   r   r   r   r    s$     0r  c                       s.   e Zd ZdZ						d fdd	Z  ZS )AssertLambdaa  Assert conditions based on lambda-function to be the case for input data.

    This augmenter applies a lambda function to each image or other input.
    The lambda function must return ``True`` or ``False``. If ``False`` is
    returned, an assertion error is produced.

    This is useful to ensure that generic assumption about the input data
    are actually the case and error out early otherwise.

    **Supported dtypes**:

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

    Parameters
    ----------
    func_images : None or callable, optional
        The function to call for each batch of images.
        It must follow the form::

            function(images, random_state, parents, hooks)

        and return either ``True`` (valid input) or ``False`` (invalid input).
        It essentially re-uses the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_images`.

    func_heatmaps : None or callable, optional
        The function to call for each batch of heatmaps.
        It must follow the form::

            function(heatmaps, random_state, parents, hooks)

        and return either ``True`` (valid input) or ``False`` (invalid input).
        It essentially re-uses the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_heatmaps`.

    func_segmentation_maps : None or callable, optional
        The function to call for each batch of segmentation maps.
        It must follow the form::

            function(segmaps, random_state, parents, hooks)

        and return either ``True`` (valid input) or ``False`` (invalid input).
        It essentially re-uses the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_segmentation_maps`.

    func_keypoints : None or callable, optional
        The function to call for each batch of keypoints.
        It must follow the form::

            function(keypoints_on_images, random_state, parents, hooks)

        and return either ``True`` (valid input) or ``False`` (invalid input).
        It essentially re-uses the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_keypoints`.

    func_bounding_boxes : None or callable, optional
        The function to call for each batch of bounding boxes.
        It must follow the form::

            function(bounding_boxes_on_images, random_state, parents, hooks)

        and return either ``True`` (valid input) or ``False`` (invalid input).
        It essentially re-uses the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_bounding_boxes`.

        Added in 0.4.0.

    func_polygons : None or callable, optional
        The function to call for each batch of polygons.
        It must follow the form::

            function(polygons_on_images, random_state, parents, hooks)

        and return either ``True`` (valid input) or ``False`` (invalid input).
        It essentially re-uses the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_polygons`.

    func_line_strings : None or callable, optional
        The function to call for each batch of line strings.
        It must follow the form::

            function(line_strings_on_images, random_state, parents, hooks)

        and return either ``True`` (valid input) or ``False`` (invalid input).
        It essentially re-uses the interface of
        :func:`~imgaug.augmenters.meta.Augmenter._augment_line_strings`.

        Added in 0.4.0.

    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.

    Nrx   c                    s\   dd }t t| j||d||d||d||d||d||d||d	||	|
|d
 d S )Nc                 S   s   | d ur
t | |dS d S )N)augmentable_name)_AssertLambdaCallback)varr  r   r   r   _default  s
   
z'AssertLambda.__init__.<locals>._defaultr&   r   r   r   r   r   r   r  r  r  r  r  r  r  r   r-   ri   rj   )rz   r  rn   )rl   r  r  r  r  r  r  r  r   r-   ri   rj   r  r   r   r   rn     s   

zAssertLambda.__init__)NNNNNNNNNrx   rx   r  r   r   r   r   r    s    xr  c                   @      e Zd Zdd Zdd ZdS )r  c                 C   s   || _ || _d S ro   r   r  )rl   r   r  r   r   r   rn     s   
z_AssertLambdaCallback.__init__c                 C   s$   |  ||||sJ d| jf |S )Nz@Input %s did not fulfill user-defined assertion in AssertLambda.r  )rl   r  ri   r   r   r   r   r   r    s   z_AssertLambdaCallback.__call__Nrt   ru   rv   rn   r  r   r   r   r   r    s    r  c                       sF   e Zd ZdZ						d fdd	Zedd Zed	d
 Z  ZS )AssertShapea  Assert that inputs have a specified shape.

    **Supported dtypes**:

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

    Parameters
    ----------
    shape : tuple
        The expected shape, given as a ``tuple``. The number of entries in
        the ``tuple`` must match the number of dimensions, i.e. it must
        contain four entries for ``(N, H, W, C)``. If only a single entity
        is augmented, e.g. via
        :func:`~imgaug.augmenters.meta.Augmenter.augment_image`, then ``N`` is
        ``1`` in the input to this augmenter. Images that don't have
        a channel axis will automatically have one assigned, i.e. ``C`` is
        at least ``1``.
        For each component of the ``tuple`` one of the following datatypes
        may be used:

            * If a component is ``None``, any value for that dimensions is
              accepted.
            * If a component is ``int``, exactly that value (and no other one)
              will be accepted for that dimension.
            * If a component is a ``tuple`` of two ``int`` s with values ``a``
              and ``b``, only a value within the interval ``[a, b)`` will be
              accepted for that dimension.
            * If an entry is a ``list`` of ``int`` s, only a value from that
              ``list`` will be accepted for that dimension.

    check_images : bool, optional
        Whether to validate input images via the given shape.

    check_heatmaps : bool, optional
        Whether to validate input heatmaps via the given shape.
        The number of heatmaps will be verified as ``N``. For each
        :class:`~imgaug.augmentables.heatmaps.HeatmapsOnImage` instance
        its array's height and width will be verified as ``H`` and ``W``,
        but not the channel count.

    check_segmentation_maps : bool, optional
        Whether to validate input segmentation maps via the given shape.
        The number of segmentation maps will be verified as ``N``. For each
        :class:`~imgaug.augmentables.segmaps.SegmentationMapOnImage` instance
        its array's height and width will be verified as ``H`` and ``W``,
        but not the channel count.

    check_keypoints : bool, optional
        Whether to validate input keypoints via the given shape.
        This will check (a) the number of keypoints and (b) for each
        :class:`~imgaug.augmentables.kps.KeypointsOnImage` instance the
        ``.shape`` attribute, i.e. the shape of the corresponding image.

    check_bounding_boxes : bool, optional
        Whether to validate input bounding boxes via the given shape.
        This will check (a) the number of bounding boxes and (b) for each
        :class:`~imgaug.augmentables.bbs.BoundingBoxesOnImage` instance the
        ``.shape`` attribute, i.e. the shape of the corresponding image.

        Added in 0.4.0.

    check_polygons : bool, optional
        Whether to validate input polygons via the given shape.
        This will check (a) the number of polygons and (b) for each
        :class:`~imgaug.augmentables.polys.PolygonsOnImage` instance the
        ``.shape`` attribute, i.e. the shape of the corresponding image.

    check_line_strings : bool, optional
        Whether to validate input line strings via the given shape.
        This will check (a) the number of line strings and (b) for each
        :class:`~imgaug.augmentables.lines.LineStringsOnImage` instance the
        ``.shape`` attribute, i.e. the shape of the corresponding image.

        Added in 0.4.0.

    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
    >>> seq = iaa.Sequential([
    >>>     iaa.AssertShape((None, 32, 32, 3)),
    >>>     iaa.Fliplr(0.5)
    >>> ])

    Verify first for each image batch if it contains a variable number of
    ``32x32`` images with ``3`` channels each. Only if that check succeeds, the
    horizontal flip will be executed. Otherwise an assertion error will be
    raised.

    >>> seq = iaa.Sequential([
    >>>     iaa.AssertShape((None, (32, 64), 32, [1, 3])),
    >>>     iaa.Fliplr(0.5)
    >>> ])

    Similar to the above example, but now the height may be in the interval
    ``[32, 64)`` and the number of channels may be either ``1`` or ``3``.

    TNrx   c                    s   t |dksJ dt |t|f || _dd }tt| j|t|||t|||t|||t	|||t
|||t|||t|||	|
||d d S )NrU   z7Expected shape to have length 4, got %d with shape: %s.c                 S   s   |r| S d S ro   r   )r   Zdo_user   r   r   r  B  s   z&AssertShape.__init__.<locals>._defaultr  )rB   r9   rX   rz   r  rn   _AssertShapeImagesCheck_AssertShapeHeatmapsCheck_AssertShapeSegmapCheck_AssertShapeKeypointsCheck_AssertShapeBoundingBoxesCheck_AssertShapePolygonsCheck_AssertShapeLineStringsCheck)rl   rX   Zcheck_imagesZcheck_heatmapsZcheck_segmentation_mapsZcheck_keypointsZcheck_bounding_boxesZcheck_polygonsZcheck_line_stringsr   r-   ri   rj   r  r   r   r   rn   7  s@   

zAssertShape.__init__c                    s   |d urut |r |ksJ d||| f d S t|trMt|dks-J dt|f |d    kr;|d k sKn J d|||d |d  f d S t|trkt fdd|D siJ d	||t| f d S td
|t	|f d S )Nz;Expected dim %d (entry index: %s) to have value %d, got %d.r
   zHExpected tuple argument 'expected' to contain exactly 2 entries, got %d.r   r   zMExpected dim %d (entry index: %s) to have value in interval [%d, %d), got %d.c                    s   g | ]} |kqS r   r   )r    valobservedr   r   r"   i  rf   z(AssertShape._compare.<locals>.<listcomp>zBExpected dim %d (entry index: %s) to have any value of %s, got %d.zxInvalid datatype for shape entry %d, expected each entry to be an integer, a tuple (with two entries) or a list, got %s.)
r#   r  r0   r  rB   rQ   r   r9   rC   r:   )r   r  expected	dimensionZimage_indexr   r  r   _compareW  sF   


 

zAssertShape._comparec                 C   sl   |d d ur|  t||d dd t|D ]\}}t|dd  D ]\}}|| }|  |||| q"qd S )Nr   ALLr   )r  rB   rH   )r   ZshapesZshape_targetZaugm_idxrX   Zdim_idxr  r  r   r   r   _check_shapess  s   zAssertShape._check_shapes)TTTTTTTNNrx   rx   )	rt   ru   rv   rw   rn   rh  r  r  ri  r   r   r   r   r    s     
r  c                   @   r  )r  c                 C   
   || _ d S ro   r  rl   rX   r   r   r   rn        
z _AssertShapeImagesCheck.__init__c                 C   s   t dd |D | j |S )Nc                 S      g | ]}|j qS r   r  r    rO   r   r   r   r"         z4_AssertShapeImagesCheck.__call__.<locals>.<listcomp>r  r  rX   )rl   r&   _random_staterS  _hooksr   r   r   r    s   z _AssertShapeImagesCheck.__call__Nr  r   r   r   r   r        r  c                   @   r  )r  c                 C   r  ro   r  r  r   r   r   rn     r  z"_AssertShapeHeatmapsCheck.__init__c                 C   $   t dd |D | jdd  |S )Nc                 S   r  r   )Zarr_0to1rX   r  r   r   r   r"     rf   z6_AssertShapeHeatmapsCheck.__call__.<locals>.<listcomp>r   rV   r  )rl   r   r  rS  r  r   r   r   r       z"_AssertShapeHeatmapsCheck.__call__Nr  r   r   r   r   r    r  r  c                   @   r  )r  c                 C   r  ro   r  r  r   r   r   rn     r  z _AssertShapeSegmapCheck.__init__c                 C   r  )Nc                 S   r  r   )rc   rX   r  r   r   r   r"     rf   z4_AssertShapeSegmapCheck.__call__.<locals>.<listcomp>r   rV   r  )rl   r   r  rS  r  r   r   r   r    r   z _AssertShapeSegmapCheck.__call__Nr  r   r   r   r   r    r  r  c                   @   r  )r  c                 C   r  ro   r  r  r   r   r   rn     r  z#_AssertShapeKeypointsCheck.__init__c                 C   r  )Nc                 S   r  r   r  r  r   r   r   r"     r  z7_AssertShapeKeypointsCheck.__call__.<locals>.<listcomp>r   rV   r  )rl   r   r  rS  r  r   r   r   r    r   z#_AssertShapeKeypointsCheck.__call__Nr  r   r   r   r   r    r  r  c                   @   r  )r  c                 C   r  ro   r  r  r   r   r   rn     r  z'_AssertShapeBoundingBoxesCheck.__init__c                 C   r  )Nc                 S   r  r   r  r  r   r   r   r"     r  z;_AssertShapeBoundingBoxesCheck.__call__.<locals>.<listcomp>r   rV   r  )rl   r   r  rS  r  r   r   r   r       
z'_AssertShapeBoundingBoxesCheck.__call__Nr  r   r   r   r   r    r  r  c                   @   r  )r  c                 C   r  ro   r  r  r   r   r   rn     r  z"_AssertShapePolygonsCheck.__init__c                 C   r  )Nc                 S   r  r   r  r  r   r   r   r"     r  z6_AssertShapePolygonsCheck.__call__.<locals>.<listcomp>r   rV   r  )rl   r   r  rS  r  r   r   r   r    r   z"_AssertShapePolygonsCheck.__call__Nr  r   r   r   r   r    r  r  c                   @   r  )r  c                 C   r  ro   r  r  r   r   r   rn     r  z%_AssertShapeLineStringsCheck.__init__c                 C   r  )Nc                 S   r  r   r  r  r   r   r   r"     r  z9_AssertShapeLineStringsCheck.__call__.<locals>.<listcomp>r   rV   r  )rl   r   r  rS  r  r   r   r   r    r  z%_AssertShapeLineStringsCheck.__call__Nr  r   r   r   r   r    r  r  c                       s8   e Zd ZdZ			d fdd	Zdd Zd	d
 Z  ZS )ChannelShufflead
  Randomize the order of channels in input images.

    **Supported dtypes**:

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

    Parameters
    ----------
    p : float or imgaug.parameters.StochasticParameter, optional
        Probability of shuffling channels in any given image.
        May be a fixed probability as a ``float``, or a
        :class:`~imgaug.parameters.StochasticParameter` that returns ``0`` s
        and ``1`` s.

    channels : None or imgaug.ALL or list of int, optional
        Which channels are allowed to be shuffled with each other.
        If this is ``None`` or ``imgaug.ALL``, then all channels may be
        shuffled. If it is a ``list`` of ``int`` s,
        then only the channels with indices in that list may be shuffled.
        (Values start at ``0``. All channel indices in the list must exist in
        each 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.ChannelShuffle(0.35)

    Shuffle all channels of ``35%`` of all images.

    >>> aug = iaa.ChannelShuffle(0.35, channels=[0, 1])

    Shuffle only channels ``0`` and ``1`` of ``35%`` of all images. As the new
    channel orders ``0, 1`` and ``1, 0`` are both valid outcomes of the
    shuffling, it means that for ``0.35 * 0.5 = 0.175`` or ``17.5%`` of all
    images the order of channels ``0`` and ``1`` is inverted.

          ?Nrx   c                    st   t t| j||||d t|d| _|d u p)|tjkp)t|t	o)t
dd |D }|s5J dt|f || _d S )Nrj  r  c                 S   r'   r   r  r;   r   r   r   r"   %  r*   z+ChannelShuffle.__init__.<locals>.<listcomp>z3Expected None or imgaug.ALL or list of int, got %s.)rz   r  rn   r  r  r  r#   r  r0   rQ   r@   r:   r]   )rl   r  r]   r   r-   ri   rj   Zvalid_channelsr   r   r   rn     s"   


zChannelShuffle.__init__c                 C   sx   |j d u r|S |j }t|}| jj|f|d}||}tt|||D ]\}	\}
}}|dkr9t|
|| j|j |	< q$|S )Nr  gH.?)	r&   rB   r  r  Z	duplicaterH   rR   shuffle_channelsr]   )rl   r   ri   r   r   r&   r  Z	p_samplesZrssrN   r   Zp_irsr   r   r   r   -  s   


zChannelShuffle._augment_batch_c                 C   s   | j | jgS rw  )r  r]   rq   r   r   r   rG  <  s   zChannelShuffle.get_parameters)r  NNNrx   rx   r  r   r   r   r   r    s    Cr  c           
      C   s   | j dk s| jd dkr| S | jd }t|}|du p-|tjkp-tt|t|dk}|r;|	|}| d|f S |	|}|}t
||D ]\}}	|	||< qG| d|f S )a  Randomize the order of (color) channels in an image.

    **Supported dtypes**:

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

        - (1) Indirectly tested via :class:`ChannelShuffle`.

    Parameters
    ----------
    image : (H,W,[C]) ndarray
        Image of any dtype for which to shuffle the channels.

    random_state : imgaug.random.RNG
        The random state to use for this shuffling operation.

    channels : None or imgaug.ALL or list of int, optional
        Which channels are allowed to be shuffled with each other.
        If this is ``None`` or ``imgaug.ALL``, then all channels may be
        shuffled. If it is a ``list`` of ``int`` s,
        then only the channels with indices in that list may be shuffled.
        (Values start at ``0``. All channel indices in the list must exist in
        the image.)

    Returns
    -------
    ndarray
        The input image with shuffled channels.

    rV   r
   r   Nr   .)r[   rX   r   r  r#   r  rB   set
differencero  rR   )
r   ri   r]   r  Zall_channelsZis_all_channelsZchannels_permZchannels_perm_fullZchannel_sourceZchannel_targetr   r   r   r  A  s"   +




r  c                       r  )RemoveCBAsByOutOfImageFractiona%  Remove coordinate-based augmentables exceeding an out of image fraction.

    This augmenter inspects all coordinate-based augmentables (e.g.
    bounding boxes, line strings) within a given batch and removes any such
    augmentable which's out of image fraction is exactly a given value or
    greater than that. The out of image fraction denotes the fraction of the
    augmentable's area that is outside of the image, e.g. for a bounding box
    that has half of its area outside of the image it would be ``0.5``.

    Added in 0.4.0.

    **Supported dtypes**:

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

    Parameters
    ----------
    fraction : number
        Remove any augmentable for which ``fraction_{actual} >= fraction``,
        where ``fraction_{actual}`` denotes the estimated out of image
        fraction.

    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.Sequential([
    >>>     iaa.Affine(translate_px={"x": (-100, 100)}),
    >>>     iaa.RemoveCBAsByOutOfImageFraction(0.5)
    >>> ])

    Translate all inputs by ``-100`` to ``100`` pixels on the x-axis, then
    remove any coordinate-based augmentable (e.g. bounding boxes) which has
    at least ``50%`` of its area outside of the image plane.

    >>> import imgaug as ia
    >>> import imgaug.augmenters as iaa
    >>> image = ia.quokka_square((100, 100))
    >>> bb = ia.BoundingBox(x1=50-25, y1=0, x2=50+25, y2=100)
    >>> bbsoi = ia.BoundingBoxesOnImage([bb], shape=image.shape)
    >>> aug_without = iaa.Affine(translate_px={"x": 51})
    >>> aug_with = iaa.Sequential([
    >>>     iaa.Affine(translate_px={"x": 51}),
    >>>     iaa.RemoveCBAsByOutOfImageFraction(0.5)
    >>> ])
    >>>
    >>> image_without, bbsoi_without = aug_without(
    >>>     image=image, bounding_boxes=bbsoi)
    >>> image_with, bbsoi_with = aug_with(
    >>>     image=image, bounding_boxes=bbsoi)
    >>>
    >>> assert len(bbsoi_without.bounding_boxes) == 1
    >>> assert len(bbsoi_with.bounding_boxes) == 0

    Create a bounding box on an example image, then translate the image so that
    ``50%`` of the bounding box's area is outside of the image and compare
    the effects and using ``RemoveCBAsByOutOfImageFraction`` with not using it.

    Nrx   c                    s"   t t| j||||d || _d S r  )rz   r  rn   fraction)rl   r	  r   r-   ri   rj   r   r   r   rn     s
   

z'RemoveCBAsByOutOfImageFraction.__init__c                 C   s@   |j D ]}|jdv rt|jD ]\}}|| j|j|< qq|S N)r   r   r   r   )r   r-   rH   r   Zremove_out_of_image_fraction_r	  rl   r   ri   r   r   r   rN   Zcbaoir   r   r   r     s   

z.RemoveCBAsByOutOfImageFraction._augment_batch_c                 C   rv  rw  )r	  rq   r   r   r   rG    rx  z-RemoveCBAsByOutOfImageFraction.get_parametersrf  r  r   r   r   r   r    s    Z
r  c                       r  )ClipCBAsToImagePlanesa	  Clip coordinate-based augmentables to areas within the image plane.

    This augmenter inspects all coordinate-based augmentables (e.g.
    bounding boxes, line strings) within a given batch and from each of them
    parts that are outside of the image plane. Parts within the image plane
    will be retained. This may e.g. shrink down bounding boxes. For keypoints,
    it removes any single points outside of the image plane. Any augmentable
    that is completely outside of the image plane will be removed.

    Added in 0.4.0.

    **Supported dtypes**:

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

    Parameters
    ----------
    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.Sequential([
    >>>     iaa.Affine(translate_px={"x": (-100, 100)}),
    >>>     iaa.ClipCBAsToImagePlanes()
    >>> ])

    Translate input data on the x-axis by ``-100`` to ``100`` pixels,
    then cut all coordinate-based augmentables (e.g. bounding boxes) down
    to areas that are within the image planes of their corresponding images.

    Nrx   c                    r  r  )rz   r  rn   r   r   r   r   rn   5  r  zClipCBAsToImagePlanes.__init__c                 C   s<   |j D ]}|jdv rt|jD ]\}}| |j|< qq|S r
  )r   r-   rH   r   Zclip_out_of_image_r  r   r   r   r   =  s   

z%ClipCBAsToImagePlanes._augment_batch_c                 C   rH  rw  r   rq   r   r   r   rG  G  r  z$ClipCBAsToImagePlanes.get_parametersrf  r  r   r   r   r   r    s    >
r  )r+   ro   )Hrw   
__future__r   r   r   abcr   r   r)   r_  rQ  r  r   r  numpyr   sixZ	six.movesmovesr#  Zimgaugr#   Zimgaug.augmentables.batchesr   r   r	    r   r  r   r   r   r   rx   r   r   r   r   rF   rP   rT   r^   r`   rd   rg   objectrh   add_metaclassr1   rQ   r>   r  r  r  r  rY  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   <module>   s    




	(                     a 7  E  wF.  L  M
lBt