o
    &j                    @   s  d Z ddlmZmZmZ ddlZddlmZ ddl	m
Z
m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ZddlZddlmZ ddlmZ dd	lmZ dd
lmZ dd Z		deddZ 		dfddZ!dgddZ"		dhddZ#		diddZ$dd Z%dd Z&			djdd Z'			djd!d"Z(e)e
G d#d$ d$e*Z+G d%d& d&e+Z,G d'd( d(e+Z-G d)d* d*e+Z.G d+d, d,e+Z/G d-d. d.e+Z0G d/d0 d0e+Z1G d1d2 d2e+Z2G d3d4 d4e+Z3G d5d6 d6e+Z4G d7d8 d8e+Z5G d9d: d:e+Z6G d;d< d<e+Z7G d=d> d>e+Z8G d?d@ d@e+Z9G dAdB dBe+Z:G dCdD dDe+Z;G dEdF dFe+Z<G dGdH dHe+Z=G dIdJ dJe+Z>G dKdL dLe+Z?G dMdN dNe+Z@G dOdP dPe+ZAG dQdR dRe+ZBG dSdT dTe+ZCdkdWdXZDdkdYdZZEG d[d\ d\e+ZFG d]d^ d^e+ZGG d_d` d`e+ZHG dadb dbe+ZIdcdd ZJdS )lzClasses and methods to use for parameters of augmenters.

This module contains e.g. classes representing probability
distributions (guassian, poisson etc.), classes representing noise sources
and methods to normalize parameter-related user inputs.

    )print_functiondivisionabsolute_importN)defaultdict)ABCMetaabstractmethod   )imgaug)dtypes)random)OpenSimplexc                 C   s  |d u rdS t |trvt|dksJ dt|f |d d u r(|d d u r(dS |d d u r@| |d ks>J d||d f dS |d d u rX|d | ksVJ d||d f dS |d |   krf|d kstn J d||d |d f dS t|r||  dS td	t|f )
NT   zGIf 'value_range' is a tuple, it must contain exactly 2 entries, got %d.r   r   zAParameter '%s' is outside of the expected value range (x <= %.4f)zAParameter '%s' is outside of the expected value range (%.4f <= x)zIParameter '%s' is outside of the expected value range (%.4f <= x <= %.4f)z)Unexpected input for value_range, got %s.)
isinstancetupleleniaZis_callable	Exceptionstr)valuenamevalue_range r   R/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/imgaug/parameters.py_check_value_range   sJ   


 
r   Tc                 C   sJ  t | rt| || t| S |rUt| trUt| dks&J d|t| f tdd | D s<J d|dd | D f t| d || t| d || t| d | d S |rt 	| rt| tstd	d | D swJ d
|dd | D f | D ]}t||| qyt
| S t| tr| S d}|rd|f nd}td||||t| f )Nr   PExpected parameter '%s' with type tuple to have exactly two entries, but got %d.c                 S      g | ]}t |qS r   r   is_single_number.0vr   r   r   
<listcomp>N       z+handle_continuous_param.<locals>.<listcomp>zHExpected parameter '%s' with type tuple to only contain numbers, got %s.c                 S      g | ]}t |qS r   typer   r   r   r   r!   P       r   r   c                 S   r   r   r   r   r   r   r   r!   W   r"   AExpected iterable parameter '%s' to only contain numbers, got %s.c                 S   r#   r   r$   r   r   r   r   r!   Y   r&   number, list of %s EExpected %s, tuple of two %s%s or StochasticParameter for %s, got %s.)r   r   r   Deterministicr   r   r   allUniformis_iterableChoiceStochasticParameterr   r%   )paramr   r   tuple_to_uniformlist_to_choiceparam_iallowed_typelist_strr   r   r   handle_continuous_paramD   sL   


r8   c           
         s  t | s rt | rt| || tt| S |rkt| trkt| dks/J d|t| f t	 fdd| D }|sNJ d| rCdnddd | D f t| d	 || t| d
 || t
t| d	 t| d
 S |rt | rt| tst	 fdd| D }|sJ d| rdnddd | D f | D ]}t||| qtdd | D S t| tr| S  rdnd}|rd|f nd}	td|||	|t| f )Nr   r   c                    $   g | ]} rt |nt |qS r   r   r   is_single_integerr   allow_floatsr   r   r!   t       z)handle_discrete_param.<locals>.<listcomp>zAExpected parameter '%s' of type tuple to only contain %s, got %s.r(   integerc                 S   r#   r   r$   r   r   r   r   r!   }   r&   r   r   c                    r9   r   r:   r   r<   r   r   r!      r>   <Expected iterable parameter '%s' to only contain %s, got %s.c                 S   r#   r   r$   r   r   r   r   r!      r&   c                 S   r#   r   intr   r5   r   r   r   r!      r&   rB   r)   r*   r+   )r   r;   is_single_floatr   r,   rB   r   r   r   r-   DiscreteUniformr/   r0   r1   r   r%   )
r2   r   r   r3   r4   r=   is_valid_typesr5   r6   r7   r   r<   r   handle_discrete_parami   sl   




rG   c                    s  | t jkr d urtt S t | r. d ur*|  v s*J d|dt | f t| S t| trntdd | D sLJ d|ddd | D f  d urjt fdd| D sjJ d|d d| f t| S t| t	ru| S t
d	| d ur~d
ndt| jf )Nz2Expected parameter '%s' to be one of: %s. Got: %s., c                 S   r   r   r   	is_stringr   valr   r   r   r!      r"   z3handle_categorical_string_param.<locals>.<listcomp>zQExpected list provided for parameter '%s' to only contain strings, got types: %s.c                 S   s   g | ]}t |jqS r   )r%   __name__r   r   r   r   r!      r"   c                    s   g | ]}| v qS r   r   rK   valid_valuesr   r   r!      r&   zmExpected list provided for parameter '%s' to only contain the following allowed strings: %s. Got strings: %s.z[Expected parameter '%s' to be%s a string, a list of strings or StochasticParameter, got %s.z imgaug.ALL,r*   )r   ALLr0   listrJ   joinr,   r   r-   r1   r   r%   rM   )r2   r   rO   r   rN   r   handle_categorical_string_param   sF   



rS   r   Nc                    s  t | s rt | rt| || tt| d fS t| trt| dks/J d|t| f t	dd | D sC rbt	dd | D rbt| d || t| d || t
t| d t| d d fS t	dd | D rs| d | d fS t| d d	|f | d
t| d d|f | d
f}|S t | rt| tst	 fdd| D }|sJ d| rdnddd | D f | D ]}t||| qtdd | D d fS t| tr| d fS tdt| f )Nr   r   c                 S   r   r   r   r;   rC   r   r   r   r!      r"   z5handle_discrete_kernel_size_param.<locals>.<listcomp>c                 S   r   r   )r   rD   rC   r   r   r   r!          r   r   c                 S      g | ]}t |tqS r   r   r1   rC   r   r   r   r!      rV   z%s[0]r<   z%s[1]c                    r9   r   r:   r   r<   r   r   r!      r>   r@   r(   r?   c                 S   r#   r   r$   r   r   r   r   r!      r&   c                 S   r#   r   rA   rC   r   r   r   r!      r&   zGExpected int, tuple/list with 2 entries or StochasticParameter. Got %s.)r   r;   rD   r   r,   rB   r   r   r   r-   rE   rG   r/   r0   r1   r   r%   )r2   r   r   r=   ZhandledrF   r5   r   r<   r   !handle_discrete_kernel_size_param   sv   


	

rY   Fc                 C   s   d}| dv rt t| S t| rSd|   krdks$n J d|| f d| |   k r2d| k sFn d| |   k rAd| k rOn t| S t tt| S t| S |rt| trt	dd | D spJ d|d	d | D f t
| d
ksJ d|t
| f d| d   krdkrn nd| d   krdksn J d|| d | d f tt| d | d S |rt| rt	dd | D sJ d|dd | D f t	dd | D sJ d|ddd | D f tt| S t| tr| S td|t| f )Ngư>)TFr   r                 ?zRExpected probability of parameter '%s' to be in the interval [0.0, 1.0], got %.4f.c                 S   r   r   r   r   r   r   r   r!     r"   z,handle_probability_param.<locals>.<listcomp>zFExpected parameter '%s' of type tuple to only contain numbers, got %s.c                 S   r#   r   r$   r   r   r   r   r!     r&   r   zKExpected parameter '%s' of type tuple to contain exactly 2 entries, got %d.r   r   zxExpected parameter '%s' of type tuple to contain two probabilities in the interval [0.0, 1.0]. Got values %.4f and %.4f.c                 S   r   r   r   r   r   r   r   r!     r"   r'   c                 S   r#   r   r$   r   r   r   r   r!     r&   c                 S   $   g | ]}d |  kodkn  qS )r   r[   r   r   Zp_ir   r   r   r!        $ ziExpected iterable parameter '%s' to only contain probabilities in the interval [0.0, 1.0], got values %s.rH   c                 S      g | ]}d |f qS z%.4fr   r]   r   r   r   r!     r"   zAExpected boolean or number or StochasticParameter for %s, got %s.)r,   rB   r   r   nproundBinomialr   r   r-   r   r.   r/   rR   r0   r1   r   r%   )r2   r   r3   r4   epsr   r   r   handle_probability_param   sd   
<
8

re   c                 C   s   | j jdkr| S | tjS )Nf)dtypekindastypera   float64)rL   r   r   r   force_np_float_dtype*  s   rk   c                 C   sl   | j jtjv }|j jtjv }|r|r| |fS |r | |tjfS |r*| tj|fS | tj|tjfS N)rg   r%   r   ZNP_FLOAT_TYPESri   ra   rj   )abZa_fZb_fr   r   r   both_np_float_if_one_is_float0  s   ro   ^  rq   c           	      C   s   |d u rd gt |  }n|du rdgt |  }|d ur'dd t| ||D }n
dd t| |D }tj||d}tj|||d}|S )NFc                 S   s    g | ]\}}}|j ||d qS ))sizetitledraw_distribution_graph)r   r5   Zsize_ititle_ir   r   r   r!   F  s    z+draw_distributions_grid.<locals>.<listcomp>c                 S   s   g | ]
\}}|j |d qS )rs   rt   )r   r5   rv   r   r   r   r!   J  s    
)sizes)rowscols)r   zipr   imresize_many_imagesZ	draw_grid)	paramsry   rz   graph_sizessample_sizestitlesZimagesZ	images_rsgridr   r   r   draw_distributions_grid=  s   
r   c              
   C   s   t t| |||||d d S )N)r~   r   ry   rz   r   )r   Zimshowr   )r}   ry   rz   r~   r   r   r   r   r   show_distributions_gridS  s   r   c                   @   s   e Zd ZdZdd Zd/ddZd/ddZed	d
 Zdd Z	dd Z
d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/dd Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd0d-d.ZdS )1r1   a  Abstract parent class for all stochastic parameters.

    Stochastic parameters are here all parameters from which values are
    supposed to be sampled. Usually the sampled values are to a degree random.
    E.g. a stochastic parameter may be the uniform distribution over the
    interval ``[-10, 10]``. Samples from that distribution (and therefore the
    stochastic parameter) could be ``5.2``, ``-3.7``, ``-9.7``, ``6.4``, etc.

    c                 C   s   d S rl   r   selfr   r   r   __init__n  s   zStochasticParameter.__init__Nc                 C   s   | j d|dd S )as  
        Draws a single sample value from this parameter.

        Parameters
        ----------
        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
            A seed or random number generator to use during the sampling
            process. If ``None``, the global RNG will be used.
            See also :func:`~imgaug.augmenters.meta.Augmenter.__init__`
            for a similar parameter with more details.

        Returns
        -------
        any
            A single sample value.

        r   random_stater   )draw_samples)r   r   r   r   r   draw_sampleq  s   zStochasticParameter.draw_samplec                 C   s6   t |}| t|s|nt|g|}|  |S )aO  Draw one or more samples from the parameter.

        Parameters
        ----------
        size : tuple of int or int
            Number of samples by dimension.

        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
            A seed or random number generator to use during the sampling
            process. If ``None``, the global RNG will be used.
            See also :func:`~imgaug.augmenters.meta.Augmenter.__init__`
            for a similar parameter with more details.

        Returns
        -------
        ndarray
            Sampled values. Usually a numpy ndarray of basically any dtype,
            though not strictly limited to numpy arrays. Its shape is expected
            to match `size`.

        )iarandomZRNG_draw_samplesr   r;   r   Zadvance_r   rr   r   samplesr   r   r   r     s   
z StochasticParameter.draw_samplesc                 C   s   t  rl   )NotImplementedError)r   rr   r   r   r   r   r     s   z!StochasticParameter._draw_samplesc                 C   0   t |s
t|trt| |S tdt|f )NzmInvalid datatypes in: StochasticParameter + %s. Expected second argument to be number or StochasticParameter.r   r   r   r1   Addr   r%   r   otherr   r   r   __add__     
zStochasticParameter.__add__c                 C   r   )NzmInvalid datatypes in: StochasticParameter - %s. Expected second argument to be number or StochasticParameter.r   r   r   r1   Subtractr   r%   r   r   r   r   __sub__  r   zStochasticParameter.__sub__c                 C   r   )NzmInvalid datatypes in: StochasticParameter * %s. Expected second argument to be number or StochasticParameter.r   r   r   r1   Multiplyr   r%   r   r   r   r   __mul__  r   zStochasticParameter.__mul__c                 C   s@   |d urt dt|st|trt| |S tdt|f )N?Modulo power is currently not supported by StochasticParameter.znInvalid datatypes in: StochasticParameter ** %s. Expected second argument to be number or StochasticParameter.r   r   r   r   r1   Powerr   r%   r   r   zr   r   r   __pow__     
zStochasticParameter.__pow__c                 C   r   )NzmInvalid datatypes in: StochasticParameter / %s. Expected second argument to be number or StochasticParameter.r   r   r   r1   Divider   r%   r   r   r   r   __div__  r   zStochasticParameter.__div__c                 C   r   )NzwInvalid datatypes in: StochasticParameter / %s (truediv). Expected second argument to be number or StochasticParameter.r   r   r   r   r   __truediv__  r   zStochasticParameter.__truediv__c                 C   s4   t |s
t|trtt| |S tdt|f )NzyInvalid datatypes in: StochasticParameter // %s (floordiv). Expected second argument to be number or StochasticParameter.r   r   r   r1   
Discretizer   r   r%   r   r   r   r   __floordiv__     z StochasticParameter.__floordiv__c                 C   0   t |s
t|trt|| S tdt|f )NzmInvalid datatypes in: %s + StochasticParameter. Expected second argument to be number or StochasticParameter.r   r   r   r   r   __radd__  r   zStochasticParameter.__radd__c                 C   r   )NzmInvalid datatypes in: %s - StochasticParameter. Expected second argument to be number or StochasticParameter.r   r   r   r   r   __rsub__  r   zStochasticParameter.__rsub__c                 C   r   )NzmInvalid datatypes in: %s * StochasticParameter. Expected second argument to be number or StochasticParameter.r   r   r   r   r   __rmul__  r   zStochasticParameter.__rmul__c                 C   s@   |d urt dt|st|trt|| S tdt|f )Nr   znInvalid datatypes in: %s ** StochasticParameter. Expected second argument to be number or StochasticParameter.r   r   r   r   r   __rpow__  r   zStochasticParameter.__rpow__c                 C   r   )NzmInvalid datatypes in: %s / StochasticParameter. Expected second argument to be number or StochasticParameter.r   r   r   r   r   __rdiv__  r   zStochasticParameter.__rdiv__c                 C   r   )NzxInvalid datatypes in: %s / StochasticParameter (rtruediv). Expected second argument to be number or StochasticParameter.r   r   r   r   r   __rtruediv__  r   z StochasticParameter.__rtruediv__c                 C   s4   t |s
t|trtt|| S tdt|f )NzzInvalid datatypes in: StochasticParameter // %s (rfloordiv). Expected second argument to be number or StochasticParameter.r   r   r   r   r   __rfloordiv__  r   z!StochasticParameter.__rfloordiv__c                 C   
   t | S )zCreate a shallow copy of this parameter.

        Returns
        -------
        imgaug.parameters.StochasticParameter
            Shallow copy.

        )copy_modulecopyr   r   r   r   r        
	zStochasticParameter.copyc                 C   r   )zCreate a deep copy of this parameter.

        Returns
        -------
        imgaug.parameters.StochasticParameter
            Deep copy.

        )r   deepcopyr   r   r   r   r   )  r   zStochasticParameter.deepcopy  r   d   c                    s`  ddl m} g }t|d D ]}|| |dd   qt|}|	 }|
d | }tj||d\}	}|	t|	 }	|j|dd |	t|t| t| ddd	  du rat|   d
ur} fddtdt dD }
|d|
 |jdd tjdd}||j t|dddf }W d   n1 sw   Y  |  |S )a  Generate an image visualizing the parameter's sample distribution.

        Parameters
        ----------
        title : None or False or str, optional
            Title of the plot. ``None`` is automatically replaced by a title
            derived from ``str(param)``. If set to ``False``, no title will be
            shown.

        size : tuple of int
            Number of points to sample. This is always expected to have at
            least two values. The first defines the number of sampling runs,
            the second (and further) dimensions define the size assigned
            to each :func:`~imgaug.parameters.StochasticParameter.draw_samples`
            call. E.g. ``(10, 20, 15)`` will lead to ``10`` calls of
            ``draw_samples(size=(20, 15))``. The results will be merged to a
            single 1d array.

        bins : int
            Number of bins in the plot histograms.

        Returns
        -------
        data : (H,W,3) ndarray
            Image of the plot.

        r   Nr   o   )binsblueg      ?)widthcoloralphaFc                    s   g | ]
} ||d   qS )2   r   )r   irw   r   r   r!   g  s    z?StochasticParameter.draw_distribution_graph.<locals>.<listcomp>r   
)padz.png)suffix.   )Zmatplotlib.pyplotZpyplotsmxrangeappendr   flattenra   ZconcatenateZfigureZadd_subplotZgcaZ	histogramsumbarmaxminr   r   	set_titlerR   Ztight_layouttempfileNamedTemporaryFileZsavefigr   imageioZimreadclose)r   rs   rr   r   ZpltZpoints_ZfigaxZheightsZtitle_fragmentsrf   datar   rw   r   ru   4  s:   


z+StochasticParameter.draw_distribution_graphrl   )Nr   r   )rM   
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ru   r   r   r   r   r1   b  s0    





r1   c                       8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
r,   a  Parameter that is a constant value.

    If ``N`` values are sampled from this parameter, it will return ``N`` times
    ``V``, where ``V`` is the constant value.

    Parameters
    ----------
    value : number or str or imgaug.parameters.StochasticParameter
        A constant value to use.
        A string may be provided to generate arrays of strings.
        If this is a StochasticParameter, a single value will be sampled
        from it exactly once and then used as the constant value.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Deterministic(10)
    >>> param.draw_sample()
    10

    Will always sample the value 10.

    c                    sV   t t|   t|tr| | _d S t|st	|r"|| _d S t
dt|f )Nz@Expected StochasticParameter object or number or string, got %s.)superr,   r   r   r1   r   r   r   r   rJ   r   r%   )r   r   	__class__r   r   r     s   

zDeterministic.__init__c                 C   sH   i }t | jrdtji}nt | jrdtji}tj|| jfi |S )Nrg   )r   r;   r   ra   int32rD   float32full)r   rr   r   kwargsr   r   r   r     s   
zDeterministic._draw_samplesc                 C      |   S rl   __str__r   r   r   r   __repr__     zDeterministic.__repr__c                 C   s@   t | jrd| jf S t | jrd| jf S dt| jf S )NzDeterministic(int %d)zDeterministic(float %.8f)zDeterministic(%s))r   r;   r   rD   r   r   r   r   r   r     s
   zDeterministic.__str__	rM   r   r   r   r   r   r   r   __classcell__r   r   r   r   r,   w  s    r,   c                       r   )
DeterministicListaj  Parameter that repeats elements from a list in the given order.

    E.g. of samples of shape ``(A, B, C)`` are requested, this parameter will
    return the first ``A*B*C`` elements, reshaped to ``(A, B, C)`` from the
    provided list. If the list contains less than ``A*B*C`` elements, it
    will (by default) be tiled until it is long enough (i.e. the sampling
    will start again at the first element, if necessary multiple times).

    Added in 0.4.0.

    Parameters
    ----------
    values : ndarray or iterable of number
        An iterable of values to sample from in the order within the iterable.

    c                    s   t t|   t|sJ dt|jf t|dks J dt|r,|	 | _
d S ttt	|| _
| j
jj}|dkrJ| j
tj| _
d S |dkrX| j
tj| _
d S d S )Nz2Expected to get an iterable as input, got type %s.r   z-Expected to get at least one value, got zero.r   rf   )r   r   r   r   r/   r%   rM   r   Zis_np_arrayr   valuesra   arrayrQ   rg   rh   ri   r   r   )r   r   rh   r   r   r   r     s    

zDeterministicList.__init__c                 C   sT   t t|}| j}|| jjkr!t t||j }t||f}|d | |S rl   )rB   ra   prodr   rr   ceiltilereshape)r   rr   r   Znb_requestedr   Z
multiplierr   r   r   r     s   zDeterministicList._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zDeterministicList.__repr__c                 C   sB   | j jjdkrdd | j D }dd|f S dt| j  f S )Nrf   c                 S   r_   r`   r   )r   r   r   r   r   r!     r"   z-DeterministicList.__str__.<locals>.<listcomp>zDeterministicList([%s])rH   zDeterministicList(%s))r   rg   rh   rR   r   tolist)r   r   r   r   r   r     s   zDeterministicList.__str__r   r   r   r   r   r     s    r   c                       s:   e Zd ZdZd fdd	Zdd Zdd	 Zd
d Z  ZS )r0   a7  Parameter that samples value from a list of allowed values.

    Parameters
    ----------
    a : iterable
        List of allowed values.
        Usually expected to be ``int`` s, ``float`` s or ``str`` s.
        May also contain ``StochasticParameter`` s. Each
        ``StochasticParameter`` that is randomly picked will automatically be
        replaced by a sample of itself (or by ``N`` samples if the parameter
        was picked ``N`` times).

    replace : bool, optional
        Whether to perform sampling with or without replacing.

    p : None or iterable of number, optional
        Probabilities of each element in `a`.
        Must have the same length as `a` (if provided).

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Choice([5, 17, 25], p=[0.25, 0.5, 0.25])
    >>> sample = param.draw_sample()
    >>> assert sample in [5, 17, 25]

    Create and sample from a parameter, which will produce with ``50%``
    probability the sample ``17`` and in the other ``50%`` of all cases the
    sample ``5`` or ``25``..

    TNc                    s   t t|   t|sJ dt|f || _|| _|d urAt|s-J dt|f t|t|ksAJ dt|t|f || _	d S )Nz1Expected a to be an iterable (e.g. list), got %s.z-Expected p to be None or an iterable, got %s.z;Expected lengths of a and p to be identical, got %d and %d.)
r   r0   r   r   r/   r%   rm   replacer   p)r   rm   r   r   r   r   r   r     s    
zChoice.__init__c                 C   s  t dd | jD r|dt| j }|d j| jt|| j| jd}t	dd }|D ]}t
|tr@t|}||  d7  < q-t }t| jD ]\}	}
t|
}||v re|
j|| f|d|	  d||< qIt	d	d }t|D ]!\}	}t
|trt|}|| }|| | ||	< ||  d7  < qp||}n|j| j|| j| jd}|j}|jd
 dkr|j}|dkr|tj}|S |dkr|tj}|S |dkr|tj}|S )Nc                 S   rW   r   rX   )r   Za_ir   r   r   r!   "  r"   z(Choice._draw_samples.<locals>.<listcomp>r   r   )r   r   c                   S      dS Nr   r   r   r   r   r   <lambda>)      z&Choice._draw_samples.<locals>.<lambda>rr   r   c                   S   r   r   r   r   r   r   r   r   @  r          r   urf   )anyrm   	duplicater   choicera   r   r   r   r   r   r1   r   dict	enumerater   r   rg   itemsizerh   ri   r   Zuint32r   )r   rr   r   rngsr   Zparams_countersamplekeyZparam_to_samplesr   r2   Zparam_to_readcountZ	readcountrg   rh   r   r   r   r   !  sX   



zChoice._draw_samplesc                 C   r   rl   r   r   r   r   r   r   Z  r   zChoice.__repr__c                 C       dt | jt | jt | jf S )NzChoice(a=%s, replace=%s, p=%s))r   rm   r   r   r   r   r   r   r   ]  s   zChoice.__str__)TNr   r   r   r   r   r0     s    9r0   c                       r   )
rc   am  Binomial distribution.

    Parameters
    ----------
    p : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Probability of the binomial distribution. Expected to be in the
        interval ``[0.0, 1.0]``.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Binomial.draw_sample` or
        :func:`Binomial.draw_samples`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Binomial(Uniform(0.01, 0.2))

    Create a binomial distribution that uses a varying probability between
    ``0.01`` and ``0.2``, randomly and uniformly estimated once per sampling
    call.

    c                       t t|   t|d| _d S )Nr   )r   rc   r   r8   r   )r   r   r   r   r   r     s   zBinomial.__init__c                 C   sH   | j j|d}d|  krdksn J d|f |d||tjS )Nr   r   r[   zBExpected probability p to be in the interval [0.0, 1.0], got %.4f.r   )r   r   binomialri   ra   r   )r   rr   r   r   r   r   r   r     s   zBinomial._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zBinomial.__repr__c                 C      d| j f S )NzBinomial(%s))r   r   r   r   r   r        zBinomial.__str__r   r   r   r   r   rc   b  s    rc   c                       r   )
rE   at  Uniform distribution over the discrete interval ``[a..b]``.

    Parameters
    ----------
    a : int or tuple of int or list of int or imgaug.parameters.StochasticParameter
        Lower bound of the interval.
        If ``a>b``, `a` and `b` will automatically be flipped.
        If ``a==b``, all generated values will be identical to `a`.

            * If a single ``int``, this ``int`` will be used as a
              constant value.
            * If a ``tuple`` of two ``int`` s ``(a, b)``, the value will be
              sampled from the discrete interval ``[a..b]`` once per call.
            * If a ``list`` of ``int``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`DiscreteUniform.draw_sample` or
        :func:`DiscreteUniform.draw_samples`.

    b : int or imgaug.parameters.StochasticParameter
        Upper bound of the interval. Analogous to `a`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.DiscreteUniform(10, Choice([20, 30, 40]))
    >>> sample = param.draw_sample()
    >>> assert 10 <= sample <= 40

    Create a discrete uniform distribution which's interval differs between
    calls and can be ``[10..20]``, ``[10..30]`` or ``[10..40]``.

    c                    *   t t|   t|d| _t|d| _d S Nrm   rn   )r   rE   r   rG   rm   rn   r   rm   rn   r   r   r   r        zDiscreteUniform.__init__c                 C   sb   | j j|d}| jj|d}||kr||}}n||kr%tj||tjdS |j||d |tjdS )Nr   rg   r   )rm   r   rn   ra   r   r   Zintegersr   rr   r   rm   rn   r   r   r   r     s   zDiscreteUniform._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zDiscreteUniform.__repr__c                 C      d| j | jf S )NzDiscreteUniform(%s, %s)rm   rn   r   r   r   r   r        zDiscreteUniform.__str__r   r   r   r   r   rE     s    $
rE   c                       r   )
Poissona  Parameter that resembles a poisson distribution.

    A poisson distribution with ``lambda=0`` has its highest probability at
    point ``0`` and decreases quickly from there.
    Poisson distributions are discrete and never negative.

    Parameters
    ----------
    lam : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Lambda parameter of the poisson distribution.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Poisson.draw_sample` or
        :func:`Poisson.draw_samples`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Poisson(1)
    >>> sample = param.draw_sample()
    >>> assert sample >= 0

    Create a poisson distribution with ``lambda=1`` and sample a value from
    it.

    c                    r  )Nlam)r   r  r   r8   r  )r   r  r   r   r   r     s   zPoisson.__init__c                 C   s.   | j j|d}t|d}|j||dtjS )Nr   r   )r  rr   )r  r   r   Zpoissonri   ra   r   )r   rr   r   r  r   r   r   r     s   
zPoisson._draw_samplesc                 C   r   rl   r   r   r   r   r   r      r   zPoisson.__repr__c                 C   r	  )NzPoisson(%s))r  r   r   r   r   r     r
  zPoisson.__str__r   r   r   r   r   r    s    #r  c                       r   )
Normala  Parameter that resembles a normal/gaussian distribution.

    Parameters
    ----------
    loc : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The mean of the normal distribution.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Laplace.draw_sample` or
        :func:`Laplace.draw_samples`.

    scale : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The standard deviation of the normal distribution.
        If this parameter reaches ``0``, the output array will be filled with
        `loc`.
        Datatype behaviour is the analogous to `loc`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Normal(Choice([-1.0, 1.0]), 1.0)

    Create a gaussian distribution with a mean that differs by call.
    Samples values may sometimes follow ``N(-1.0, 1.0)`` and sometimes
    ``N(1.0, 1.0)``.

    c                    .   t t|   t|d| _t|ddd| _d S Nlocscaler   Nr   )r   r  r   r8   r  r  r   r  r  r   r   r   r   +  
   zNormal.__init__c                 C   d   | j j|d}| jj|d}|dksJ d|f |dkr&tj||tjdS |j|||dtjS )Nr   r   #Expected scale to be >=0, got %.4f.r  rr   )r  r   r  ra   r   r   normalri   r   rr   r   r  r  r   r   r   r   2     zNormal._draw_samplesc                 C   r   rl   r   r   r   r   r   r   :  r   zNormal.__repr__c                 C   r  )NzNormal(loc=%s, scale=%s)r  r  r   r   r   r   r   =  r  zNormal.__str__r   r   r   r   r   r    s    #r  c                       sD   e Zd ZdZej ejf fdd	Zdd Zdd Zdd	 Z	  Z
S )
TruncatedNormalaa  Parameter that resembles a truncated normal distribution.

    A truncated normal distribution is similar to a normal distribution,
    except the domain is smoothly bounded to a min and max value.

    This is a wrapper around :func:`scipy.stats.truncnorm`.

    Parameters
    ----------
    loc : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The mean of the normal distribution.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`TruncatedNormal.draw_sample` or
        :func:`TruncatedNormal.draw_samples`.

    scale : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The standard deviation of the normal distribution.
        If this parameter reaches ``0``, the output array will be filled with
        `loc`.
        Datatype behaviour is the same as for `loc`.

    low : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The minimum value of the truncated normal distribution.
        Datatype behaviour is the same as for `loc`.

    high : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The maximum value of the truncated normal distribution.
        Datatype behaviour is the same as for `loc`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.TruncatedNormal(0, 5.0, low=-10, high=10)
    >>> samples = param.draw_samples(100, random_state=0)
    >>> assert np.all(samples >= -10)
    >>> assert np.all(samples <= 10)

    Create a truncated normal distribution with its minimum at ``-10.0``
    and its maximum at ``10.0``.

    c                    sF   t t|   t|d| _t|ddd| _t|d| _t|d| _d S )Nr  r  r  r  lowhigh)r   r&  r   r8   r  r  r'  r(  )r   r  r  r'  r(  r   r   r   r   v  s   zTruncatedNormal.__init__c                 C   s   | j j|d}| jj|d}| jj|d}| jj|d}| }||kr)||}}|dks4J d|f |dkrAtj||tjdS || | }|| | }	t	j
j||	||d}
|
j||dtjS )Nr   r   r   )Z
fill_valuerg   )rm   rn   r  r  r   )r  r   r  r'  r(  generate_seed_ra   r   r   scipystatsZ	truncnormZrvsri   )r   rr   r   r  r  r'  r(  seedrm   rn   Ztnormr   r   r   r     s   
zTruncatedNormal._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zTruncatedNormal.__repr__c                 C   s   d| j | j| j| jf S )Nz2TruncatedNormal(loc=%s, scale=%s, low=%s, high=%s))r  r  r'  r(  r   r   r   r   r     s   zTruncatedNormal.__str__)rM   r   r   r   ra   infr   r   r   r   r   r   r   r   r   r&  B  s    3	r&  c                       r   )
Laplacea  Parameter that resembles a (continuous) laplace distribution.

    This is a wrapper around numpy's :func:`numpy.random.laplace`.

    Parameters
    ----------
    loc : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The position of the distribution peak, similar to the mean in normal
        distributions.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Laplace.draw_sample` or
        :func:`Laplace.draw_samples`.

    scale : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        The exponential decay factor, similar to the standard deviation in
        gaussian distributions.
        If this parameter reaches ``0``, the output array will be filled with
        `loc`.
        Datatype behaviour is the analogous to `loc`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Laplace(0, 1.0)

    Create a laplace distribution, which's peak is at ``0`` and decay is
    ``1.0``.

    c                    r  r  )r   r.  r   r8   r  r  r  r   r   r   r     r  zLaplace.__init__c                 C   r  )Nr   r   z!Expected scale to be >=0, got %s.r  r!  )r  r   r  ra   r   r   Zlaplaceri   r#  r   r   r   r     r$  zLaplace._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zLaplace.__repr__c                 C   r  )NzLaplace(loc=%s, scale=%s)r%  r   r   r   r   r     r  zLaplace.__str__r   r   r   r   r   r.    s    &r.  c                       r   )
	ChiSquarea9  Parameter that resembles a (continuous) chi-square distribution.

    This is a wrapper around numpy's :func:`numpy.random.chisquare`.

    Parameters
    ----------
    df : int or tuple of two int or list of int or imgaug.parameters.StochasticParameter
        Degrees of freedom. Expected value range is ``[1, inf)``.

            * If a single ``int``, this ``int`` will be used as a
              constant value.
            * If a ``tuple`` of two ``int`` s ``(a, b)``, the value will be
              sampled from the discrete interval ``[a..b]`` once per call.
            * If a ``list`` of ``int``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`ChiSquare.draw_sample` or
        :func:`ChiSquare.draw_samples`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.ChiSquare(df=2)

    Create a chi-square distribution with two degrees of freedom.

    c                    "   t t|   t|ddd| _d S )NdfrT   r  )r   r/  r   rG   r1  )r   r1  r   r   r   r        zChiSquare.__init__c                 C   s:   | j j|d}|dksJ d|f |j||dtjS )Nr   r   zExpected df to be >=1, got %d.r!  )r1  r   Z	chisquareri   ra   r   )r   rr   r   r1  r   r   r   r        zChiSquare._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zChiSquare.__repr__c                 C   r	  )NzChiSquare(df=%s))r1  r   r   r   r   r     r
  zChiSquare.__str__r   r   r   r   r   r/    s    r/  c                       r   )
Weibulla!  
    Parameter that resembles a (continuous) weibull distribution.

    This is a wrapper around numpy's :func:`numpy.random.weibull`.

    Parameters
    ----------
    a : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Shape parameter of the distribution.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Weibull.draw_sample` or
        :func:`Weibull.draw_samples`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Weibull(a=0.5)

    Create a weibull distribution with shape 0.5.

    c                    r0  )Nrm   )-C6?Nr  )r   r4  r   r8   rm   )r   rm   r   r   r   r   )  r2  zWeibull.__init__c                 C   s:   | j j|d}|dksJ d|f |j||dtjS )Nr   r   zExpected a to be >0, got %.4f.r!  )rm   r   Zweibullri   ra   r   )r   rr   r   rm   r   r   r   r   /  r3  zWeibull._draw_samplesc                 C   r   rl   r   r   r   r   r   r   5  r   zWeibull.__repr__c                 C   r	  )NzWeibull(a=%s))rm   r   r   r   r   r   8  r
  zWeibull.__str__r   r   r   r   r   r4  
  s    r4  c                       r   )
r.   aI  Parameter that resembles a uniform distribution over ``[a, b)``.

    Parameters
    ----------
    a : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Lower bound of the interval.
        If ``a>b``, `a` and `b` will automatically be flipped.
        If ``a==b``, all generated values will be identical to `a`.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Uniform.draw_sample` or
        :func:`Uniform.draw_samples`.

    b : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Upper bound of the interval. Analogous to `a`.


    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Uniform(0, 10.0)
    >>> sample = param.draw_sample()
    >>> assert 0 <= sample < 10.0

    Create and sample from a uniform distribution over ``[0, 10.0)``.

    c                    r  r  )r   r.   r   r8   rm   rn   r  r   r   r   r   a  r  zUniform.__init__c                 C   s`   | j j|d}| jj|d}||kr||}}n||kr%tj||tjdS ||||tjS )Nr   r  )rm   r   rn   ra   r   r   uniformri   r  r   r   r   r   h  s   zUniform._draw_samplesc                 C   r   rl   r   r   r   r   r   r   r  r   zUniform.__repr__c                 C   r  )NzUniform(%s, %s)r  r   r   r   r   r   u  r  zUniform.__str__r   r   r   r   r   r.   =  s    #
r.   c                       :   e Zd ZdZd fdd	Zdd Zdd Zd	d
 Z  ZS )Betaa  Parameter that resembles a (continuous) beta distribution.

    Parameters
    ----------
    alpha : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        alpha parameter of the beta distribution.
        Expected value range is ``(0, inf)``. Values below ``0`` are
        automatically clipped to ``0+epsilon``.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Beta.draw_sample` or
        :func:`Beta.draw_samples`.

    beta : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Beta parameter of the beta distribution. Analogous to `alpha`.

    epsilon : number
        Clipping parameter. If `alpha` or `beta` end up ``<=0``, they are clipped to ``0+epsilon``.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Beta(0.4, 0.6)

    Create a beta distribution with ``alpha=0.4`` and ``beta=0.6``.

    r5  c                    sL   t t|   t|d| _t|d| _t|s!J dt|f || _	d S )Nr   betaz*Expected epsilon to a number, got type %s.)
r   r8  r   r8   r   r9  r   r   r%   epsilon)r   r   r9  r:  r   r   r   r     s   
zBeta.__init__c                 C   sL   | j j|d}| jj|d}t|| j}t|| j}|j|||dtjS )Nr   r!  )r   r   r9  r   r:  ri   ra   r   )r   rr   r   r   r9  r   r   r   r     s
   zBeta._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zBeta.__repr__c                 C   r  )NzBeta(%s, %s))r   r9  r   r   r   r   r     r  zBeta.__str__)r5  r   r   r   r   r   r8  y  s    #
r8  c                       s>   e Zd ZdZ		d fdd	Zdd Zd	d
 Zdd Z  ZS )FromLowerResolutiona}  Parameter to sample from other parameters at lower image resolutions.

    This parameter is intended to be used with parameters that would usually
    sample one value per pixel (or one value per pixel and channel). Instead
    of sampling from the other parameter at full resolution, it samples at
    lower resolution, e.g. ``0.5*H x 0.5*W`` with ``H`` being the height and
    ``W`` being the width. After the low-resolution sampling this parameter
    then upscales the result to ``HxW``.

    This parameter is intended to produce coarse samples. E.g. combining
    this with :class:`Binomial` can lead to large rectangular areas of
    ``1`` s and ``0`` s.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        The other parameter which is to be sampled on a coarser image.

    size_percent : None or number or iterable of number or imgaug.parameters.StochasticParameter, optional
        Size of the 2d sampling plane in percent of the requested size.
        I.e. this is relative to the size provided in the call to
        ``draw_samples(size)``. Lower values will result in smaller sampling
        planes, which are then upsampled to `size`. This means that lower
        values will result in larger rectangles. The size may be provided as
        a constant value or a tuple ``(a, b)``, which will automatically be
        converted to the continuous uniform range ``[a, b)`` or a
        :class:`StochasticParameter`, which will be queried per call to
        :func:`FromLowerResolution.draw_sample` and
        :func:`FromLowerResolution.draw_samples`.

    size_px : None or number or iterable of numbers or imgaug.parameters.StochasticParameter, optional
        Size of the 2d sampling plane in pixels.
        Lower values will result in smaller sampling planes, which are then
        upsampled to the input `size` of ``draw_samples(size)``.
        This means that lower values will result in larger rectangles.
        The size may be provided as a constant value or a tuple ``(a, b)``,
        which will automatically be converted to the discrete uniform
        range ``[a..b]`` or a :class:`StochasticParameter`, which will be
        queried once per call to :func:`FromLowerResolution.draw_sample` and
        :func:`FromLowerResolution.draw_samples`.

    method : str or int or imgaug.parameters.StochasticParameter, optional
        Upsampling/interpolation method to use. This is used after the sampling
        is finished and the low resolution plane has to be upsampled to the
        requested `size` in ``draw_samples(size, ...)``. The method may be
        the same as in :func:`~imgaug.imgaug.imresize_many_images`. Usually
        ``nearest`` or ``linear`` are good choices. ``nearest`` will result
        in rectangles with sharp edges and ``linear`` in rectangles with
        blurry and round edges. The method may be provided as a
        :class:`StochasticParameter`, which will be queried once per call to
        :func:`FromLowerResolution.draw_sample` and
        :func:`FromLowerResolution.draw_samples`.

    min_size : int, optional
        Minimum size in pixels of the low resolution sampling plane.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.FromLowerResolution(
    >>>     Binomial(0.05),
    >>>     size_px=(2, 16),
    >>>     method=Choice(["nearest", "linear"]))

    Samples from a binomial distribution with ``p=0.05``. The sampling plane
    will always have a size HxWxC with H and W being independently sampled
    from ``[2..16]`` (i.e. it may range from ``2x2xC`` up to ``16x16xC`` max,
    but may also be e.g. ``4x8xC``). The upsampling method will be ``nearest``
    in ``50%`` of all cases and ``linear`` in the other 50 percent. The result
    will sometimes be rectangular patches of sharp ``1`` s surrounded by
    ``0`` s and sometimes blurry blobs of ``1``s, surrounded by values
    ``<1.0``.

    Nnearestr   c                    s  t t|   |d us|d usJ d|d urYd| _d | _t|r(t|| _nst	|rGt
|dks<J dt
|f t|d |d | _nTt|trP|| _nKtdt|f d| _d | _t|rjt|| _n1t	|rt
|dks~J d	t
|f t|d |d | _nt|tr|| _n	td
t|f || _t|st|rt|| _nt|tr|| _n	tdt|f || _d S )NzPExpected either 'size_percent' or 'size_px' to be provided, got neither of them.percentr   zEExpected iterable 'size_percent' to contain exactly 2 values, got %d.r   r   z^Expected int, float, tuple of two ints/floats or StochasticParameter for size_percent, got %s.Zpxz@Expected iterable 'size_px' to contain exactly 2 values, got %d.zYExpected int, float, tuple of two ints/floats or StochasticParameter for size_px, got %s.z/Expected string or StochasticParameter, got %s.)r   r;  r   size_methodsize_pxr   r   r,   size_percentr/   r   r.   r   r1   r   r%   r;   rE   other_paramrJ   methodmin_size)r   rA  r@  r?  rB  rC  r   r   r   r      sd   







zFromLowerResolution.__init__c                 C   s  t |dkrd}|\}}}nt |dkr|\}}}}n	tdt|f | jdkrA| jj|df|d}|t||g tj	}n
| j
j|df|d}| jj|f|d}	d }
tt||	D ]\}\}}t|d | j}t|d | j}| jjd|||f|d}|jjd	krt|tj}n;|jjd
kr|dkrt|tj	}n)t|tj}n!|jjdksJ d|jj |dkrt|tj}nt|tj}tj|||f|d}|
d u rtj||||f|jd}
||
|< q]t |dkr|
d S |
S )Nr   r      zcFromLowerResolution can only generate samples of shape (H, W, C) or (N, H, W, C), requested was %s.r=  r   r   r   rf   r   r<  r   z\FromLowerResolution can only process outputs of kind f (float), i (int) or u (uint), got %s.interpolationr  )r   r   r   r>  r@  r   ra   r   ri   r   r?  rB  r  r{   r   rC  rA  rg   rh   iadtZrestore_dtypes_r   Zuint16r   r|   zeros)r   rr   r   nhwcZhw_percentsZhw_pxsmethodsresultr   Zhw_pxrB  h_smallw_smallr   Zsamples_upscaledr   r   r   r   7  s^   


z!FromLowerResolution._draw_samplesc                 C   r   rl   r   r   r   r   r   r   w  r   zFromLowerResolution.__repr__c                 C   s:   | j dkrd}|| j| j| jf S d}|| j| j| jf S )Nr=  z?FromLowerResolution(size_percent=%s, method=%s, other_param=%s)z:FromLowerResolution(size_px=%s, method=%s, other_param=%s))r>  r@  rB  rA  r?  )r   patternr   r   r   r   z  s   
zFromLowerResolution.__str__)NNr<  r   r   r   r   r   r   r;    s    J7@r;  c                       r7  )Clipa  Clip another parameter to a defined value range.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        The other parameter, which's values are to be clipped.

    minval : None or number, optional
        The minimum value to use.
        If ``None``, no minimum will be used.

    maxval : None or number, optional
        The maximum value to use.
        If ``None``, no maximum will be used.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Clip(Normal(0, 1.0), minval=-2.0, maxval=2.0)

    Create a standard gaussian distribution, which's values never go below
    ``-2.0`` or above ``2.0``. Note that this will lead to small "bumps" of
    higher probability at ``-2.0`` and ``2.0``, as values below/above these
    will be clipped to them. For smoother limitations on gaussian
    distributions, see :class:`TruncatedNormal`.

    Nc                    sv   t t|   td| |d u st|sJ dt|f |d u s0t|s0J dt|f || _|| _|| _	d S )NrA  z6Expected 'minval' to be None or a number, got type %s.z6Expected 'maxval' to be None or a number, got type %s.)
r   rR  r   _assert_arg_is_stoch_paramr   r   r%   rA  minvalmaxval)r   rA  rT  rU  r   r   r   r     s   

zClip.__init__c                 C   s>   | j j||d}| jd us| jd urtj|| j| j|d}|S )Nr   )out)rA  r   rT  rU  ra   clipr   r   r   r   r     s   zClip._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zClip.__repr__c                 C   sz   t | j}| jd ur| jd urd|t| jt| jf S | jd ur*d|t| jf S | jd ur8d|t| jf S d|f S )NzClip(%s, %.6f, %.6f)zClip(%s, %.6f, None)zClip(%s, None, %.6f)zClip(%s, None, None))r   rA  rT  rU  floatr   Zopstrr   r   r   r     s   



zClip.__str__)NNr   r   r   r   r   rR    s    rR  c                       r7  )r   a{  Convert a continuous distribution to a discrete one.

    This will round the values and then cast them to integers.
    Values sampled from already discrete distributions are not changed.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        The other parameter, which's values are to be discretized.

    round : bool, optional
        Whether to round before converting to integer dtype.

        Added in 0.4.0.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Discretize(iap.Normal(0, 1.0))

    Create a discrete standard gaussian distribution.

    Tc                    s(   t t|   td| || _|| _d S NrA  )r   r   r   rS  rA  rb   )r   rA  rb   r   r   r   r     s   

zDiscretize.__init__c                 C   s   | j j||d}|jjdv sJ d|jj|jjf |jjdv r"|S d|jj d }t|d}td|f }| jr?t|}|	|S )Nr   )r   r   rn   rf   zrExpected to get uint, int, bool or float dtype as samples in Discretize(), but got dtype '%s' (kind '%s') instead.)r   r   rn   r   r   zint%d)
rA  r   rg   rh   r   r  r   ra   rb   ri   )r   rr   r   r   Zbitsizerg   r   r   r   r     s   


zDiscretize._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zDiscretize.__repr__c                 C   s   t | j}d|t | jf S )NzDiscretize(%s, round=%s))r   rA  rb   rY  r   r   r   r     s   
zDiscretize.__str__)Tr   r   r   r   r   r     s    r   c                       r7  )r   a  Multiply the samples of another stochastic parameter.

    Parameters
    ----------
    other_param : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be multiplied with `val`.
        Let ``S`` be the requested shape of samples, then the datatype
        behaviour is as follows:

            * If a single ``number``, this ``number`` will be used as a
              constant value to fill an array of shape ``S``.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, an array of
              shape ``S`` will be filled with uniformly sampled values from
              the continuous interval ``[a, b)``.
            * If a ``list`` of ``number``, an array of shape ``S`` will be
              filled with randomly picked values from the ``list``.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call to generate an array of shape ``S``.

        "per call" denotes a call of :func:`Multiply.draw_sample` or
        :func:`Multiply.draw_samples`.

    val : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Multiplier to use.
        Datatype behaviour is analogous to `other_param`, though if
        ``elementwise=False`` (the default), only a single sample will be
        generated per call instead of ``S``.

    elementwise : bool, optional
        Controls the sampling behaviour of `val`.
        If set to ``False``, a single samples will be requested from `val` and
        used as the constant multiplier.
        If set to ``True``, samples of shape ``S`` will be requested from
        `val` and multiplied elementwise with the samples of `other_param`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Multiply(iap.Uniform(0.0, 1.0), -1)

    Convert a uniform distribution from ``[0.0, 1.0)`` to ``(-1.0, 0.0]``.

    Fc                    0   t t|   t|d| _t|d| _|| _d S NrA  rL   )r   r   r   r8   rA  rL   elementwiser   rA  rL   r]  r   r   r   r   5     
zMultiply.__init__c                 C   sv   | d}| jj||d d}| jot| jt }|r&| jj||d d}n	| jj|d d}|r7t	||S || S Nr   r   r   r   )
r   rA  r   r]  r   rL   r,   r   ra   multiplyr   rr   r   r  r   r]  val_samplesr   r   r   r   <  s   
zMultiply._draw_samplesc                 C   r   rl   r   r   r   r   r   r   M  r   zMultiply.__repr__c                 C      dt | jt | j| jf S )NzMultiply(%s, %s, %s)r   rA  rL   r]  r   r   r   r   r   P     zMultiply.__str__Fr   r   r   r   r   r   	  s    +r   c                       r7  )r   a  Divide the samples of another stochastic parameter.

    This parameter will automatically prevent division by zero (uses 1.0)
    as the denominator in these cases.

    Parameters
    ----------
    other_param : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be divided by `val`.
        Let ``S`` be the requested shape of samples, then the datatype
        behaviour is as follows:

            * If a single ``number``, this ``number`` will be used as a
              constant value to fill an array of shape ``S``.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, an array of
              shape ``S`` will be filled with uniformly sampled values from
              the continuous interval ``[a, b)``.
            * If a ``list`` of ``number``, an array of shape ``S`` will be
              filled with randomly picked values from the ``list``.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call to generate an array of shape ``S``.

        "per call" denotes a call of :func:`Divide.draw_sample` or
        :func:`Divide.draw_samples`.

    val : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Denominator to use.
        Datatype behaviour is analogous to `other_param`, though if
        ``elementwise=False`` (the default), only a single sample will be
        generated per call instead of ``S``.

    elementwise : bool, optional
        Controls the sampling behaviour of `val`.
        If set to ``False``, a single samples will be requested from `val` and
        used as the constant denominator.
        If set to ``True``, samples of shape ``S`` will be requested from
        `val` and used to divide the samples of `other_param` elementwise.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Divide(iap.Uniform(0.0, 1.0), 2)

    Convert a uniform distribution ``[0.0, 1.0)`` to ``[0, 0.5)``.

    Fc                    r[  r\  )r   r   r   r8   rA  rL   r]  r^  r   r   r   r     r_  zDivide.__init__c                 C   s   | d}| jj||d d}| jot| jt }|r5| jj||d d}d||dk< tt	|t	|S | jj
|d d}|dkrDd}t	|t| S r`  )r   rA  r   r]  r   rL   r,   ra   dividerk   r   rX  )r   rr   r   r  r   r]  rc  Z
val_sampler   r   r   r     s    
zDivide._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zDivide.__repr__c                 C   rd  )NzDivide(%s, %s, %s)re  r   r   r   r   r     rf  zDivide.__str__rg  r   r   r   r   r   r   U  s    /r   c                       r7  )r   a  Add to the samples of another stochastic parameter.

    Parameters
    ----------
    other_param : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Samples of `val` will be added to samples of this parameter.
        Let ``S`` be the requested shape of samples, then the datatype
        behaviour is as follows:

            * If a single ``number``, this ``number`` will be used as a
              constant value to fill an array of shape ``S``.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, an array of
              shape ``S`` will be filled with uniformly sampled values from
              the continuous interval ``[a, b)``.
            * If a ``list`` of ``number``, an array of shape ``S`` will be
              filled with randomly picked values from the ``list``.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call to generate an array of shape ``S``.

        "per call" denotes a call of :func:`Add.draw_sample` or
        :func:`Add.draw_samples`.

    val : number or tuple of two number or list of number or imgaug.parameters.StochasticParameter
        Value to add to the samples of `other_param`.
        Datatype behaviour is analogous to `other_param`, though if
        ``elementwise=False`` (the default), only a single sample will be
        generated per call instead of ``S``.

    elementwise : bool, optional
        Controls the sampling behaviour of `val`.
        If set to ``False``, a single samples will be requested from `val` and
        used as the constant multiplier.
        If set to ``True``, samples of shape ``S`` will be requested from
        `val` and added elementwise with the samples of `other_param`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Add(Uniform(0.0, 1.0), 1.0)

    Convert a uniform distribution from ``[0.0, 1.0)`` to ``[1.0, 2.0)``.

    Fc                    r[  r\  )r   r   r   r8   rA  rL   r]  r^  r   r   r   r     r_  zAdd.__init__c                 C   sv   | d}| jj||d d}| jot| jt }|r&| jj||d d}n	| jj|d d}|r7t	||S || S r`  )
r   rA  r   r]  r   rL   r,   r   ra   addrb  r   r   r   r     s   
zAdd._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zAdd.__repr__c                 C   rd  )NzAdd(%s, %s, %s)re  r   r   r   r   r     rf  zAdd.__str__rg  r   r   r   r   r   r     s    ,r   c                       r7  )r   a  Subtract from the samples of another stochastic parameter.

    Parameters
    ----------
    other_param : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Samples of `val` will be subtracted from samples of this parameter.
        Let ``S`` be the requested shape of samples, then the datatype
        behaviour is as follows:

            * If a single ``number``, this ``number`` will be used as a
              constant value to fill an array of shape ``S``.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, an array of
              shape ``S`` will be filled with uniformly sampled values from
              the continuous interval ``[a, b)``.
            * If a ``list`` of ``number``, an array of shape ``S`` will be
              filled with randomly picked values from the ``list``.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call to generate an array of shape ``S``.

        "per call" denotes a call of :func:`Subtract.draw_sample` or
        :func:`Subtract.draw_samples`.

    val : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Value to subtract from the other parameter.
        Datatype behaviour is analogous to `other_param`, though if
        ``elementwise=False`` (the default), only a single sample will be
        generated per call instead of ``S``.

    elementwise : bool, optional
        Controls the sampling behaviour of `val`.
        If set to ``False``, a single samples will be requested from `val` and
        used as the constant multiplier.
        If set to ``True``, samples of shape ``S`` will be requested from
        `val` and subtracted elementwise from the samples of `other_param`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Subtract(iap.Uniform(0.0, 1.0), 1.0)

    Convert a uniform distribution from ``[0.0, 1.0)`` to ``[-1.0, 0.0)``.

    Fc                    r[  r\  )r   r   r   r8   rA  rL   r]  r^  r   r   r   r   ,  r_  zSubtract.__init__c                 C   sv   | d}| jj||d d}| jot| jt }|r&| jj||d d}n	| jj|d d}|r7t	||S || S r`  )
r   rA  r   r]  r   rL   r,   r   ra   subtractrb  r   r   r   r   3  s   
zSubtract._draw_samplesc                 C   r   rl   r   r   r   r   r   r   C  r   zSubtract.__repr__c                 C   rd  )NzSubtract(%s, %s, %s)re  r   r   r   r   r   F  rf  zSubtract.__str__rg  r   r   r   r   r   r      s    +r   c                       r7  )r   a  Exponentiate the samples of another stochastic parameter.

    Parameters
    ----------
    other_param : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be exponentiated by `val`.
        Let ``S`` be the requested shape of samples, then the datatype
        behaviour is as follows:

            * If a single ``number``, this ``number`` will be used as a
              constant value to fill an array of shape ``S``.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, an array of
              shape ``S`` will be filled with uniformly sampled values from
              the continuous interval ``[a, b)``.
            * If a ``list`` of ``number``, an array of shape ``S`` will be
              filled with randomly picked values from the ``list``.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call to generate an array of shape ``S``.

        "per call" denotes a call of :func:`Power.draw_sample` or
        :func:`Power.draw_samples`.

    val : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Value to use exponentiate the samples of `other_param`.
        Datatype behaviour is analogous to `other_param`, though if
        ``elementwise=False`` (the default), only a single sample will be
        generated per call instead of ``S``.

    elementwise : bool, optional
        Controls the sampling behaviour of `val`.
        If set to ``False``, a single samples will be requested from `val` and
        used as the constant multiplier.
        If set to ``True``, samples of shape ``S`` will be requested from
        `val` and used to exponentiate elementwise the samples of `other_param`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Power(iap.Uniform(0.0, 1.0), 2)

    Converts a uniform range ``[0.0, 1.0)`` to a distribution that is peaked
    towards 1.0.

    Fc                    r[  r\  )r   r   r   r8   rA  rL   r]  r^  r   r   r   r   x  r_  zPower.__init__c           	      C   s   | d}| jj||d d}| jot| jt }|r&| jj||d d}n	| jj|d d}t||\}}|j	}t
|t
j|j}|j	|krN||}|S r`  )r   rA  r   r]  r   rL   r,   r   ro   rg   ra   powerri   complexreal)	r   rr   r   r  r   r]  Z	exponentsZsamples_dtyperN  r   r   r   r     s   


zPower._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zPower.__repr__c                 C   rd  )NzPower(%s, %s, %s)re  r   r   r   r   r     rf  zPower.__str__rg  r   r   r   r   r   r   K  s    ,r   c                       r   )
Absolutea  Convert the samples of another parameter to their absolute values.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be modified.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Absolute(iap.Uniform(-1.0, 1.0))

    Convert a uniform distribution from ``[-1.0, 1.0)`` to ``[0.0, 1.0]``.

    c                    s"   t t|   td| || _d S rZ  )r   rn  r   rS  rA  )r   rA  r   r   r   r     s   

zAbsolute.__init__c                 C   s   | j j||d}t|S )Nr   )rA  r   ra   absoluter   r   r   r   r     s   
zAbsolute._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zAbsolute.__repr__c                 C   s   t | j}d|f S )NzAbsolute(%s))r   rA  rY  r   r   r   r     s   

zAbsolute.__str__r   r   r   r   r   rn    s    rn  c                       r7  )
RandomSigna,  Convert a parameter's samples randomly to positive or negative values.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be modified.

    p_positive : number
        Fraction of values that are supposed to be turned to positive values.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.RandomSign(iap.Poisson(1))

    Create a poisson distribution with ``alpha=1`` that is mirrored/copied (not
    flipped) at the y-axis.

          ?c                    sf   t t|   td| t|sJ dt| d|  kr#dks+n J d|f || _|| _d S )NrA  z-Expected 'p_positive' to be a number, got %s.rZ   r[   zAExpected 'p_positive' to be in the interval [0.0, 1.0], got %.4f.)	r   rp  r   rS  r   r   r%   rA  
p_positive)r   rA  rr  r   r   r   r     s   

zRandomSign.__init__c                 C   s~   | d}| jj||d d}|jjdv s!J d|jj|jjf |d jd| j|dt	j
}|d d }t	|| }|S )Nr   r   r   )rf   r   zJExpected to get samples of kind float or int, but got dtype %s of kind %s.r   r!  )r   rA  r   rg   rh   r   r  rr  ri   ra   Zint8ro  )r   rr   r   Zrssr   Z	coinflipsZsignsrN  r   r   r   r     s   
zRandomSign._draw_samplesc                 C   r   rl   r   r   r   r   r   r     r   zRandomSign.__repr__c                 C   s   t | j}d|| jf S )NzRandomSign(%s, %.2f))r   rA  rr  rY  r   r   r   r   	  s   
zRandomSign.__str__)rq  r   r   r   r   r   rp    s    rp  c                       s>   e Zd ZdZ		d fdd	Zdd Zdd	 Zd
d Z  ZS )	ForceSigna  Convert a parameter's samples to either positive or negative values.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be modified.

    positive : bool
        Whether to force all signs to be positive (``True``) or
        negative (``False``).

    mode : {'invert', 'reroll'}, optional
        Method to change the signs. Valid values are ``invert`` and ``reroll``.
        ``invert`` means that wrong signs are simply flipped.
        ``reroll`` means that all samples with wrong signs are sampled again,
        optionally many times, until they randomly end up having the correct
        sign.

    reroll_count_max : int, optional
        If `mode` is set to ``reroll``, this determines how often values may
        be rerolled before giving up and simply flipping the sign (as in
        ``mode="invert"``). This shouldn't be set too high, as rerolling is
        expensive.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.ForceSign(iap.Poisson(1), positive=False)

    Create a poisson distribution with ``alpha=1`` that is flipped towards
    negative values.

    invertr   c                    s~   t t|   td| || _|dv sJ dt|f || _|dv s*J d|f || _t	|s:J dt| || _
d S )NrA  )TFz5Expected 'positive' to be True or False, got type %s.)rt  Zrerollz3Expected 'mode' to be "invert" or "reroll", got %s.z:Expected 'reroll_count_max' to be an integer, got type %s.)r   rs  r   rS  rA  r%   positivemoder   r;   reroll_count_max)r   rA  ru  rv  rw  r   r   r   r   )	  s&   



zForceSign.__init__c                 C   s8  | d| j }| jj||d d}| jdkr2| jr&||dk   d9  < |S ||dk  d9  < |S | jr?t|dk d }n	t|dkd }d}t|dkr|| jk r| jj||d|  d}|| ||< |d7 }| jrxt|dk d }n	t|dkd }t|dkr|| jk sUt|dkr||  d9  < |S )Nr   r   r   rt  r   )	r   rw  rA  r   rv  ru  ra   wherer   )r   rr   r   r  r   Zbad_samplesZreroll_countZsamples_rerollr   r   r   r   >	  s4   
 
zForceSign._draw_samplesc                 C   r   rl   r   r   r   r   r   r   f	  r   zForceSign.__repr__c                 C   s$   t | j}d|t | j| j| jf S )NzForceSign(%s, %s, %s, %d))r   rA  ru  rv  rw  rY  r   r   r   r   i	     
zForceSign.__str__rt  r   r   r   r   r   r   rs  	  s    "(rs  rt  r   c                 C      t | d||dS )a  Convert another parameter's results to positive values.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be
        modified.

    mode : {'invert', 'reroll'}, optional
        How to change the signs. Valid values are ``invert`` and ``reroll``.
        ``invert`` means that wrong signs are simply flipped.
        ``reroll`` means that all samples with wrong signs are sampled again,
        optionally many times, until they randomly end up having the correct
        sign.

    reroll_count_max : int, optional
        If `mode` is set to ``reroll``, this determines how often values may
        be rerolled before giving up and simply flipping the sign (as in
        ``mode="invert"``). This shouldn't be set too high, as rerolling is
        expensive.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Positive(iap.Normal(0, 1), mode="reroll")

    Create a gaussian distribution that has only positive values.
    If any negative value is sampled in the process, that sample is resampled
    up to two times to get a positive one. If it isn't positive after the
    second resampling step, the sign is simply flipped.

    TrA  ru  rv  rw  rs  rA  rv  rw  r   r   r   Positiveo	     "r  c                 C   r{  )a  Convert another parameter's results to negative values.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        Other parameter which's sampled values are to be
        modified.

    mode : {'invert', 'reroll'}, optional
        How to change the signs. Valid values are ``invert`` and ``reroll``.
        ``invert`` means that wrong signs are simply flipped.
        ``reroll`` means that all samples with wrong signs are sampled again,
        optionally many times, until they randomly end up having the correct
        sign.

    reroll_count_max : int, optional
        If `mode` is set to ``reroll``, this determines how often values may
        be rerolled before giving up and simply flipping the sign (as in
        ``mode="invert"``). This shouldn't be set too high, as rerolling is
        expensive.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Negative(iap.Normal(0, 1), mode="reroll")

    Create a gaussian distribution that has only negative values.
    If any positive value is sampled in the process, that sample is resampled
    up to two times to get a negative one. If it isn't negative after the
    second resampling step, the sign is simply flipped.

    Fr|  r}  r~  r   r   r   Negative	  r  r  c                       sB   e Zd ZdZdddgf fdd	Zdd Zd	d
 Zdd Z  ZS )IterativeNoiseAggregatora  Aggregate multiple iterations of samples from another parameter.

    This is supposed to be used in conjunction with :class:`SimplexNoise` or
    :class:`FrequencyNoise`. If a shape ``S`` is requested, it will request
    ``I`` times ``S`` samples from the underlying parameter, where ``I`` is
    the number of iterations. The ``I`` arrays will be combined to a single
    array of shape ``S`` using an aggregation method, e.g. simple averaging.

    Parameters
    ----------
    other_param : StochasticParameter
        The other parameter from which to sample one or more times.

    iterations : int or iterable of int or list of int or imgaug.parameters.StochasticParameter, optional
        The number of iterations.

            * If a single ``int``, this ``int`` will be used as a
              constant value.
            * If a ``tuple`` of two ``int`` s ``(a, b)``, the value will be
              sampled from the discrete interval ``[a..b]`` once per call.
            * If a ``list`` of ``int``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of
        :func:`IterativeNoiseAggregator.draw_sample` or
        :func:`IterativeNoiseAggregator.draw_samples`.

    aggregation_method : imgaug.ALL or {'min', 'avg', 'max'} or list of str or imgaug.parameters.StochasticParameter, optional
        The method to use to aggregate the samples of multiple iterations
        to a single output array. All methods combine several arrays of
        shape ``S`` each to a single array of shape ``S`` and hence work
        elementwise. Known methods are ``min`` (take the minimum over all
        iterations), ``max`` (take the maximum) and ``avg`` (take the average).

            * If an ``str``, it must be one of the described methods and
              will be used for all calls..
            * If a ``list`` of ``str``, it must contain one or more of the
              described methods and a random one will be samples once per call.
            * If ``imgaug.ALL``, then equivalent to the ``list``
              ``["min", "max", "avg"]``.
            * If :class:`StochasticParameter`, a value will be sampled from
              that parameter once per call and must be one of the described
              methods..

        "per call" denotes a call of
        :func:`IterativeNoiseAggregator.draw_sample` or
        :func:`IterativeNoiseAggregator.draw_samples`.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> noise = iap.IterativeNoiseAggregator(
    >>>     iap.SimplexNoise(),
    >>>     iterations=(2, 5),
    >>>     aggregation_method="max")

    Create a parameter that -- upon each call -- generates ``2`` to ``5``
    arrays of simplex noise with the same shape. Then it combines these
    noise maps to a single map using elementwise maximum.

    )r   r   r   avgc                    s  t t|   td| || _dd }t|r#||g t|| _nkt	|t
rAt|dks7J dt|f || t|| _nMt|r|t|dksUJ dt|f tdd	 |D smJ d
ddd	 |D f || t|d |d | _nt	|tr|| _n	tdt|f |tjkrtg d| _d S t|rt|| _d S t	|t
rt|dksJ dt|f tdd	 |D sJ dddd	 |D  t|| _d S t	|tr|| _d S tdt|f )NrA  c                 S   s4   t dd | D sJ dddd | D f d S )Nc                 S   r\   r   i'  r   rK   r   r   r   r!   
  r^   zTIterativeNoiseAggregator.__init__.<locals>._assert_within_bounds.<locals>.<listcomp>zZExpected 'iterations' to only contain values within the interval [1, 1000], got values %s.rH   c                 S   r#   r   )r   rK   r   r   r   r!   
  r&   )r-   rR   )Z_iterationsr   r   r   _assert_within_bounds
  s   z@IterativeNoiseAggregator.__init__.<locals>._assert_within_boundsr   zIExpected 'iterations' of type list to contain at least one entry, got %d.r   zNExpected iterable non-list 'iteratons' to contain exactly two entries, got %d.c                 S   r   r   rU   rK   r   r   r   r!   !
  r"   z5IterativeNoiseAggregator.__init__.<locals>.<listcomp>zOExpected iterable non-list 'iterations' to only contain integers, got types %s.rH   c                 S      g | ]}t t|qS r   r   r%   rK   r   r   r   r!   $
      r   zRExpected iterations to be int or tuple of two ints or StochasticParameter, got %s.)r   r   r  z0Expected at least one aggregation method got %d.c                 S   r   r   rI   rK   r   r   r   r!   6
  r"   z?Expected aggregation methods provided as strings, got types %s.c                 S   r  r   r  r   r   r   r   r!   9
  r  z[Expected aggregation_method to be string or list of strings or StochasticParameter, got %s.)r   r  r   rS  rA  r   r;   r,   
iterationsr   rQ   r   r0   r/   r-   rR   rE   r1   r   r%   rP   aggregation_methodrJ   )r   rA  r  r  r  r   r   r   r   
  sx   










z!IterativeNoiseAggregator.__init__c           
      C   s   | d}| jj|d d}| jj|d d}|dks"J d|f |d  |}tj|tjd}t|D ]4}| j	j
||| d}	|dkrK||	7 }q6|dkr]|dkrV|	}q6t||	}q6|dkrd|	}q6t||	}q6|dkrs|| }|S )	Nr   r   r   r   zAExpected to sample at least one iteration of aggregation. Got %d.r  r  r   )r   r  r   r  ra   rH  r   r   r   rA  r   minimummaximum)
r   rr   r   r  r  r  Zrngs_iterationsrN  r   
noise_iterr   r   r   r   C
  s8   


z&IterativeNoiseAggregator._draw_samplesc                 C   r   rl   r   r   r   r   r   r   e
  r   z!IterativeNoiseAggregator.__repr__c                 C   s$   t | j}d|t | jt | jf S )Nz$IterativeNoiseAggregator(%s, %s, %s))r   rA  r  r  rY  r   r   r   r   h
  ry  z IterativeNoiseAggregator.__str__r   r   r   r   r   r  	  s    @<"r  c                       sL   e Zd ZdZ		d fdd	Zeddd	Zd
d Zdd Zdd Z	  Z
S )Sigmoida	  Apply a sigmoid function to the outputs of another parameter.

    This is intended to be used in combination with :class:`SimplexNoise` or
    :class:`FrequencyNoise`. It pushes the noise values away from ``~0.5`` and
    towards ``0.0`` or ``1.0``, making the noise maps more binary.

    Parameters
    ----------
    other_param : imgaug.parameters.StochasticParameter
        The other parameter to which the sigmoid will be applied.

    threshold : number or tuple of number or iterable of number or imgaug.parameters.StochasticParameter, optional
        Sets the value of the sigmoid's saddle point, i.e. where values
        start to quickly shift from ``0.0`` to ``1.0``.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`Sigmoid.draw_sample` or
        :func:`Sigmoid.draw_samples`.

    activated : bool or number, optional
        Defines whether the sigmoid is activated. If this is ``False``, the
        results of `other_param` will not be altered. This may be set to a
        ``float`` ``p`` in value range``[0.0, 1.0]``, which will result in
        `activated` being ``True`` in ``p`` percent of all calls.

    mul : number, optional
        The results of `other_param` will be multiplied with this value before
        applying the sigmoid. For noise values (range ``[0.0, 1.0]``) this
        should be set to about ``20``.

    add : number, optional
        This value will be added to the results of `other_param` before
        applying the sigmoid. For noise values (range ``[0.0, 1.0]``) this
        should be set to about ``-10.0``, provided `mul` was set to ``20``.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.Sigmoid(
    >>>     iap.SimplexNoise(),
    >>>     activated=0.5,
    >>>     mul=20,
    >>>     add=-10)

    Applies a sigmoid to simplex noise in ``50%`` of all calls. The noise
    results are modified to match the sigmoid's expected value range. The
    sigmoid's outputs are in the range ``[0.0, 1.0]``.

    
   Tr   r   c                    s   t t|   td| || _t|d| _t|d| _t	
|s)J dt|f |dks4J d|f || _t	
|sEJ dt|f || _d S )NrA  	threshold	activatedz+Expected 'mul' to be a number, got type %s.r   z1Expected 'mul' to be greater than zero, got %.4f.z+Expected 'add' to be a number, got type %s.)r   r  r   rS  rA  r8   r  re   r  r   r   r%   mulri  )r   rA  r  r  r  ri  r   r   r   r   
  s    


zSigmoid.__init__c                 C   s   t | ||dddS )a  Create a Sigmoid adjusted for noise parameters.

        "noise" here denotes :class:`SimplexNoise` and :class:`FrequencyNoise`.

        Parameters
        ----------
        other_param : imgaug.parameters.StochasticParameter
            See :func:`~imgaug.parameters.Sigmoid.__init__`.

        threshold : number or tuple of number or iterable of number or imgaug.parameters.StochasticParameter, optional
            See :func:`~imgaug.parameters.Sigmoid.__init__`.

        activated : bool or number, optional
            See :func:`~imgaug.parameters.Sigmoid.__init__`.

        Returns
        -------
        Sigmoid
            A sigmoid adjusted to be used with noise.

           r  )r  ri  )r  )rA  r  r  r   r   r   create_for_noise
  s   zSigmoid.create_for_noisec                 C   s   | d}| jj||d d}|jjdkr|tj}| jj	|d d}| j
j	|d d}|dkrCddt|| j | j |    S |S )Nr   r   r   rf   r   r   rq  )r   rA  r   rg   rh   ri   ra   r   r  r   r  expr  ri  )r   rr   r   r  rN  r  r  r   r   r   r   
  s   
$zSigmoid._draw_samplesc                 C   r   rl   r   r   r   r   r   r   
  r   zSigmoid.__repr__c                 C   s4   t | j}d|t | jt | jt | jt | jf S )NzSigmoid(%s, %s, %s, %s, %s))r   rA  r  r  r  ri  rY  r   r   r   r   
  s
   
zSigmoid.__str__)r  Tr   r   )r  T)rM   r   r   r   r   staticmethodr  r   r   r   r   r   r   r   r   r  n
  s    :r  c                       sR   e Zd ZdZdddgf fdd	Zdd Zd	d
 Zdd Zdd Zdd Z	  Z
S )SimplexNoisea  Parameter that generates simplex noise of varying resolutions.

    This parameter expects to sample noise for 2d planes, i.e. for
    sizes ``(H, W, [C])`` and will return a value in the range ``[0.0, 1.0]``
    per spatial location in that plane.

    The noise is sampled from low resolution planes and
    upscaled to the requested height and width. The size of the low
    resolution plane may be defined (large values can be slow) and the
    interpolation method for upscaling can be set.

    Parameters
    ----------
    size_px_max : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Maximum height and width in pixels of the low resolution plane.
        Upon any sampling call, the requested shape will be downscaled until
        the height or width (whichever is larger) does not exceed this maximum
        value anymore. Then the noise will be sampled at that shape and later
        upscaled back to the requested shape.

            * If a single ``int``, this ``int`` will be used as a
              constant value.
            * If a ``tuple`` of two ``int`` s ``(a, b)``, the value will be
              sampled from the discrete interval ``[a..b]`` once per call.
            * If a ``list`` of ``int``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`SimplexNoise.draw_sample` or
        :func:`SimplexNoise.draw_samples`.

    upscale_method : str or int or list of str or list of int or imgaug.parameters.StochasticParameter, optional
        After generating the noise maps in low resolution environments, they
        have to be upscaled to the originally requested shape (i.e. usually
        the image size). This parameter controls the interpolation method to
        use. See also :func:`~imgaug.imgaug.imresize_many_images` for a
        description of possible values.

            * If ``imgaug.ALL``, then either ``nearest`` or ``linear`` or
              ``area`` or ``cubic`` is picked per iteration (all same
              probability).
            * If ``str``, then that value will always be used as the method
              (must be ``nearest`` or ``linear`` or ``area`` or ``cubic``).
            * If ``list`` of ``str``, then a random value will be picked from
              that list per call.
            * If :class:`StochasticParameter`, then a random value will be
              sampled from that parameter per call.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.SimplexNoise(upscale_method="linear")

    Create a parameter that produces smooth simplex noise of varying sizes.

    >>> param = iap.SimplexNoise(
    >>>     size_px_max=(8, 16),
    >>>     upscale_method="nearest")

    Create a parameter that produces rectangular simplex noise of rather
    high detail.

    )r      linearr<  c                    s   t t|   t|ddd| _|tjkrtg d| _d S t	|r)t
|| _d S t|tr[t|dks=J dt|f tdd |D sTJ d	d
dd |D  t|| _d S t|tre|| _d S tdt|f )Nsize_px_maxr  r  r<  r  ZareaZcubicr   -Expected at least one upscale method, got %d.c                 S   r   r   rI   rK   r   r   r   r!   C  r"   z)SimplexNoise.__init__.<locals>.<listcomp>9Expected all upscale methods to be strings, got types %s.rH   c                 S   r  r   r  r   r   r   r   r!   E  r  WExpected upscale_method to be string or list of strings or StochasticParameter, got %s.)r   r  r   rG   r  r   rP   r0   upscale_methodrJ   r,   r   rQ   r   r-   rR   r1   r   r%   )r   r  r  r   r   r   r   3  s6   




zSimplexNoise.__init__c                       t |dv sJ d|f |dd \ t |dkrdn|d } fddt|D }t |dkr:|d S tj|dd	S )
Nr   r   IExpected requested noise to have shape (H, W) or (H, W, C), got shape %s.r   r   r   c                       g | ]	}  qS r   _draw_samples_hwr   r   heightr   r   r   r   r   r!   U      z.SimplexNoise._draw_samples.<locals>.<listcomp>r   Zaxisr   ra   Zarangestackr   rr   r   Znb_channelsZchannelsr   r  r   r   N  s   zSimplexNoise._draw_samplesc                 C   s   d}| d| }d}| jj|f|d d}tj||ftjd}t|D ]8}	| |||d|	  ||	 }
|dkr>||
7 }q%|dkrP|	dkrI|
}q%t	||
}q%|	dkrW|
}q%t
||
}q%|dkrf|| }|S )Nr   r   r   r   r  r  r   )r   r  r   ra   rH  r   r   r   _draw_samples_iterationr  r  )r   r  r   r   r  r  r  Zupscale_methodsrN  r   r  r   r   r   r  \  s.   

zSimplexNoise._draw_samples_hwc                 C   s8  |  }tt|d}t||}| jj|d}||kr,|| }	t||	 }
t||	 }n|}
|}t|
d}
t|d}tj|
|ftjd}t	
|
D ]}t	
|D ]}|j||d|||f< qPqI|d d }t|dd}|j||fkr|d	 tj}t|d
tjf d}tj|||f|d}|d d tj}|S )N)r,  r   r   r  )yxr[   r   rZ      .r   r   r   rE  .r        o@)r)  r   rB   r   r  r   ra   rH  r   r   r   Znoise2drW  shaperi   uint8r   newaxisr   imresize_single_image)r   r  r   rngr  Zopensimplex_seed	generatormaxlenr  downscale_factorrO  rP  noiser  r  
noise_0to1noise_0to1_uint8noise_0to1_3dr   r   r   r  x  s:   



z$SimplexNoise._draw_samples_iterationc                 C   r   rl   r   r   r   r   r   r     r   zSimplexNoise.__repr__c                 C   s   dt | jt | jf S )NzSimplexNoise(%s, %s))r   r  r  r   r   r   r   r     s   zSimplexNoise.__str__)rM   r   r   r   r   r   r  r  r   r   r   r   r   r   r   r  
  s    A+r  c                       sX   e Zd ZdZddddgf fdd	Zdd	 Zd
d Zedd Zdd Z	dd Z
  ZS )FrequencyNoisea"  Parameter to generate noise of varying frequencies.

    This parameter expects to sample noise for 2d planes, i.e. for
    sizes ``(H, W, [C])`` and will return a value in the range ``[0.0, 1.0]``
    per spatial location in that plane.

    The exponent controls the frequencies and therefore noise patterns.
    Small values (around ``-4.0``) will result in large blobs. Large values
    (around ``4.0``) will result in small, repetitive patterns.

    The noise is sampled from low resolution planes and
    upscaled to the requested height and width. The size of the low
    resolution plane may be defined (high values can be slow) and the
    interpolation method for upscaling can be set.

    Parameters
    ----------
    exponent : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Exponent to use when scaling in the frequency domain.
        Sane values are in the range ``-4`` (large blobs) to ``4`` (small
        patterns). To generate cloud-like structures, use roughly ``-2``.

            * If a single ``number``, this ``number`` will be used as a
              constant value.
            * If a ``tuple`` of two ``number`` s ``(a, b)``, the value will be
              sampled from the continuous interval ``[a, b)`` once per call.
            * If a ``list`` of ``number``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

    size_px_max : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Maximum height and width in pixels of the low resolution plane.
        Upon any sampling call, the requested shape will be downscaled until
        the height or width (whichever is larger) does not exceed this maximum
        value anymore. Then the noise will be sampled at that shape and later
        upscaled back to the requested shape.

            * If a single ``int``, this ``int`` will be used as a
              constant value.
            * If a ``tuple`` of two ``int`` s ``(a, b)``, the value will be
              sampled from the discrete interval ``[a..b]`` once per call.
            * If a ``list`` of ``int``, a random value will be picked from
              the ``list`` once per call.
            * If a :class:`StochasticParameter`, that parameter will be
              queried once per call.

        "per call" denotes a call of :func:`FrequencyNoise.draw_sample` or
        :func:`FrequencyNoise.draw_samples`.

    upscale_method : imgaug.ALL or str or list of str or imgaug.parameters.StochasticParameter, optional
        After generating the noise maps in low resolution environments, they
        have to be upscaled to the originally requested shape (i.e. usually
        the image size). This parameter controls the interpolation method to
        use. See also :func:`~imgaug.imgaug.imresize_many_images` for a
        description of possible values.

            * If ``imgaug.ALL``, then either ``nearest`` or ``linear`` or
              ``area`` or ``cubic`` is picked per iteration (all same
              probability).
            * If ``str``, then that value will always be used as the method
              (must be ``nearest`` or ``linear`` or ``area`` or ``cubic``).
            * If ``list`` of ``str``, then a random value will be picked from
              that list per call.
            * If :class:`StochasticParameter`, then a random value will be
              sampled from that parameter per call.

    Examples
    --------
    >>> import imgaug.parameters as iap
    >>> param = iap.FrequencyNoise(
    >>>     exponent=-2,
    >>>     size_px_max=(16, 32),
    >>>     upscale_method="linear")

    Create a parameter that produces noise with cloud-like patterns.

    )rD  )rD  r   r  r<  c                    s   t t|   t|d| _t|ddd| _|tjkr#t	g d| _
d S t|r/t|| _
d S t|trat|dksCJ dt|f tdd	 |D sZJ d
ddd	 |D  t	|| _
d S t|trk|| _
d S tdt|f )Nexponentr  r  r  r  r   r  c                 S   r   r   rI   rK   r   r   r   r!     r"   z+FrequencyNoise.__init__.<locals>.<listcomp>r  rH   c                 S   r  r   r  r   r   r   r   r!     r  r  )r   r  r   r8   r  rG   r  r   rP   r0   r  rJ   r,   r   rQ   r   r-   rR   r1   r   r%   )r   r  r  r  r   r   r   r     s8   




zFrequencyNoise.__init__c                    r  )
Nr  r  r   r   r   c                    r  r   r  r  r  r   r   r!   %  r  z0FrequencyNoise._draw_samples.<locals>.<listcomp>r   r  r  r  r   r  r   r     s   zFrequencyNoise._draw_samplesc                 C   s  | d}t||}| jj|d d}||kr(|| }t|| }t|| }	n|}|}	t|d}t|	d}	|d j||	fd}
|d j||	fd}|
t||	d  }
|d tj }|
t| }
|
t	| }| j
j|d d}| ||	f}d|d	< || }d|d	< |
| }|| }tj|jtjd
}||_||_tj|j}t|}t|}|| ||  }| jj|d d}|j||fkr|d tj}t|dtjf d}tj|||f|d}|d d tj}|S )N   r   r   rD  r   r!  r   r   )r   r   r  r  .r  rE  r  r  )r   r   r  r   rB   r   ra   picossinr  _create_distance_matrixrH  r  rl  rm  imagZfftZifft2r   r  ri   r  r   r  r   r  r   )r   r  r   r   r  r  r  r  rO  rP  Zwn_rZwn_ar  rf   r  ZtrealZtimagZwn_freqs_mulZwn_invZ
wn_inv_minZ
wn_inv_maxr  r  r  r  r   r   r   r  ,  sX   





zFrequencyNoise._draw_samples_hwc                    s&   |\  fdd}t | fS )Nc                    s6   t |  |  }t || }t |d |d  S )Nr   )ra   r  sqrt)yyxxZhdistZwdistrJ  rK  r   r   _freqo  s   z5FrequencyNoise._create_distance_matrix.<locals>._freq)ra   Zfromfunction)clsrr   r  r   r  r   r  k  s   z&FrequencyNoise._create_distance_matrixc                 C   r   rl   r   r   r   r   r   r   v  r   zFrequencyNoise.__repr__c                 C   r  )NzFrequencyNoise(%s, %s, %s))r   r  r  r  r   r   r   r   r   y  s
   zFrequencyNoise.__str__)rM   r   r   r   r   r   r  classmethodr  r   r   r   r   r   r   r   r    s    O?

r  c                 C   s   t |tsJ d| |f d S )Nz7Expected '%s' to be a StochasticParameter, got type %s.rX   )Zarg_name	arg_valuer   r   r   rS    s
   rS  )NTT)NTTTrl   )rT   T)FF)NNrp   NNrz  )Kr   
__future__r   r   r   r   r   collectionsr   abcr   r   r   numpyra   sixZ	six.movesZmovesr   r*  Zscipy.statsr   r*   r	   r   r
   rG  r   r   Zexternal.opensimplexr   r   r8   rG   rS   rY   re   rk   ro   r   r   Zadd_metaclassobjectr1   r,   r   r0   rc   rE   r  r  r&  r.  r/  r4  r.   r8  r;  rR  r   r   r   r   r   r   rn  rp  rs  r  r  r  r  r  r  rS  r   r   r   r   <module>   s    )
%

7#
9
.

  7Cq2=6;Z=13<< UC=L_LKY#?
i
*- )  = T