def blend_alpha(image_fg, image_bg, alpha, eps=1e-2):
    """
    Blend two images using an alpha blending.

    In an alpha blending, the two images are naively mixed. Let ``A`` be the foreground image
    and ``B`` the background image and ``a`` is the alpha value. Each pixel intensity is then
    computed as ``a * A_ij + (1-a) * B_ij``.

    dtype support::

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

        - (1) Tests show that these dtypes work, but a conversion to float128 happens, which only
              has 96 bits of size instead of true 128 bits and hence not twice as much resolution.
              It is possible that these dtypes result in inaccuracies, though the tests did not
              indicate that.
        - (2) Not available due to the input dtype having to be increased to an equivalent float
              dtype with two times the input resolution.
        - (3) Mapped internally to ``float16``.

    Parameters
    ----------
    image_fg : (H,W,[C]) ndarray
        Foreground image. Shape and dtype kind must match the one of the
        background image.

    image_bg : (H,W,[C]) ndarray
        Background image. Shape and dtype kind must match the one of the
        foreground image.

    alpha : number or iterable of number or ndarray
        The blending factor, between 0.0 and 1.0. Can be interpreted as the opacity of the
        foreground image. Values around 1.0 result in only the foreground image being visible.
        Values around 0.0 result in only the background image being visible.
        Multiple alphas may be provided. In these cases, there must be exactly one alpha per
        channel in the foreground/background image. Alternatively, for ``(H,W,C)`` images,
        either one ``(H,W)`` array or an ``(H,W,C)`` array of alphas may be provided,
        denoting the elementwise alpha value.

    eps : number, optional
        Controls when an alpha is to be interpreted as exactly 1.0 or exactly 0.0, resulting
        in only the foreground/background being visible and skipping the actual computation.

    Returns
    -------
    image_blend : (H,W,C) ndarray
        Blend of foreground and background image.

    """
    assert image_fg.shape == image_bg.shape
    assert image_fg.dtype.kind == image_bg.dtype.kind
    # TODO switch to gate_dtypes()
    assert image_fg.dtype.name not in ["float128"]
    assert image_bg.dtype.name not in ["float128"]

    # TODO add test for this
    input_was_2d = (len(image_fg.shape) == 2)
    if input_was_2d:
        image_fg = np.atleast_3d(image_fg)
        image_bg = np.atleast_3d(image_bg)

    input_was_bool = False
    if image_fg.dtype.kind == "b":
        input_was_bool = True
        # use float32 instead of float16 here because it seems to be faster
        image_fg = image_fg.astype(np.float32)
        image_bg = image_bg.astype(np.float32)

    alpha = np.array(alpha, dtype=np.float64)
    if alpha.size == 1:
        pass
    else:
        if alpha.ndim == 2:
            assert alpha.shape == image_fg.shape[0:2]
            alpha = alpha.reshape((alpha.shape[0], alpha.shape[1], 1))
        elif alpha.ndim == 3:
            assert alpha.shape == image_fg.shape or alpha.shape == image_fg.shape[0:2] + (1,)
        else:
            alpha = alpha.reshape((1, 1, -1))
        if alpha.shape[2] != image_fg.shape[2]:
            alpha = np.tile(alpha, (1, 1, image_fg.shape[2]))

    if not input_was_bool:
        if np.all(alpha >= 1.0 - eps):
            return np.copy(image_fg)
        elif np.all(alpha <= eps):
            return np.copy(image_bg)

    # for efficiency reaons, only test one value of alpha here, even if alpha is much larger
    assert 0 <= alpha.item(0) <= 1.0

    dt_images = iadt.get_minimal_dtype([image_fg, image_bg])

    # doing this only for non-float images led to inaccuracies for large floats values
    isize = dt_images.itemsize * 2
    isize = max(isize, 4)  # at least 4 bytes (=float32), tends to be faster than float16
    dt_blend = np.dtype("f%d" % (isize,))

    if alpha.dtype != dt_blend:
        alpha = alpha.astype(dt_blend)
    if image_fg.dtype != dt_blend:
        image_fg = image_fg.astype(dt_blend)
    if image_bg.dtype != dt_blend:
        image_bg = image_bg.astype(dt_blend)

    # the following is equivalent to
    #     image_blend = alpha * image_fg + (1 - alpha) * image_bg
    # but supposedly faster
    image_blend = image_bg + alpha * (image_fg - image_bg)

    if input_was_bool:
        image_blend = image_blend > 0.5
    else:
        # skip clip, because alpha is expected to be in range [0.0, 1.0] and both images must have same dtype
        # dont skip round, because otherwise it is very unlikely to hit the image's max possible value
        image_blend = iadt.restore_dtypes_(image_blend, dt_images, clip=False, round=True)

    if input_was_2d:
        return image_blend[:, :, 0]
    return image_blend

Blend two images using an alpha blending .


def SimplexNoiseAlpha(first=None, second=None, per_channel=False, size_px_max=(2, 16), upscale_method=None,
                      iterations=(1, 3), aggregation_method="max", sigmoid=True, sigmoid_thresh=None,
                      name=None, deterministic=False, random_state=None):
    """
    Augmenter to alpha-blend two image sources using simplex noise alpha masks.

    The alpha masks are sampled using a simplex noise method, roughly creating
    connected blobs of 1s surrounded by 0s. If nearest neighbour upsampling
    is used, these blobs can be rectangular with sharp edges.

    dtype support::

        See ``imgaug.augmenters.blend.AlphaElementwise``.

    Parameters
    ----------
    first : None or imgaug.augmenters.meta.Augmenter or iterable of imgaug.augmenters.meta.Augmenter, optional
        Augmenter(s) that make up the first of the two branches.

            * If None, then the input images will be reused as the output
              of the first branch.
            * If Augmenter, then that augmenter will be used as the branch.
            * If iterable of Augmenter, then that iterable will be converted
              into a Sequential and used as the augmenter.

    second : None or imgaug.augmenters.meta.Augmenter or iterable of imgaug.augmenters.meta.Augmenter, optional
        Augmenter(s) that make up the second of the two branches.

            * If None, then the input images will be reused as the output
              of the second branch.
            * If Augmenter, then that augmenter will be used as the branch.
            * If iterable of Augmenter, then that iterable will be converted
              into a Sequential and used as the augmenter.

    per_channel : bool or float, optional
        Whether to use the same factor for all channels (False)
        or to sample a new value for each channel (True).
        If this value is a float ``p``, then for ``p`` percent of all images
        `per_channel` will be treated as True, otherwise as False.

    size_px_max : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        The simplex noise is always generated in a low resolution environment.
        This parameter defines the maximum size of that environment (in
        pixels). The environment is initialized at the same size as the input
        image and then downscaled, so that no side exceeds `size_px_max`
        (aspect ratio is kept).

            * If int, then that number will be used as the size for all
              iterations.
            * If tuple of two ints ``(a, b)``, then a value will be sampled
              per iteration from the discrete range ``[a..b]``.
            * If a list of ints, then a value will be picked per iteration at
              random from that list.
            * If a StochasticParameter, then a value will be sampled from
              that parameter per iteration.

    upscale_method : None or 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 input image size. This parameter controls
        the upscaling method.

            * If None, then either ``nearest`` or ``linear`` or ``cubic`` is picked.
              Most weight is put on linear, followed by cubic.
            * If ia.ALL, then either ``nearest`` or ``linear`` or ``area`` or ``cubic``
              is picked per iteration (all same probability).
            * If string, then that value will be used as the method (must be
              'nearest' or ``linear`` or ``area`` or ``cubic``).
            * If list of string, then a random value will be picked from that
              list per iteration.
            * If StochasticParameter, then a random value will be sampled
              from that parameter per iteration.

    iterations : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        How often to repeat the simplex noise generation process per image.

            * If int, then that number will be used as the iterations for all
              images.
            * If tuple of two ints ``(a, b)``, then a value will be sampled
              per image from the discrete range ``[a..b]``.
            * If a list of ints, then a value will be picked per image at
              random from that list.
            * If a StochasticParameter, then a value will be sampled from
              that parameter per image.

    aggregation_method : imgaug.ALL or str or list of str or imgaug.parameters.StochasticParameter, optional
        The noise maps (from each iteration) are combined to one noise map
        using an aggregation process. This parameter defines the method used
        for that process. Valid methods are ``min``, ``max`` or ``avg``,
        where ``min`` combines the noise maps by taking the (elementwise) minimum
        over all iteration's results, ``max`` the (elementwise) maximum and
        ``avg`` the (elementwise) average.

            * If imgaug.ALL, then a random value will be picked per image from the
              valid ones.
            * If a string, then that value will always be used as the method.
            * If a list of string, then a random value will be picked from
              that list per image.
            * If a StochasticParameter, then a random value will be sampled
              from that paramter per image.

    sigmoid : bool or number, optional
        Whether to apply a sigmoid function to the final noise maps, resulting
        in maps that have more extreme values (close to 0.0 or 1.0).

            * If bool, then a sigmoid will always (True) or never (False) be
              applied.
            * If a number ``p`` with ``0<=p<=1``, then a sigmoid will be applied to
              ``p`` percent of all final noise maps.

    sigmoid_thresh : None or number or tuple of number or imgaug.parameters.StochasticParameter, optional
        Threshold of the sigmoid, when applied. Thresholds above zero
        (e.g. 5.0) will move the saddle point towards the right, leading to
        more values close to 0.0.

            * If None, then ``Normal(0, 5.0)`` will be used.
            * If number, then that threshold will be used for all images.
            * If tuple of two numbers ``(a, b)``, then a random value will
              be sampled per image from the range ``[a, b]``.
            * If StochasticParameter, then a random value will be sampled from
              that parameter per image.

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

    deterministic : bool, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or numpy.random.RandomState, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    Examples
    --------
    >>> aug = iaa.SimplexNoiseAlpha(iaa.EdgeDetect(1.0))

    Detects per image all edges, marks them in a black and white image and
    then alpha-blends the result with the original image using simplex noise
    masks.

    >>> aug = iaa.SimplexNoiseAlpha(iaa.EdgeDetect(1.0), upscale_method="linear")

    Same as the first example, but uses only (smooth) linear upscaling to
    scale the simplex noise masks to the final image sizes, i.e. no nearest
    neighbour upsampling is used, which would result in rectangles with hard
    edges.

    >>> aug = iaa.SimplexNoiseAlpha(iaa.EdgeDetect(1.0), sigmoid_thresh=iap.Normal(10.0, 5.0))

    Same as the first example, but uses a threshold for the sigmoid function
    that is further to the right. This is more conservative, i.e. the generated
    noise masks will be mostly black (values around 0.0), which means that
    most of the original images (parameter/branch `second`) will be kept,
    rather than using the results of the augmentation (parameter/branch
    `first`).

    """
    upscale_method_default = iap.Choice(["nearest", "linear", "cubic"], p=[0.05, 0.6, 0.35])
    sigmoid_thresh_default = iap.Normal(0.0, 5.0)

    noise = iap.SimplexNoise(
        size_px_max=size_px_max,
        upscale_method=upscale_method if upscale_method is not None else upscale_method_default
    )

    if iterations != 1:
        noise = iap.IterativeNoiseAggregator(
            noise,
            iterations=iterations,
            aggregation_method=aggregation_method
        )

    if sigmoid is False or (ia.is_single_number(sigmoid) and sigmoid <= 0.01):
        noise = iap.Sigmoid.create_for_noise(
            noise,
            threshold=sigmoid_thresh if sigmoid_thresh is not None else sigmoid_thresh_default,
            activated=sigmoid
        )

    if name is None:
        name = "Unnamed%s" % (ia.caller_name(),)

    return AlphaElementwise(
        factor=noise, first=first, second=second, per_channel=per_channel,
        name=name, deterministic=deterministic, random_state=random_state
    )

def SimplexNoiseAlpha ( first = None , second = None , per_channel = False , size_px_max = ( 2 , 16 ) , upscale_method = None , iterations = ( 1 , 3 ) , aggregation_method = "max" , sigmoid = True , sigmoid_thresh = None , name = None , deterministic = False , random_state = None ) : upscale_method_default = iap . Choice ( [ "nearest" , "linear" , "cubic" ] , p = [ 0.05 , 0.6 , 0.35 ] ) sigmoid_thresh_default = iap . Normal ( 0.0 , 5.0 ) noise = iap . SimplexNoise ( size_px_max = size_px_max , upscale_method = upscale_method if upscale_method is not None else upscale_method_default ) if iterations != 1 : noise = iap . IterativeNoiseAggregator ( noise , iterations = iterations , aggregation_method = aggregation_method ) if sigmoid is False or ( ia . is_single_number ( sigmoid ) and sigmoid <= 0.01 ) : noise = iap . Sigmoid . create_for_noise ( noise , threshold = sigmoid_thresh if sigmoid_thresh is not None else sigmoid_thresh_default , activated = sigmoid ) if name is None : name = "Unnamed%s" % ( ia . caller_name ( ) , ) return AlphaElementwise ( factor = noise , first = first , second = second , per_channel = per_channel , name = name , deterministic = deterministic , random_state = random_state )

Augmenter to alpha - blend two image sources using simplex noise alpha masks .


def OneOf(children, name=None, deterministic=False, random_state=None):
    """
    Augmenter that always executes exactly one of its children.

    dtype support::

        See ``imgaug.augmenters.meta.SomeOf``.

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

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

    deterministic : bool, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or numpy.random.RandomState, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    Examples
    --------
    >>> imgs = [np.ones((10, 10))]
    >>> seq = iaa.OneOf([
    >>>     iaa.Fliplr(1.0),
    >>>     iaa.Flipud(1.0)
    >>> ])
    >>> imgs_aug = seq.augment_images(imgs)

    flips each image either horizontally or vertically.

    >>> seq = iaa.OneOf([
    >>>     iaa.Fliplr(1.0),
    >>>     iaa.Sequential([
    >>>         iaa.GaussianBlur(1.0),
    >>>         iaa.Dropout(0.05),
    >>>         iaa.AdditiveGaussianNoise(0.1*255)
    >>>     ]),
    >>>     iaa.Noop()
    >>> ])
    >>> imgs_aug = seq.augment_images(imgs)

    either flips each image horizontally, or adds blur+dropout+noise or does
    nothing.

    """
    return SomeOf(n=1, children=children, random_order=False, name=name, deterministic=deterministic,
                  random_state=random_state)

def OneOf ( children , name = None , deterministic = False , random_state = None ) : return SomeOf ( n = 1 , children = children , random_order = False , name = name , deterministic = deterministic , random_state = random_state )

Augmenter that always executes exactly one of its children .


def AssertLambda(func_images=None, func_heatmaps=None, func_keypoints=None,
                 func_polygons=None, name=None, deterministic=False,
                 random_state=None):
    """
    Augmenter that runs an assert on each batch of input images
    using a lambda function as condition.

    This is useful to make generic assumption about the input images and error
    out early if they aren't met.

    dtype support::

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

    Parameters
    ----------
    func_images : None or callable, optional
        The function to call for each batch of images.
        It must follow the form ``function(images, random_state, parents, hooks)``
        and return either True (valid input) or False (invalid input).
        It essentially reuses the interface of
        :func:`imgaug.augmenters.meta.Augmenter._augment_images`.

    func_heatmaps : None or callable, optional
        The function to call for each batch of heatmaps.
        It must follow the form ``function(heatmaps, random_state, parents, hooks)``
        and return either True (valid input) or False (invalid input).
        It essentially reuses the interface of
        :func:`imgaug.augmenters.meta.Augmenter._augment_heatmaps`.

    func_keypoints : None or callable, optional
        The function to call for each batch of keypoints.
        It must follow the form ``function(keypoints_on_images, random_state, parents, hooks)``
        and return either True (valid input) or False (invalid input).
        It essentially reuses the interface of
        :func:`imgaug.augmenters.meta.Augmenter._augment_keypoints`.

    func_polygons : None or callable, optional
        The function to call for each batch of polygons.
        It must follow the form ``function(polygons_on_images, random_state, parents, hooks)``
        and return either True (valid input) or False (invalid input).
        It essentially reuses the interface of
        :func:`imgaug.augmenters.meta.Augmenter._augment_polygons`.

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

    deterministic : bool, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or numpy.random.RandomState, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    """
    def func_images_assert(images, random_state, parents, hooks):
        ia.do_assert(func_images(images, random_state, parents, hooks),
                     "Input images did not fulfill user-defined assertion in AssertLambda.")
        return images

    def func_heatmaps_assert(heatmaps, random_state, parents, hooks):
        ia.do_assert(func_heatmaps(heatmaps, random_state, parents, hooks),
                     "Input heatmaps did not fulfill user-defined assertion in AssertLambda.")
        return heatmaps

    def func_keypoints_assert(keypoints_on_images, random_state, parents, hooks):
        ia.do_assert(func_keypoints(keypoints_on_images, random_state, parents, hooks),
                     "Input keypoints did not fulfill user-defined assertion in AssertLambda.")
        return keypoints_on_images

    def func_polygons_assert(polygons_on_images, random_state, parents, hooks):
        ia.do_assert(func_polygons(polygons_on_images, random_state, parents, hooks),
                     "Input polygons did not fulfill user-defined assertion in AssertLambda.")
        return polygons_on_images

    if name is None:
        name = "Unnamed%s" % (ia.caller_name(),)
    return Lambda(func_images_assert if func_images is not None else None,
                  func_heatmaps_assert if func_heatmaps is not None else None,
                  func_keypoints_assert if func_keypoints is not None else None,
                  func_polygons_assert if func_polygons is not None else None,
                  name=name, deterministic=deterministic, random_state=random_state)

Augmenter that runs an assert on each batch of input images using a lambda function as condition .


def MotionBlur(k=5, angle=(0, 360), direction=(-1.0, 1.0), order=1, name=None, deterministic=False, random_state=None):
    """
    Augmenter that sharpens images and overlays the result with the original image.

    dtype support::

        See ``imgaug.augmenters.convolutional.Convolve``.

    Parameters
    ----------
    k : int or tuple of int or list of int or imgaug.parameters.StochasticParameter, optional
        Kernel size to use.

            * If a single int, then that value will be used for the height
              and width of the kernel.
            * If a tuple of two ints ``(a, b)``, then the kernel size will be
              sampled from the interval ``[a..b]``.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, then ``N`` samples will be drawn from
              that parameter per ``N`` input images, each representing the kernel
              size for the nth image.

    angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Angle of the motion blur in degrees (clockwise, relative to top center direction).

            * If a number, exactly that value will be used.
            * If a tuple ``(a, b)``, a random value from the range ``a <= x <= b`` will
              be sampled per image.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, a value will be sampled from the
              parameter per image.

    direction : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Forward/backward direction of the motion blur. Lower values towards -1.0 will point the motion blur towards
        the back (with angle provided via `angle`). Higher values towards 1.0 will point the motion blur forward.
        A value of 0.0 leads to a uniformly (but still angled) motion blur.

            * If a number, exactly that value will be used.
            * If a tuple ``(a, b)``, a random value from the range ``a <= x <= b`` will
              be sampled per image.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, a value will be sampled from the
              parameter per image.

    order : int or iterable of int or imgaug.ALL or imgaug.parameters.StochasticParameter, optional
        Interpolation order to use when rotating the kernel according to `angle`.
        See :func:`imgaug.augmenters.geometric.Affine.__init__`.
        Recommended to be ``0`` or ``1``, with ``0`` being faster, but less continuous/smooth as `angle` is changed,
        particularly around multiple of 45 degrees.

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

    deterministic : bool, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or numpy.random.RandomState, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    Examples
    --------
    >>> aug = iaa.MotionBlur(k=15)

    Create a motion blur augmenter with kernel size of 15x15.

    >>> aug = iaa.MotionBlur(k=15, angle=[-45, 45])

    Create a motion blur augmenter with kernel size of 15x15 and a blur angle of either -45 or 45 degrees (randomly
    picked per image).

    """
    # TODO allow (1, None) and set to identity matrix if k == 1
    k_param = iap.handle_discrete_param(k, "k", value_range=(3, None), tuple_to_uniform=True, list_to_choice=True,
                                        allow_floats=False)
    angle_param = iap.handle_continuous_param(angle, "angle", value_range=None, tuple_to_uniform=True,
                                              list_to_choice=True)
    direction_param = iap.handle_continuous_param(direction, "direction", value_range=(-1.0-1e-6, 1.0+1e-6),
                                                  tuple_to_uniform=True, list_to_choice=True)

    def create_matrices(image, nb_channels, random_state_func):
        # avoid cyclic import between blur and geometric
        from . import geometric as iaa_geometric

        # force discrete for k_sample via int() in case of stochastic parameter
        k_sample = int(k_param.draw_sample(random_state=random_state_func))
        angle_sample = angle_param.draw_sample(random_state=random_state_func)
        direction_sample = direction_param.draw_sample(random_state=random_state_func)

        k_sample = k_sample if k_sample % 2 != 0 else k_sample + 1
        direction_sample = np.clip(direction_sample, -1.0, 1.0)
        direction_sample = (direction_sample + 1.0) / 2.0

        matrix = np.zeros((k_sample, k_sample), dtype=np.float32)
        matrix[:, k_sample//2] = np.linspace(float(direction_sample), 1.0 - float(direction_sample), num=k_sample)
        rot = iaa_geometric.Affine(rotate=angle_sample, order=order)
        matrix = (rot.augment_image((matrix * 255).astype(np.uint8)) / 255.0).astype(np.float32)

        return [matrix/np.sum(matrix)] * nb_channels

    if name is None:
        name = "Unnamed%s" % (ia.caller_name(),)

    return iaa_convolutional.Convolve(create_matrices, name=name, deterministic=deterministic,
                                      random_state=random_state)

Augmenter that sharpens images and overlays the result with the original image .


def Clouds(name=None, deterministic=False, random_state=None):
    """
    Augmenter to draw clouds in images.

    This is a wrapper around ``CloudLayer``. It executes 1 to 2 layers per image, leading to varying densities
    and frequency patterns of clouds.

    This augmenter seems to be fairly robust w.r.t. the image size. Tested with ``96x128``, ``192x256``
    and ``960x1280``.

    dtype support::

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

        - (1) Parameters of this augmenter are optimized for the value range of uint8.
              While other dtypes may be accepted, they will lead to images augmented in
              ways inappropriate for the respective dtype.

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

    deterministic : bool, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or numpy.random.RandomState, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    Examples
    --------
    >>> aug = iaa.Clouds()

    Creates an augmenter that adds clouds to images.

    """
    if name is None:
        name = "Unnamed%s" % (ia.caller_name(),)

    return meta.SomeOf((1, 2), children=[
        CloudLayer(
            intensity_mean=(196, 255), intensity_freq_exponent=(-2.5, -2.0), intensity_coarse_scale=10,
            alpha_min=0, alpha_multiplier=(0.25, 0.75), alpha_size_px_max=(2, 8), alpha_freq_exponent=(-2.5, -2.0),
            sparsity=(0.8, 1.0), density_multiplier=(0.5, 1.0)
        ),
        CloudLayer(
            intensity_mean=(196, 255), intensity_freq_exponent=(-2.0, -1.0), intensity_coarse_scale=10,
            alpha_min=0, alpha_multiplier=(0.5, 1.0), alpha_size_px_max=(64, 128), alpha_freq_exponent=(-2.0, -1.0),
            sparsity=(1.0, 1.4), density_multiplier=(0.8, 1.5)
        )
    ], random_order=False, name=name, deterministic=deterministic, random_state=random_state)

def Clouds ( name = None , deterministic = False , random_state = None ) : if name is None : name = "Unnamed%s" % ( ia . caller_name ( ) , ) return meta . SomeOf ( ( 1 , 2 ) , children = [ CloudLayer ( intensity_mean = ( 196 , 255 ) , intensity_freq_exponent = ( - 2.5 , - 2.0 ) , intensity_coarse_scale = 10 , alpha_min = 0 , alpha_multiplier = ( 0.25 , 0.75 ) , alpha_size_px_max = ( 2 , 8 ) , alpha_freq_exponent = ( - 2.5 , - 2.0 ) , sparsity = ( 0.8 , 1.0 ) , density_multiplier = ( 0.5 , 1.0 ) ) , CloudLayer ( intensity_mean = ( 196 , 255 ) , intensity_freq_exponent = ( - 2.0 , - 1.0 ) , intensity_coarse_scale = 10 , alpha_min = 0 , alpha_multiplier = ( 0.5 , 1.0 ) , alpha_size_px_max = ( 64 , 128 ) , alpha_freq_exponent = ( - 2.0 , - 1.0 ) , sparsity = ( 1.0 , 1.4 ) , density_multiplier = ( 0.8 , 1.5 ) ) ] , random_order = False , name = name , deterministic = deterministic , random_state = random_state )


def Fog(name=None, deterministic=False, random_state=None):
    """
    Augmenter to draw fog in images.

    This is a wrapper around ``CloudLayer``. It executes a single layer per image with a configuration leading
    to fairly dense clouds with low-frequency patterns.

    This augmenter seems to be fairly robust w.r.t. the image size. Tested with ``96x128``, ``192x256``
    and ``960x1280``.

    dtype support::

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

        - (1) Parameters of this augmenter are optimized for the value range of uint8.
              While other dtypes may be accepted, they will lead to images augmented in
              ways inappropriate for the respective dtype.

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

    deterministic : bool, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or numpy.random.RandomState, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    Examples
    --------
    >>> aug = iaa.Fog()

    Creates an augmenter that adds fog to images.

    """
    if name is None:
        name = "Unnamed%s" % (ia.caller_name(),)

    return CloudLayer(
        intensity_mean=(220, 255), intensity_freq_exponent=(-2.0, -1.5), intensity_coarse_scale=2,
        alpha_min=(0.7, 0.9), alpha_multiplier=0.3, alpha_size_px_max=(2, 8), alpha_freq_exponent=(-4.0, -2.0),
        sparsity=0.9, density_multiplier=(0.4, 0.9),
        name=name, deterministic=deterministic, random_state=random_state
    )

def Fog ( name = None , deterministic = False , random_state = None ) : if name is None : name = "Unnamed%s" % ( ia . caller_name ( ) , ) return CloudLayer ( intensity_mean = ( 220 , 255 ) , intensity_freq_exponent = ( - 2.0 , - 1.5 ) , intensity_coarse_scale = 2 , alpha_min = ( 0.7 , 0.9 ) , alpha_multiplier = 0.3 , alpha_size_px_max = ( 2 , 8 ) , alpha_freq_exponent = ( - 4.0 , - 2.0 ) , sparsity = 0.9 , density_multiplier = ( 0.4 , 0.9 ) , name = name , deterministic = deterministic , random_state = random_state )


def Snowflakes(density=(0.005, 0.075), density_uniformity=(0.3, 0.9), flake_size=(0.2, 0.7),
               flake_size_uniformity=(0.4, 0.8), angle=(-30, 30), speed=(0.007, 0.03),
               name=None, deterministic=False, random_state=None):
    """
    Augmenter to add falling snowflakes to images.

    This is a wrapper around ``SnowflakesLayer``. It executes 1 to 3 layers per image.

    dtype support::

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

        - (1) Parameters of this augmenter are optimized for the value range of uint8.
              While other dtypes may be accepted, they will lead to images augmented in
              ways inappropriate for the respective dtype.

    Parameters
    ----------
    density : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Density of the snowflake layer, as a probability of each pixel in low resolution space to be a snowflake.
        Valid value range is ``(0.0, 1.0)``. Recommended to be around ``(0.01, 0.075)``.

            * If a number, then that value will be used for all images.
            * If a tuple ``(a, b)``, then a value from the continuous range ``[a, b]`` will be used.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, then a value will be sampled per image from that parameter.

    density_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Size uniformity of the snowflakes. Higher values denote more similarly sized snowflakes.
        Valid value range is ``(0.0, 1.0)``. Recommended to be around ``0.5``.

            * If a number, then that value will be used for all images.
            * If a tuple ``(a, b)``, then a value from the continuous range ``[a, b]`` will be used.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, then a value will be sampled per image from that parameter.

    flake_size : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Size of the snowflakes. This parameter controls the resolution at which snowflakes are sampled.
        Higher values mean that the resolution is closer to the input image's resolution and hence each sampled
        snowflake will be smaller (because of the smaller pixel size).

        Valid value range is ``[0.0, 1.0)``. Recommended values:

            * On ``96x128`` a value of ``(0.1, 0.4)`` worked well.
            * On ``192x256`` a value of ``(0.2, 0.7)`` worked well.
            * On ``960x1280`` a value of ``(0.7, 0.95)`` worked well.

        Allowed datatypes:

            * If a number, then that value will be used for all images.
            * If a tuple ``(a, b)``, then a value from the continuous range ``[a, b]`` will be used.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, then a value will be sampled per image from that parameter.

    flake_size_uniformity : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Controls the size uniformity of the snowflakes. Higher values mean that the snowflakes are more similarly
        sized. Valid value range is ``(0.0, 1.0)``. Recommended to be around ``0.5``.

            * If a number, then that value will be used for all images.
            * If a tuple ``(a, b)``, then a value from the continuous range ``[a, b]`` will be used.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, then a value will be sampled per image from that parameter.

    angle : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Angle in degrees of motion blur applied to the snowflakes, where ``0.0`` is motion blur that points straight
        upwards. Recommended to be around ``(-30, 30)``.
        See also :func:`imgaug.augmenters.blur.MotionBlur.__init__`.

            * If a number, then that value will be used for all images.
            * If a tuple ``(a, b)``, then a value from the continuous range ``[a, b]`` will be used.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, then a value will be sampled per image from that parameter.

    speed : number or tuple of number or list of number or imgaug.parameters.StochasticParameter
        Perceived falling speed of the snowflakes. This parameter controls the motion blur's kernel size.
        It follows roughly the form ``kernel_size = image_size * speed``. Hence,
        Values around ``1.0`` denote that the motion blur should "stretch" each snowflake over the whole image.

        Valid value range is ``(0.0, 1.0)``. Recommended values:

            * On ``96x128`` a value of ``(0.01, 0.05)`` worked well.
            * On ``192x256`` a value of ``(0.007, 0.03)`` worked well.
            * On ``960x1280`` a value of ``(0.001, 0.03)`` worked well.

        Allowed datatypes:

            * If a number, then that value will be used for all images.
            * If a tuple ``(a, b)``, then a value from the continuous range ``[a, b]`` will be used.
            * If a list, then a random value will be sampled from that list per image.
            * If a StochasticParameter, then a value will be sampled per image from that parameter.

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

    deterministic : bool, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or numpy.random.RandomState, optional
        See :func:`imgaug.augmenters.meta.Augmenter.__init__`.

    Examples
    --------
    >>> aug = iaa.Snowflakes(flake_size=(0.1, 0.4), speed=(0.01, 0.05))

    Adds snowflakes to small images (around ``96x128``).

    >>> aug = iaa.Snowflakes(flake_size=(0.2, 0.7), speed=(0.007, 0.03))

    Adds snowflakes to medium-sized images (around ``192x256``).

    >>> aug = iaa.Snowflakes(flake_size=(0.7, 0.95), speed=(0.001, 0.03))

    Adds snowflakes to large images (around ``960x1280``).

    """
    if name is None:
        name = "Unnamed%s" % (ia.caller_name(),)

    layer = SnowflakesLayer(
        density=density, density_uniformity=density_uniformity,
        flake_size=flake_size, flake_size_uniformity=flake_size_uniformity,
        angle=angle, speed=speed,
        blur_sigma_fraction=(0.0001, 0.001)
    )

    return meta.SomeOf(
        (1, 3), children=[layer.deepcopy() for _ in range(3)],
        random_order=False, name=name, deterministic=deterministic, random_state=random_state
    )

def Snowflakes ( density = ( 0.005 , 0.075 ) , density_uniformity = ( 0.3 , 0.9 ) , flake_size = ( 0.2 , 0.7 ) , flake_size_uniformity = ( 0.4 , 0.8 ) , angle = ( - 30 , 30 ) , speed = ( 0.007 , 0.03 ) , name = None , deterministic = False , random_state = None ) : if name is None : name = "Unnamed%s" % ( ia . caller_name ( ) , ) layer = SnowflakesLayer ( density = density , density_uniformity = density_uniformity , flake_size = flake_size , flake_size_uniformity = flake_size_uniformity , angle = angle , speed = speed , blur_sigma_fraction = ( 0.0001 , 0.001 ) ) return meta . SomeOf ( ( 1 , 3 ) , children = [ layer . deepcopy ( ) for _ in range ( 3 ) ] , random_order = False , name = name , deterministic = deterministic , random_state = random_state )

Augmenter to add falling snowflakes to images .


def draw(self, size=None, background_threshold=0.01, background_class_id=None, colors=None,
             return_foreground_mask=False):
        """
        Render the segmentation map as an RGB image.

        Parameters
        ----------
        size : None or float or iterable of int or iterable of float, optional
            Size of the rendered RGB image as ``(height, width)``.
            See :func:`imgaug.imgaug.imresize_single_image` for details.
            If set to None, no resizing is performed and the size of the segmentation map array is used.

        background_threshold : float, optional
            See :func:`imgaug.SegmentationMapOnImage.get_arr_int`.

        background_class_id : None or int, optional
            See :func:`imgaug.SegmentationMapOnImage.get_arr_int`.

        colors : None or list of tuple of int, optional
            Colors to use. One for each class to draw. If None, then default colors will be used.

        return_foreground_mask : bool, optional
            Whether to return a mask of the same size as the drawn segmentation map, containing
            True at any spatial location that is not the background class and False everywhere else.

        Returns
        -------
        segmap_drawn : (H,W,3) ndarray
            Rendered segmentation map (dtype is uint8).

        foreground_mask : (H,W) ndarray
            Mask indicating the locations of foreground classes (dtype is bool).
            This value is only returned if `return_foreground_mask` is True.

        """
        arr = self.get_arr_int(background_threshold=background_threshold, background_class_id=background_class_id)
        nb_classes = 1 + np.max(arr)
        segmap_drawn = np.zeros((arr.shape[0], arr.shape[1], 3), dtype=np.uint8)
        if colors is None:
            colors = SegmentationMapOnImage.DEFAULT_SEGMENT_COLORS
        ia.do_assert(nb_classes <= len(colors),
                     "Can't draw all %d classes as it would exceed the maximum number of %d available colors." % (
                         nb_classes, len(colors),))

        ids_in_map = np.unique(arr)
        for c, color in zip(sm.xrange(nb_classes), colors):
            if c in ids_in_map:
                class_mask = (arr == c)
                segmap_drawn[class_mask] = color

        if return_foreground_mask:
            background_class_id = 0 if background_class_id is None else background_class_id
            foreground_mask = (arr != background_class_id)
        else:
            foreground_mask = None

        if size is not None:
            segmap_drawn = ia.imresize_single_image(segmap_drawn, size, interpolation="nearest")
            if foreground_mask is not None:
                foreground_mask = ia.imresize_single_image(
                    foreground_mask.astype(np.uint8), size, interpolation="nearest") > 0

        if foreground_mask is not None:
            return segmap_drawn, foreground_mask
        return segmap_drawn

Render the segmentation map as an RGB image .


def draw_on_image(self, image, alpha=0.75, resize="segmentation_map", background_threshold=0.01,
                      background_class_id=None, colors=None, draw_background=False):
        """
        Draw the segmentation map as an overlay over an image.

        Parameters
        ----------
        image : (H,W,3) ndarray
            Image onto which to draw the segmentation map. Dtype is expected to be uint8.

        alpha : float, optional
            Alpha/opacity value to use for the mixing of image and segmentation map.
            Higher values mean that the segmentation map will be more visible and the image less visible.

        resize : {'segmentation_map', 'image'}, optional
            In case of size differences between the image and segmentation map, either the image or
            the segmentation map can be resized. This parameter controls which of the two will be
            resized to the other's size.

        background_threshold : float, optional
            See :func:`imgaug.SegmentationMapOnImage.get_arr_int`.

        background_class_id : None or int, optional
            See :func:`imgaug.SegmentationMapOnImage.get_arr_int`.

        colors : None or list of tuple of int, optional
            Colors to use. One for each class to draw. If None, then default colors will be used.

        draw_background : bool, optional
            If True, the background will be drawn like any other class.
            If False, the background will not be drawn, i.e. the respective background pixels
            will be identical with the image's RGB color at the corresponding spatial location
            and no color overlay will be applied.

        Returns
        -------
        mix : (H,W,3) ndarray
            Rendered overlays (dtype is uint8).

        """
        # assert RGB image
        ia.do_assert(image.ndim == 3)
        ia.do_assert(image.shape[2] == 3)
        ia.do_assert(image.dtype.type == np.uint8)

        ia.do_assert(0 - 1e-8 <= alpha <= 1.0 + 1e-8)
        ia.do_assert(resize in ["segmentation_map", "image"])

        if resize == "image":
            image = ia.imresize_single_image(image, self.arr.shape[0:2], interpolation="cubic")

        segmap_drawn, foreground_mask = self.draw(
            background_threshold=background_threshold,
            background_class_id=background_class_id,
            size=image.shape[0:2] if resize == "segmentation_map" else None,
            colors=colors,
            return_foreground_mask=True
        )

        if draw_background:
            mix = np.clip(
                (1-alpha) * image + alpha * segmap_drawn,
                0,
                255
            ).astype(np.uint8)
        else:
            foreground_mask = foreground_mask[..., np.newaxis]
            mix = np.zeros_like(image)
            mix += (~foreground_mask).astype(np.uint8) * image
            mix += foreground_mask.astype(np.uint8) * np.clip(
                (1-alpha) * image + alpha * segmap_drawn,
                0,
                255
            ).astype(np.uint8)
        return mix

def
draw_on_image
(
self
,
image
,
alpha
=
0.75
,
resize
=
"segmentation_map"
,
background_threshold
=
0.01
,
background_class_id
=
,
colors
=
,
draw_background
=
False
)
:
# assert RGB image
ia
.
do_assert
(
image
.
ndim
==
3
)
ia
.
do_assert
(
image
.
shape
[
2
]
==
3
)
ia
.
do_assert
(
image
.
dtype
.
type
==
np
.
uint8
)
ia
.
do_assert
(
0
1e-8
<=
alpha
<=
1.0
+
1e-8
)
ia
.
do_assert
(
resize
in
[
"segmentation_map"
,
"image"
]
)
if
resize
==
"image"
:
image
=
ia
.
imresize_single_image
(
image
,
self
.
arr
.
shape
[
0
:
2
]
,
interpolation
=
"cubic"
)
segmap_drawn
,
foreground_mask
=
self
.
draw
(
background_threshold
=
background_threshold
,
background_class_id
=
background_class_id
,
size
=
image
.
shape
[
0
:
2
]
if
resize
==
"segmentation_map"
else
,
colors
=
colors
,
return_foreground_mask
=
True
)
if
draw_background
:
mix
=
np
.
clip
(
(
1
alpha
)
*
image
+
alpha
*
segmap_drawn
,
0
,
255
)
.
astype
(
np
.
uint8
)
else
:
foreground_mask
=
foreground_mask
[
...
,
np
.
newaxis
]
mix
=
np
.
zeros_like
(
image
)
mix
+=
(
~
foreground_mask
)
.
astype
(
np
.
uint8
)
*
image
mix
+=
foreground_mask
.
astype
(
np
.
uint8
)
*
np
.
clip
(
(
1
alpha
)
*
image
+
alpha
*
segmap_drawn
,
0
,
255
)
.
astype
(
np
.
uint8
)
return
mix

Draw the segmentation map as an overlay over an image .


def pad_to_aspect_ratio(self, aspect_ratio, mode="constant", cval=0.0, return_pad_amounts=False):
        """
        Pad the segmentation map on its sides so that its matches a target aspect ratio.

        Depending on which dimension is smaller (height or width), only the corresponding
        sides (left/right or top/bottom) will be padded. In each case, both of the sides will
        be padded equally.

        Parameters
        ----------
        aspect_ratio : float
            Target aspect ratio, given as width/height. E.g. 2.0 denotes the image having twice
            as much width as height.

        mode : str, optional
            Padding mode to use. See :func:`numpy.pad` for details.

        cval : number, optional
            Value to use for padding if `mode` is ``constant``. See :func:`numpy.pad` for details.

        return_pad_amounts : bool, optional
            If False, then only the padded image will be returned. If True, a tuple with two
            entries will be returned, where the first entry is the padded image and the second
            entry are the amounts by which each image side was padded. These amounts are again a
            tuple of the form (top, right, bottom, left), with each value being an integer.

        Returns
        -------
        segmap : imgaug.SegmentationMapOnImage
            Padded segmentation map as SegmentationMapOnImage object.

        pad_amounts : tuple of int
            Amounts by which the segmentation map was padded on each side, given as a
            tuple ``(top, right, bottom, left)``.
            This tuple is only returned if `return_pad_amounts` was set to True.

        """
        arr_padded, pad_amounts = ia.pad_to_aspect_ratio(self.arr, aspect_ratio=aspect_ratio, mode=mode, cval=cval,
                                                         return_pad_amounts=True)
        segmap = SegmentationMapOnImage(arr_padded, shape=self.shape)
        segmap.input_was = self.input_was
        if return_pad_amounts:
            return segmap, pad_amounts
        else:
            return segmap

def pad_to_aspect_ratio ( self , aspect_ratio , mode = "constant" , cval = 0.0 , return_pad_amounts = False ) : arr_padded , pad_amounts = ia . pad_to_aspect_ratio ( self . arr , aspect_ratio = aspect_ratio , mode = mode , cval = cval , return_pad_amounts = True ) segmap = SegmentationMapOnImage ( arr_padded , shape = self . shape ) segmap . input_was = self . input_was if return_pad_amounts : return segmap , pad_amounts else : return segmap

Pad the segmentation map on its sides so that its matches a target aspect ratio .


def resize(self, sizes, interpolation="cubic"):
        """
        Resize the segmentation map array to the provided size given the provided interpolation.

        Parameters
        ----------
        sizes : float or iterable of int or iterable of float
            New size of the array in ``(height, width)``.
            See :func:`imgaug.imgaug.imresize_single_image` for details.

        interpolation : None or str or int, optional
            The interpolation to use during resize.
            See :func:`imgaug.imgaug.imresize_single_image` for details.
            Note: The segmentation map is internally stored as multiple float-based heatmaps,
            making smooth interpolations potentially more reasonable than nearest neighbour
            interpolation.

        Returns
        -------
        segmap : imgaug.SegmentationMapOnImage
            Resized segmentation map object.

        """
        arr_resized = ia.imresize_single_image(self.arr, sizes, interpolation=interpolation)

        # cubic interpolation can lead to values outside of [0.0, 1.0],
        # see https://github.com/opencv/opencv/issues/7195
        # TODO area interpolation too?
        arr_resized = np.clip(arr_resized, 0.0, 1.0)
        segmap = SegmentationMapOnImage(arr_resized, shape=self.shape)
        segmap.input_was = self.input_was
        return segmap

Resize the segmentation map array to the provided size given the provided interpolation .


def to_heatmaps(self, only_nonempty=False, not_none_if_no_nonempty=False):
        """
        Convert segmentation map to heatmaps object.

        Each segmentation map class will be represented as a single heatmap channel.

        Parameters
        ----------
        only_nonempty : bool, optional
            If True, then only heatmaps for classes that appear in the segmentation map will be
            generated. Additionally, a list of these class ids will be returned.

        not_none_if_no_nonempty : bool, optional
            If `only_nonempty` is True and for a segmentation map no channel was non-empty,
            this function usually returns None as the heatmaps object. If however this parameter
            is set to True, a heatmaps object with one channel (representing class 0)
            will be returned as a fallback in these cases.

        Returns
        -------
        imgaug.HeatmapsOnImage or None
            Segmentation map as a heatmaps object.
            If `only_nonempty` was set to True and no class appeared in the segmentation map,
            then this is None.

        class_indices : list of int
            Class ids (0 to C-1) of the classes that were actually added to the heatmaps.
            Only returned if `only_nonempty` was set to True.

        """
        # TODO get rid of this deferred import
        from imgaug.augmentables.heatmaps import HeatmapsOnImage

        if not only_nonempty:
            return HeatmapsOnImage.from_0to1(self.arr, self.shape, min_value=0.0, max_value=1.0)
        else:
            nonempty_mask = np.sum(self.arr, axis=(0, 1)) > 0 + 1e-4
            if np.sum(nonempty_mask) == 0:
                if not_none_if_no_nonempty:
                    nonempty_mask[0] = True
                else:
                    return None, []

            class_indices = np.arange(self.arr.shape[2])[nonempty_mask]
            channels = self.arr[..., class_indices]
            return HeatmapsOnImage(channels, self.shape, min_value=0.0, max_value=1.0), class_indices

def
to_heatmaps
(
self
,
only_nonempty
=
False
,
not_none_if_no_nonempty
=
False
)
:
# TODO get rid of this deferred import
from
imgaug
.
augmentables
.
heatmaps
import
HeatmapsOnImage
if
not
only_nonempty
:
return
HeatmapsOnImage
.
from_0to1
(
self
.
arr
,
self
.
shape
,
min_value
=
0.0
,
max_value
=
1.0
)
else
:
nonempty_mask
=
np
.
sum
(
self
.
arr
,
axis
=
(
0
,
1
)
)
>
0
+
1e-4
if
np
.
sum
(
nonempty_mask
)
==
0
:
if
not_none_if_no_nonempty
:
nonempty_mask
[
0
]
=
True
else
:
return
,
[
]
class_indices
=
np
.
arange
(
self
.
arr
.
shape
[
2
]
)
[
nonempty_mask
]
channels
=
self
.
arr
[
...
,
class_indices
]
return
HeatmapsOnImage
(
channels
,
self
.
shape
,
min_value
=
0.0
,
max_value
=
1.0
)
,
class_indices

Convert segmentation map to heatmaps object .


def from_heatmaps(heatmaps, class_indices=None, nb_classes=None):
        """
        Convert heatmaps to segmentation map.

        Assumes that each class is represented as a single heatmap channel.

        Parameters
        ----------
        heatmaps : imgaug.HeatmapsOnImage
            Heatmaps to convert.

        class_indices : None or list of int, optional
            List of class indices represented by each heatmap channel. See also the
            secondary output of :func:`imgaug.SegmentationMapOnImage.to_heatmap`.
            If this is provided, it must have the same length as the number of heatmap channels.

        nb_classes : None or int, optional
            Number of classes. Must be provided if class_indices is set.

        Returns
        -------
        imgaug.SegmentationMapOnImage
            Segmentation map derived from heatmaps.

        """
        if class_indices is None:
            return SegmentationMapOnImage(heatmaps.arr_0to1, shape=heatmaps.shape)
        else:
            ia.do_assert(nb_classes is not None)
            ia.do_assert(min(class_indices) >= 0)
            ia.do_assert(max(class_indices) < nb_classes)
            ia.do_assert(len(class_indices) == heatmaps.arr_0to1.shape[2])
            arr_0to1 = heatmaps.arr_0to1
            arr_0to1_full = np.zeros((arr_0to1.shape[0], arr_0to1.shape[1], nb_classes), dtype=np.float32)
            for heatmap_channel, mapped_channel in enumerate(class_indices):
                arr_0to1_full[:, :, mapped_channel] = arr_0to1[:, :, heatmap_channel]
            return SegmentationMapOnImage(arr_0to1_full, shape=heatmaps.shape)

def from_heatmaps ( heatmaps , class_indices = None , nb_classes = None ) : if class_indices is None : return SegmentationMapOnImage ( heatmaps . arr_0to1 , shape = heatmaps . shape ) else : ia . do_assert ( nb_classes is not None ) ia . do_assert ( min ( class_indices ) >= 0 ) ia . do_assert ( max ( class_indices ) < nb_classes ) ia . do_assert ( len ( class_indices ) == heatmaps . arr_0to1 . shape [ 2 ] ) arr_0to1 = heatmaps . arr_0to1 arr_0to1_full = np . zeros ( ( arr_0to1 . shape [ 0 ] , arr_0to1 . shape [ 1 ] , nb_classes ) , dtype = np . float32 ) for heatmap_channel , mapped_channel in enumerate ( class_indices ) : arr_0to1_full [ : , : , mapped_channel ] = arr_0to1 [ : , : , heatmap_channel ] return SegmentationMapOnImage ( arr_0to1_full , shape = heatmaps . shape )


def deepcopy(self):
        """
        Create a deep copy of the segmentation map object.

        Returns
        -------
        imgaug.SegmentationMapOnImage
            Deep copy.

        """
        segmap = SegmentationMapOnImage(self.arr, shape=self.shape, nb_classes=self.nb_classes)
        segmap.input_was = self.input_was
        return segmap

def deepcopy ( self ) : segmap = SegmentationMapOnImage ( self . arr , shape = self . shape , nb_classes = self . nb_classes ) segmap . input_was = self . input_was return segmap

Create a deep copy of the segmentation map object .


def offer(self, p, e: Event):
        """
        Offer a new event ``s`` at point ``p`` in this queue.
        """
        existing = self.events_scan.setdefault(
                p, ([], [], [], []) if USE_VERTICAL else
                   ([], [], []))
        # Can use double linked-list for easy insertion at beginning/end
        '''
        if e.type == Event.Type.END:
            existing.insert(0, e)
        else:
            existing.append(e)
        '''

        existing[e.type].append(e)

Offer a new event s at point p in this queue .


def draw(self, size=None, cmap="jet"):
        """
        Render the heatmaps as RGB images.

        Parameters
        ----------
        size : None or float or iterable of int or iterable of float, optional
            Size of the rendered RGB image as ``(height, width)``.
            See :func:`imgaug.imgaug.imresize_single_image` for details.
            If set to None, no resizing is performed and the size of the heatmaps array is used.

        cmap : str or None, optional
            Color map of ``matplotlib`` to use in order to convert the heatmaps to RGB images.
            If set to None, no color map will be used and the heatmaps will be converted
            to simple intensity maps.

        Returns
        -------
        heatmaps_drawn : list of (H,W,3) ndarray
            Rendered heatmaps. One per heatmap array channel. Dtype is uint8.

        """
        heatmaps_uint8 = self.to_uint8()
        heatmaps_drawn = []

        for c in sm.xrange(heatmaps_uint8.shape[2]):
            # c:c+1 here, because the additional axis is needed by imresize_single_image
            heatmap_c = heatmaps_uint8[..., c:c+1]

            if size is not None:
                heatmap_c_rs = ia.imresize_single_image(heatmap_c, size, interpolation="nearest")
            else:
                heatmap_c_rs = heatmap_c
            heatmap_c_rs = np.squeeze(heatmap_c_rs).astype(np.float32) / 255.0

            if cmap is not None:
                # import only when necessary (faster startup; optional dependency; less fragile -- see issue #225)
                import matplotlib.pyplot as plt

                cmap_func = plt.get_cmap(cmap)
                heatmap_cmapped = cmap_func(heatmap_c_rs)
                heatmap_cmapped = np.delete(heatmap_cmapped, 3, 2)
            else:
                heatmap_cmapped = np.tile(heatmap_c_rs[..., np.newaxis], (1, 1, 3))

            heatmap_cmapped = np.clip(heatmap_cmapped * 255, 0, 255).astype(np.uint8)

            heatmaps_drawn.append(heatmap_cmapped)
        return heatmaps_drawn


def draw_on_image(self, image, alpha=0.75, cmap="jet", resize="heatmaps"):
        """
        Draw the heatmaps as overlays over an image.

        Parameters
        ----------
        image : (H,W,3) ndarray
            Image onto which to draw the heatmaps. Expected to be of dtype uint8.

        alpha : float, optional
            Alpha/opacity value to use for the mixing of image and heatmaps.
            Higher values mean that the heatmaps will be more visible and the image less visible.

        cmap : str or None, optional
            Color map to use. See :func:`imgaug.HeatmapsOnImage.draw` for details.

        resize : {'heatmaps', 'image'}, optional
            In case of size differences between the image and heatmaps, either the image or
            the heatmaps can be resized. This parameter controls which of the two will be resized
            to the other's size.

        Returns
        -------
        mix : list of (H,W,3) ndarray
            Rendered overlays. One per heatmap array channel. Dtype is uint8.

        """
        # assert RGB image
        ia.do_assert(image.ndim == 3)
        ia.do_assert(image.shape[2] == 3)
        ia.do_assert(image.dtype.type == np.uint8)

        ia.do_assert(0 - 1e-8 <= alpha <= 1.0 + 1e-8)
        ia.do_assert(resize in ["heatmaps", "image"])

        if resize == "image":
            image = ia.imresize_single_image(image, self.arr_0to1.shape[0:2], interpolation="cubic")

        heatmaps_drawn = self.draw(
            size=image.shape[0:2] if resize == "heatmaps" else None,
            cmap=cmap
        )

        mix = [
            np.clip((1-alpha) * image + alpha * heatmap_i, 0, 255).astype(np.uint8)
            for heatmap_i
            in heatmaps_drawn
        ]

        return mix

def
draw_on_image
(
self
,
image
,
alpha
=
0.75
,
cmap
=
"jet"
,
resize
=
"heatmaps"
)
:
# assert RGB image
ia
.
do_assert
(
image
.
ndim
==
3
)
ia
.
do_assert
(
image
.
shape
[
2
]
==
3
)
ia
.
do_assert
(
image
.
dtype
.
type
==
np
.
uint8
)
ia
.
do_assert
(
0
1e-8
<=
alpha
<=
1.0
+
1e-8
)
ia
.
do_assert
(
resize
in
[
"heatmaps"
,
"image"
]
)
if
resize
==
"image"
:
image
=
ia
.
imresize_single_image
(
image
,
self
.
arr_0to1
.
shape
[
0
:
2
]
,
interpolation
=
"cubic"
)
heatmaps_drawn
=
self
.
draw
(
size
=
image
.
shape
[
0
:
2
]
if
resize
==
"heatmaps"
else
,
cmap
=
cmap
)
mix
=
[
np
.
clip
(
(
1
alpha
)
*
image
+
alpha
*
heatmap_i
,
0
,
255
)
.
astype
(
np
.
uint8
)
for
heatmap_i
in
heatmaps_drawn
]
return
mix

Draw the heatmaps as overlays over an image .


def invert(self):
        """
        Inverts each value in the heatmap, shifting low towards high values and vice versa.

        This changes each value to::

            v' = max - (v - min)

        where ``v`` is the value at some spatial location, ``min`` is the minimum value in the heatmap
        and ``max`` is the maximum value.
        As the heatmap uses internally a 0.0 to 1.0 representation, this simply becomes ``v' = 1.0 - v``.

        Note that the attributes ``min_value`` and ``max_value`` are not switched. They both keep their values.

        This function can be useful e.g. when working with depth maps, where algorithms might have
        an easier time representing the furthest away points with zeros, requiring an inverted
        depth map.

        Returns
        -------
        arr_inv : imgaug.HeatmapsOnImage
            Inverted heatmap.

        """
        arr_inv = HeatmapsOnImage.from_0to1(1 - self.arr_0to1, shape=self.shape, min_value=self.min_value,
                                            max_value=self.max_value)
        arr_inv.arr_was_2d = self.arr_was_2d
        return arr_inv

def invert ( self ) : arr_inv = HeatmapsOnImage . from_0to1 ( 1 - self . arr_0to1 , shape = self . shape , min_value = self . min_value , max_value = self . max_value ) arr_inv . arr_was_2d = self . arr_was_2d return arr_inv

Inverts each value in the heatmap shifting low towards high values and vice versa .


def pad_to_aspect_ratio(self, aspect_ratio, mode="constant", cval=0.0, return_pad_amounts=False):
        """
        Pad the heatmaps on their sides so that they match a target aspect ratio.

        Depending on which dimension is smaller (height or width), only the corresponding
        sides (left/right or top/bottom) will be padded. In each case, both of the sides will
        be padded equally.

        Parameters
        ----------
        aspect_ratio : float
            Target aspect ratio, given as width/height. E.g. 2.0 denotes the image having twice
            as much width as height.

        mode : str, optional
            Padding mode to use. See :func:`numpy.pad` for details.

        cval : number, optional
            Value to use for padding if `mode` is ``constant``. See :func:`numpy.pad` for details.

        return_pad_amounts : bool, optional
            If False, then only the padded image will be returned. If True, a tuple with two
            entries will be returned, where the first entry is the padded image and the second
            entry are the amounts by which each image side was padded. These amounts are again a
            tuple of the form (top, right, bottom, left), with each value being an integer.

        Returns
        -------
        heatmaps : imgaug.HeatmapsOnImage
            Padded heatmaps as HeatmapsOnImage object.

        pad_amounts : tuple of int
            Amounts by which the heatmaps were padded on each side, given as a tuple ``(top, right, bottom, left)``.
            This tuple is only returned if `return_pad_amounts` was set to True.

        """
        arr_0to1_padded, pad_amounts = ia.pad_to_aspect_ratio(self.arr_0to1, aspect_ratio=aspect_ratio, mode=mode,
                                                              cval=cval, return_pad_amounts=True)
        heatmaps = HeatmapsOnImage.from_0to1(arr_0to1_padded, shape=self.shape, min_value=self.min_value,
                                             max_value=self.max_value)
        if return_pad_amounts:
            return heatmaps, pad_amounts
        else:
            return heatmaps

def pad_to_aspect_ratio ( self , aspect_ratio , mode = "constant" , cval = 0.0 , return_pad_amounts = False ) : arr_0to1_padded , pad_amounts = ia . pad_to_aspect_ratio ( self . arr_0to1 , aspect_ratio = aspect_ratio , mode = mode , cval = cval , return_pad_amounts = True ) heatmaps = HeatmapsOnImage . from_0to1 ( arr_0to1_padded , shape = self . shape , min_value = self . min_value , max_value = self . max_value ) if return_pad_amounts : return heatmaps , pad_amounts else : return heatmaps

Pad the heatmaps on their sides so that they match a target aspect ratio .


def to_uint8(self):
        """
        Convert this heatmaps object to a 0-to-255 array.

        Returns
        -------
        arr_uint8 : (H,W,C) ndarray
            Heatmap as a 0-to-255 array (dtype is uint8).

        """
        # TODO this always returns (H,W,C), even if input ndarray was originall (H,W)
        # does it make sense here to also return (H,W) if self.arr_was_2d?
        arr_0to255 = np.clip(np.round(self.arr_0to1 * 255), 0, 255)
        arr_uint8 = arr_0to255.astype(np.uint8)
        return arr_uint8

Convert this heatmaps object to a 0 - to - 255 array .


def from_uint8(arr_uint8, shape, min_value=0.0, max_value=1.0):
        """
        Create a heatmaps object from an heatmap array containing values ranging from 0 to 255.

        Parameters
        ----------
        arr_uint8 : (H,W) ndarray or (H,W,C) ndarray
            Heatmap(s) array, where ``H`` is height, ``W`` is width and ``C`` is the number of heatmap channels.
            Expected dtype is uint8.

        shape : tuple of int
            Shape of the image on which the heatmap(s) is/are placed. NOT the shape of the
            heatmap(s) array, unless it is identical to the image shape (note the likely
            difference between the arrays in the number of channels).
            If there is not a corresponding image, use the shape of the heatmaps array.

        min_value : float, optional
            Minimum value for the heatmaps that the 0-to-255 array represents. This will usually
            be 0.0. It is used when calling :func:`imgaug.HeatmapsOnImage.get_arr`, which converts the
            underlying ``(0, 255)`` array to value range ``(min_value, max_value)``.

        max_value : float, optional
            Maximum value for the heatmaps that 0-to-255 array represents.
            See parameter `min_value` for details.

        Returns
        -------
        imgaug.HeatmapsOnImage
            Heatmaps object.

        """
        arr_0to1 = arr_uint8.astype(np.float32) / 255.0
        return HeatmapsOnImage.from_0to1(arr_0to1, shape, min_value=min_value, max_value=max_value)

Create a heatmaps object from an heatmap array containing values ranging from 0 to 255 .


def from_0to1(arr_0to1, shape, min_value=0.0, max_value=1.0):
        """
        Create a heatmaps object from an heatmap array containing values ranging from 0.0 to 1.0.

        Parameters
        ----------
        arr_0to1 : (H,W) or (H,W,C) ndarray
            Heatmap(s) array, where ``H`` is height, ``W`` is width and ``C`` is the number of heatmap channels.
            Expected dtype is float32.

        shape : tuple of ints
            Shape of the image on which the heatmap(s) is/are placed. NOT the shape of the
            heatmap(s) array, unless it is identical to the image shape (note the likely
            difference between the arrays in the number of channels).
            If there is not a corresponding image, use the shape of the heatmaps array.

        min_value : float, optional
            Minimum value for the heatmaps that the 0-to-1 array represents. This will usually
            be 0.0. It is used when calling :func:`imgaug.HeatmapsOnImage.get_arr`, which converts the
            underlying ``(0.0, 1.0)`` array to value range ``(min_value, max_value)``.
            E.g. if you started with heatmaps in the range ``(-1.0, 1.0)`` and projected these
            to (0.0, 1.0), you should call this function with ``min_value=-1.0``, ``max_value=1.0``
            so that :func:`imgaug.HeatmapsOnImage.get_arr` returns heatmap arrays having value
            range (-1.0, 1.0).

        max_value : float, optional
            Maximum value for the heatmaps that to 0-to-255 array represents.
            See parameter min_value for details.

        Returns
        -------
        heatmaps : imgaug.HeatmapsOnImage
            Heatmaps object.

        """
        heatmaps = HeatmapsOnImage(arr_0to1, shape, min_value=0.0, max_value=1.0)
        heatmaps.min_value = min_value
        heatmaps.max_value = max_value
        return heatmaps

Create a heatmaps object from an heatmap array containing values ranging from 0 . 0 to 1 . 0 .


def change_normalization(cls, arr, source, target):
        """
        Change the value range of a heatmap from one min-max to another min-max.

        E.g. the value range may be changed from min=0.0, max=1.0 to min=-1.0, max=1.0.

        Parameters
        ----------
        arr : ndarray
            Heatmap array to modify.

        source : tuple of float
            Current value range of the input array, given as (min, max), where both are float values.

        target : tuple of float
            Desired output value range of the array, given as (min, max), where both are float values.

        Returns
        -------
        arr_target : ndarray
            Input array, with value range projected to the desired target value range.

        """
        ia.do_assert(ia.is_np_array(arr))

        if isinstance(source, HeatmapsOnImage):
            source = (source.min_value, source.max_value)
        else:
            ia.do_assert(isinstance(source, tuple))
            ia.do_assert(len(source) == 2)
            ia.do_assert(source[0] < source[1])

        if isinstance(target, HeatmapsOnImage):
            target = (target.min_value, target.max_value)
        else:
            ia.do_assert(isinstance(target, tuple))
            ia.do_assert(len(target) == 2)
            ia.do_assert(target[0] < target[1])

        # Check if source and target are the same (with a tiny bit of tolerance)
        # if so, evade compuation and just copy the array instead.
        # This is reasonable, as source and target will often both be (0.0, 1.0).
        eps = np.finfo(arr.dtype).eps
        mins_same = source[0] - 10*eps < target[0] < source[0] + 10*eps
        maxs_same = source[1] - 10*eps < target[1] < source[1] + 10*eps
        if mins_same and maxs_same:
            return np.copy(arr)

        min_source, max_source = source
        min_target, max_target = target

        diff_source = max_source - min_source
        diff_target = max_target - min_target

        arr_0to1 = (arr - min_source) / diff_source
        arr_target = min_target + arr_0to1 * diff_target

        return arr_target

Change the value range of a heatmap from one min - max to another min - max .


def deepcopy(self):
        """
        Create a deep copy of the Heatmaps object.

        Returns
        -------
        imgaug.HeatmapsOnImage
            Deep copy.

        """
        return HeatmapsOnImage(self.get_arr(), shape=self.shape, min_value=self.min_value, max_value=self.max_value)

def deepcopy ( self ) : return HeatmapsOnImage ( self . get_arr ( ) , shape = self . shape , min_value = self . min_value , max_value = self . max_value )

Create a deep copy of the Heatmaps object .


def setdefault(self, key: str, value: str) -> str:
        """
        If the header `key` does not exist, then set it to `value`.
        Returns the header value.
        """
        set_key = key.lower().encode("latin-1")
        set_value = value.encode("latin-1")

        for idx, (item_key, item_value) in enumerate(self._list):
            if item_key == set_key:
                return item_value.decode("latin-1")
        self._list.append((set_key, set_value))
        return value

def setdefault ( self , key : str , value : str ) -> str : set_key = key . lower ( ) . encode ( "latin-1" ) set_value = value . encode ( "latin-1" ) for idx , ( item_key , item_value ) in enumerate ( self . _list ) : if item_key == set_key : return item_value . decode ( "latin-1" ) self . _list . append ( ( set_key , set_value ) ) return value

If the header key does not exist then set it to value . Returns the header value .


def append(self, key: str, value: str) -> None:
        """
        Append a header, preserving any duplicate entries.
        """
        append_key = key.lower().encode("latin-1")
        append_value = value.encode("latin-1")
        self._list.append((append_key, append_value))

def append ( self , key : str , value : str ) -> None : append_key = key . lower ( ) . encode ( "latin-1" ) append_value = value . encode ( "latin-1" ) self . _list . append ( ( append_key , append_value ) )

Append a header preserving any duplicate entries .


def parse_docstring(self, func_or_method: typing.Callable) -> dict:
        """
        Given a function, parse the docstring as YAML and return a dictionary of info.
        """
        docstring = func_or_method.__doc__
        if not docstring:
            return {}

        # We support having regular docstrings before the schema
        # definition. Here we return just the schema part from
        # the docstring.
        docstring = docstring.split("---")[-1]

        parsed = yaml.safe_load(docstring)

        if not isinstance(parsed, dict):
            # A regular docstring (not yaml formatted) can return
            # a simple string here, which wouldn't follow the schema.
            return {}

        return parsed

Given a function parse the docstring as YAML and return a dictionary of info .


def get_directories(
        self, directory: str = None, packages: typing.List[str] = None
    ) -> typing.List[str]:
        """
        Given `directory` and `packages` arugments, return a list of all the
        directories that should be used for serving static files from.
        """
        directories = []
        if directory is not None:
            directories.append(directory)

        for package in packages or []:
            spec = importlib.util.find_spec(package)
            assert spec is not None, f"Package {package!r} could not be found."
            assert (
                spec.origin is not None
            ), "Directory 'statics' in package {package!r} could not be found."
            directory = os.path.normpath(os.path.join(spec.origin, "..", "statics"))
            assert os.path.isdir(
                directory
            ), "Directory 'statics' in package {package!r} could not be found."
            directories.append(directory)

        return directories

Given directory and packages arugments return a list of all the directories that should be used for serving static files from .


async def get_response(self, path: str, scope: Scope) -> Response:
        """
        Returns an HTTP response, given the incoming path, method and request headers.
        """
        if scope["method"] not in ("GET", "HEAD"):
            return PlainTextResponse("Method Not Allowed", status_code=405)

        if path.startswith(".."):
            # Most clients will normalize the path, so we shouldn't normally
            # get this, but don't allow misbehaving clients to break out of
            # the static files directory.
            return PlainTextResponse("Not Found", status_code=404)

        full_path, stat_result = await self.lookup_path(path)

        if stat_result and stat.S_ISREG(stat_result.st_mode):
            # We have a static file to serve.
            return self.file_response(full_path, stat_result, scope)

        elif stat_result and stat.S_ISDIR(stat_result.st_mode) and self.html:
            # We're in HTML mode, and have got a directory URL.
            # Check if we have 'index.html' file to serve.
            index_path = os.path.join(path, "index.html")
            full_path, stat_result = await self.lookup_path(index_path)
            if stat_result is not None and stat.S_ISREG(stat_result.st_mode):
                if not scope["path"].endswith("/"):
                    # Directory URLs should redirect to always end in "/".
                    url = URL(scope=scope)
                    url = url.replace(path=url.path + "/")
                    return RedirectResponse(url=url)
                return self.file_response(full_path, stat_result, scope)

        if self.html:
            # Check for '404.html' if we're in HTML mode.
            full_path, stat_result = await self.lookup_path("404.html")
            if stat_result is not None and stat.S_ISREG(stat_result.st_mode):
                return self.file_response(
                    full_path, stat_result, scope, status_code=404
                )

        return PlainTextResponse("Not Found", status_code=404)

Returns an HTTP response given the incoming path method and request headers .


async def check_config(self) -> None:
        """
        Perform a one-off configuration check that StaticFiles is actually
        pointed at a directory, so that we can raise loud errors rather than
        just returning 404 responses.
        """
        if self.directory is None:
            return

        try:
            stat_result = await aio_stat(self.directory)
        except FileNotFoundError:
            raise RuntimeError(
                f"StaticFiles directory '{self.directory}' does not exist."
            )
        if not (stat.S_ISDIR(stat_result.st_mode) or stat.S_ISLNK(stat_result.st_mode)):
            raise RuntimeError(
                f"StaticFiles path '{self.directory}' is not a directory."
            )

Perform a one - off configuration check that StaticFiles is actually pointed at a directory so that we can raise loud errors rather than just returning 404 responses .


def is_not_modified(
        self, response_headers: Headers, request_headers: Headers
    ) -> bool:
        """
        Given the request and response headers, return `True` if an HTTP
        "Not Modified" response could be returned instead.
        """
        try:
            if_none_match = request_headers["if-none-match"]
            etag = response_headers["etag"]
            if if_none_match == etag:
                return True
        except KeyError:
            pass

        try:
            if_modified_since = parsedate(request_headers["if-modified-since"])
            last_modified = parsedate(response_headers["last-modified"])
            if (
                if_modified_since is not None
                and last_modified is not None
                and if_modified_since >= last_modified
            ):
                return True
        except KeyError:
            pass

        return False

def is_not_modified ( self , response_headers : Headers , request_headers : Headers ) -> bool : try : if_none_match = request_headers [ "if-none-match" ] etag = response_headers [ "etag" ] if if_none_match == etag : return True except KeyError : pass try : if_modified_since = parsedate ( request_headers [ "if-modified-since" ] ) last_modified = parsedate ( response_headers [ "last-modified" ] ) if ( if_modified_since is not None and last_modified is not None and if_modified_since >= last_modified ) : return True except KeyError : pass return False

Given the request and response headers return True if an HTTP Not Modified response could be returned instead .


def build_environ(scope: Scope, body: bytes) -> dict:
    """
    Builds a scope and request body into a WSGI environ object.
    """
    environ = {
        "REQUEST_METHOD": scope["method"],
        "SCRIPT_NAME": scope.get("root_path", ""),
        "PATH_INFO": scope["path"],
        "QUERY_STRING": scope["query_string"].decode("ascii"),
        "SERVER_PROTOCOL": f"HTTP/{scope['http_version']}",
        "wsgi.version": (1, 0),
        "wsgi.url_scheme": scope.get("scheme", "http"),
        "wsgi.input": io.BytesIO(body),
        "wsgi.errors": sys.stdout,
        "wsgi.multithread": True,
        "wsgi.multiprocess": True,
        "wsgi.run_once": False,
    }

    # Get server name and port - required in WSGI, not in ASGI
    server = scope.get("server") or ("localhost", 80)
    environ["SERVER_NAME"] = server[0]
    environ["SERVER_PORT"] = server[1]

    # Get client IP address
    if scope.get("client"):
        environ["REMOTE_ADDR"] = scope["client"][0]

    # Go through headers and make them into environ entries
    for name, value in scope.get("headers", []):
        name = name.decode("latin1")
        if name == "content-length":
            corrected_name = "CONTENT_LENGTH"
        elif name == "content-type":
            corrected_name = "CONTENT_TYPE"
        else:
            corrected_name = f"HTTP_{name}".upper().replace("-", "_")
        # HTTPbis say only ASCII chars are allowed in headers, but we latin1 just in case
        value = value.decode("latin1")
        if corrected_name in environ:
            value = environ[corrected_name] + "," + value
        environ[corrected_name] = value
    return environ

Builds a scope and request body into a WSGI environ object .


async def receive(self) -> Message:
        """
        Receive ASGI websocket messages, ensuring valid state transitions.
        """
        if self.client_state == WebSocketState.CONNECTING:
            message = await self._receive()
            message_type = message["type"]
            assert message_type == "websocket.connect"
            self.client_state = WebSocketState.CONNECTED
            return message
        elif self.client_state == WebSocketState.CONNECTED:
            message = await self._receive()
            message_type = message["type"]
            assert message_type in {"websocket.receive", "websocket.disconnect"}
            if message_type == "websocket.disconnect":
                self.client_state = WebSocketState.DISCONNECTED
            return message
        else:
            raise RuntimeError(
                'Cannot call "receive" once a disconnect message has been received.'
            )

Receive ASGI websocket messages ensuring valid state transitions .


async def send(self, message: Message) -> None:
        """
        Send ASGI websocket messages, ensuring valid state transitions.
        """
        if self.application_state == WebSocketState.CONNECTING:
            message_type = message["type"]
            assert message_type in {"websocket.accept", "websocket.close"}
            if message_type == "websocket.close":
                self.application_state = WebSocketState.DISCONNECTED
            else:
                self.application_state = WebSocketState.CONNECTED
            await self._send(message)
        elif self.application_state == WebSocketState.CONNECTED:
            message_type = message["type"]
            assert message_type in {"websocket.send", "websocket.close"}
            if message_type == "websocket.close":
                self.application_state = WebSocketState.DISCONNECTED
            await self._send(message)
        else:
            raise RuntimeError('Cannot call "send" once a close message has been sent.')

Send ASGI websocket messages ensuring valid state transitions .


def get_top_long_short_abs(positions, top=10):
    """
    Finds the top long, short, and absolute positions.

    Parameters
    ----------
    positions : pd.DataFrame
        The positions that the strategy takes over time.
    top : int, optional
        How many of each to find (default 10).

    Returns
    -------
    df_top_long : pd.DataFrame
        Top long positions.
    df_top_short : pd.DataFrame
        Top short positions.
    df_top_abs : pd.DataFrame
        Top absolute positions.
    """

    positions = positions.drop('cash', axis='columns')
    df_max = positions.max()
    df_min = positions.min()
    df_abs_max = positions.abs().max()
    df_top_long = df_max[df_max > 0].nlargest(top)
    df_top_short = df_min[df_min < 0].nsmallest(top)
    df_top_abs = df_abs_max.nlargest(top)
    return df_top_long, df_top_short, df_top_abs

def get_top_long_short_abs ( positions , top = 10 ) : positions = positions . drop ( 'cash' , axis = 'columns' ) df_max = positions . max ( ) df_min = positions . min ( ) df_abs_max = positions . abs ( ) . max ( ) df_top_long = df_max [ df_max > 0 ] . nlargest ( top ) df_top_short = df_min [ df_min < 0 ] . nsmallest ( top ) df_top_abs = df_abs_max . nlargest ( top ) return df_top_long , df_top_short , df_top_abs

Finds the top long short and absolute positions .


def get_max_median_position_concentration(positions):
    """
    Finds the max and median long and short position concentrations
    in each time period specified by the index of positions.

    Parameters
    ----------
    positions : pd.DataFrame
        The positions that the strategy takes over time.

    Returns
    -------
    pd.DataFrame
        Columns are max long, max short, median long, and median short
        position concentrations. Rows are timeperiods.
    """

    expos = get_percent_alloc(positions)
    expos = expos.drop('cash', axis=1)

    longs = expos.where(expos.applymap(lambda x: x > 0))
    shorts = expos.where(expos.applymap(lambda x: x < 0))

    alloc_summary = pd.DataFrame()
    alloc_summary['max_long'] = longs.max(axis=1)
    alloc_summary['median_long'] = longs.median(axis=1)
    alloc_summary['median_short'] = shorts.median(axis=1)
    alloc_summary['max_short'] = shorts.min(axis=1)

    return alloc_summary

def get_max_median_position_concentration ( positions ) : expos = get_percent_alloc ( positions ) expos = expos . drop ( 'cash' , axis = 1 ) longs = expos . where ( expos . applymap ( lambda x : x > 0 ) ) shorts = expos . where ( expos . applymap ( lambda x : x < 0 ) ) alloc_summary = pd . DataFrame ( ) alloc_summary [ 'max_long' ] = longs . max ( axis = 1 ) alloc_summary [ 'median_long' ] = longs . median ( axis = 1 ) alloc_summary [ 'median_short' ] = shorts . median ( axis = 1 ) alloc_summary [ 'max_short' ] = shorts . min ( axis = 1 ) return alloc_summary

Finds the max and median long and short position concentrations in each time period specified by the index of positions .


def get_long_short_pos(positions):
    """
    Determines the long and short allocations in a portfolio.

    Parameters
    ----------
    positions : pd.DataFrame
        The positions that the strategy takes over time.

    Returns
    -------
    df_long_short : pd.DataFrame
        Long and short allocations as a decimal
        percentage of the total net liquidation
    """

    pos_wo_cash = positions.drop('cash', axis=1)
    longs = pos_wo_cash[pos_wo_cash > 0].sum(axis=1).fillna(0)
    shorts = pos_wo_cash[pos_wo_cash < 0].sum(axis=1).fillna(0)
    cash = positions.cash
    net_liquidation = longs + shorts + cash
    df_pos = pd.DataFrame({'long': longs.divide(net_liquidation, axis='index'),
                           'short': shorts.divide(net_liquidation,
                                                  axis='index')})
    df_pos['net exposure'] = df_pos['long'] + df_pos['short']
    return df_pos

def
get_long_short_pos
(
positions
)
:
pos_wo_cash
=
positions
.
drop
(
'cash'
,
axis
=
1
)
longs
=
pos_wo_cash
[
pos_wo_cash
>
0
]
.
sum
(
axis
=
1
)
.
fillna
(
0
)
shorts
=
pos_wo_cash
[
pos_wo_cash
<
0
]
.
sum
(
axis
=
1
)
.
fillna
(
0
)
cash
=
positions
.
cash
net_liquidation
=
longs
+
shorts
+
cash
df_pos
=
pd
.
DataFrame
(
{
'long'
:
longs
.
divide
(
net_liquidation
,
axis
=
'index'
)
,
'short'
:
shorts
.
divide
(
net_liquidation
,
axis
=
'index'
)
}
)
df_pos
[
'net exposure'
]
=
df_pos
[
'long'
]
+
df_pos
[
'short'
]
return
df_pos

Determines the long and short allocations in a portfolio .


def compute_style_factor_exposures(positions, risk_factor):
    """
    Returns style factor exposure of an algorithm's positions

    Parameters
    ----------
    positions : pd.DataFrame
        Daily equity positions of algorithm, in dollars.
        - See full explanation in create_risk_tear_sheet

    risk_factor : pd.DataFrame
        Daily risk factor per asset.
        - DataFrame with dates as index and equities as columns
        - Example:
                         Equity(24   Equity(62
                           [AAPL])      [ABT])
        2017-04-03	  -0.51284     1.39173
        2017-04-04	  -0.73381     0.98149
        2017-04-05	  -0.90132     1.13981
    """

    positions_wo_cash = positions.drop('cash', axis='columns')
    gross_exposure = positions_wo_cash.abs().sum(axis='columns')

    style_factor_exposure = positions_wo_cash.multiply(risk_factor) \
        .divide(gross_exposure, axis='index')
    tot_style_factor_exposure = style_factor_exposure.sum(axis='columns',
                                                          skipna=True)

    return tot_style_factor_exposure

def compute_style_factor_exposures ( positions , risk_factor ) : positions_wo_cash = positions . drop ( 'cash' , axis = 'columns' ) gross_exposure = positions_wo_cash . abs ( ) . sum ( axis = 'columns' ) style_factor_exposure = positions_wo_cash . multiply ( risk_factor ) . divide ( gross_exposure , axis = 'index' ) tot_style_factor_exposure = style_factor_exposure . sum ( axis = 'columns' , skipna = True ) return tot_style_factor_exposure

Returns style factor exposure of an algorithm s positions


def plot_style_factor_exposures(tot_style_factor_exposure, factor_name=None,
                                ax=None):
    """
    Plots DataFrame output of compute_style_factor_exposures as a line graph

    Parameters
    ----------
    tot_style_factor_exposure : pd.Series
        Daily style factor exposures (output of compute_style_factor_exposures)
        - Time series with decimal style factor exposures
        - Example:
            2017-04-24    0.037820
            2017-04-25    0.016413
            2017-04-26   -0.021472
            2017-04-27   -0.024859

    factor_name : string
        Name of style factor, for use in graph title
        - Defaults to tot_style_factor_exposure.name
    """

    if ax is None:
        ax = plt.gca()

    if factor_name is None:
        factor_name = tot_style_factor_exposure.name

    ax.plot(tot_style_factor_exposure.index, tot_style_factor_exposure,
            label=factor_name)
    avg = tot_style_factor_exposure.mean()
    ax.axhline(avg, linestyle='-.', label='Mean = {:.3}'.format(avg))
    ax.axhline(0, color='k', linestyle='-')
    _, _, y1, y2 = plt.axis()
    lim = max(abs(y1), abs(y2))
    ax.set(title='Exposure to {}'.format(factor_name),
           ylabel='{} \n weighted exposure'.format(factor_name),
           ylim=(-lim, lim))
    ax.legend(frameon=True, framealpha=0.5)

    return ax

def
plot_style_factor_exposures
(
tot_style_factor_exposure
,
factor_name
=
,
ax
=
)
:
if
ax
is
:
ax
=
plt
.
gca
(
)
if
factor_name
is
:
factor_name
=
tot_style_factor_exposure
.
name
ax
.
plot
(
tot_style_factor_exposure
.
index
,
tot_style_factor_exposure
,
label
=
factor_name
)
avg
=
tot_style_factor_exposure
.
mean
(
)
ax
.
axhline
(
avg
,
linestyle
=
'-.'
,
label
=
'Mean = {:.3}'
.
format
(
avg
)
)
ax
.
axhline
(
0
,
color
=
'k'
,
linestyle
=
'-'
)
_
,
_
,
y1
,
y2
=
plt
.
axis
(
)
lim
=
max
(
abs
(
y1
)
,
abs
(
y2
)
)
ax
.
set
(
title
=
'Exposure to {}'
.
format
(
factor_name
)
,
ylabel
=
'{} \n weighted exposure'
.
format
(
factor_name
)
,
ylim
=
(
lim
,
lim
)
)
ax
.
legend
(
frameon
=
True
,
framealpha
=
0.5
)
return
ax


def compute_sector_exposures(positions, sectors, sector_dict=SECTORS):
    """
    Returns arrays of long, short and gross sector exposures of an algorithm's
    positions

    Parameters
    ----------
    positions : pd.DataFrame
        Daily equity positions of algorithm, in dollars.
        - See full explanation in compute_style_factor_exposures.

    sectors : pd.DataFrame
        Daily Morningstar sector code per asset
        - See full explanation in create_risk_tear_sheet

    sector_dict : dict or OrderedDict
        Dictionary of all sectors
        - Keys are sector codes (e.g. ints or strings) and values are sector
          names (which must be strings)
        - Defaults to Morningstar sectors
    """

    sector_ids = sector_dict.keys()

    long_exposures = []
    short_exposures = []
    gross_exposures = []
    net_exposures = []

    positions_wo_cash = positions.drop('cash', axis='columns')
    long_exposure = positions_wo_cash[positions_wo_cash > 0] \
        .sum(axis='columns')
    short_exposure = positions_wo_cash[positions_wo_cash < 0] \
        .abs().sum(axis='columns')
    gross_exposure = positions_wo_cash.abs().sum(axis='columns')

    for sector_id in sector_ids:
        in_sector = positions_wo_cash[sectors == sector_id]

        long_sector = in_sector[in_sector > 0] \
            .sum(axis='columns').divide(long_exposure)
        short_sector = in_sector[in_sector < 0] \
            .sum(axis='columns').divide(short_exposure)
        gross_sector = in_sector.abs().sum(axis='columns') \
            .divide(gross_exposure)
        net_sector = long_sector.subtract(short_sector)

        long_exposures.append(long_sector)
        short_exposures.append(short_sector)
        gross_exposures.append(gross_sector)
        net_exposures.append(net_sector)

    return long_exposures, short_exposures, gross_exposures, net_exposures

def compute_sector_exposures ( positions , sectors , sector_dict = SECTORS ) : sector_ids = sector_dict . keys ( ) long_exposures = [ ] short_exposures = [ ] gross_exposures = [ ] net_exposures = [ ] positions_wo_cash = positions . drop ( 'cash' , axis = 'columns' ) long_exposure = positions_wo_cash [ positions_wo_cash > 0 ] . sum ( axis = 'columns' ) short_exposure = positions_wo_cash [ positions_wo_cash < 0 ] . abs ( ) . sum ( axis = 'columns' ) gross_exposure = positions_wo_cash . abs ( ) . sum ( axis = 'columns' ) for sector_id in sector_ids : in_sector = positions_wo_cash [ sectors == sector_id ] long_sector = in_sector [ in_sector > 0 ] . sum ( axis = 'columns' ) . divide ( long_exposure ) short_sector = in_sector [ in_sector < 0 ] . sum ( axis = 'columns' ) . divide ( short_exposure ) gross_sector = in_sector . abs ( ) . sum ( axis = 'columns' ) . divide ( gross_exposure ) net_sector = long_sector . subtract ( short_sector ) long_exposures . append ( long_sector ) short_exposures . append ( short_sector ) gross_exposures . append ( gross_sector ) net_exposures . append ( net_sector ) return long_exposures , short_exposures , gross_exposures , net_exposures

Returns arrays of long short and gross sector exposures of an algorithm s positions


def plot_sector_exposures_longshort(long_exposures, short_exposures,
                                    sector_dict=SECTORS, ax=None):
    """
    Plots outputs of compute_sector_exposures as area charts

    Parameters
    ----------
    long_exposures, short_exposures : arrays
        Arrays of long and short sector exposures (output of
        compute_sector_exposures).

    sector_dict : dict or OrderedDict
        Dictionary of all sectors
        - See full description in compute_sector_exposures
    """

    if ax is None:
        ax = plt.gca()

    if sector_dict is None:
        sector_names = SECTORS.values()
    else:
        sector_names = sector_dict.values()

    color_list = plt.cm.gist_rainbow(np.linspace(0, 1, 11))

    ax.stackplot(long_exposures[0].index, long_exposures,
                 labels=sector_names, colors=color_list, alpha=0.8,
                 baseline='zero')
    ax.stackplot(long_exposures[0].index, short_exposures,
                 colors=color_list, alpha=0.8, baseline='zero')
    ax.axhline(0, color='k', linestyle='-')
    ax.set(title='Long and short exposures to sectors',
           ylabel='Proportion of long/short exposure in sectors')
    ax.legend(loc='upper left', frameon=True, framealpha=0.5)

    return ax