def Func(arg_0, arg_1=None, arg_2=None):
        """
        Create a shallow Func of the KeypointsOnImage object.

        Parameters
        ----------
        keypoints : None or list of imgaug.Keypoint, optional
            List of keypoints on the image. If ``None``, the instance's
            keypoints will be copied.

        shape : tuple of int, optional
            The shape of the image on which the keypoints are placed.
            If ``None``, the instance's shape will be copied.

        Returns
        -------
        imgaug.KeypointsOnImage
            Shallow Func.

        """
        arg_3 = Func.Func(arg_0)
        if arg_1 is not None:
            arg_3.keypoints = arg_1
        if arg_2 is not None:
            arg_3.shape = arg_2
        return arg_3


def Func(arg_0, arg_1, arg_2=None):
        """
        Compute the Func bounding box of this bounding box and another one.

        Note that in extreme cases, the Func can be a single point, meaning that the Func bounding box
        will exist, but then also has a height and width of zero.

        Parameters
        ----------
        other : imgaug.BoundingBox
            Other bounding box with which to generate the Func.

        default : any, optional
            Default value to return if there is no Func.

        Returns
        -------
        imgaug.BoundingBox or any
            Intersection bounding box of the two bounding boxes if there is an Func.
            If there is no Func, the default value will be returned, which can by anything.

        """
        arg_3 = max(arg_0.x1, arg_1.x1)
        arg_4 = max(arg_0.y1, arg_1.y1)
        arg_5 = min(arg_0.x2, arg_1.x2)
        arg_6 = min(arg_0.y2, arg_1.y2)
        if arg_3 > arg_5 or arg_4 > arg_6:
            return arg_2
        else:
            return BoundingBox(x1=arg_3, y1=arg_4, x2=arg_5, y2=arg_6)


def Func(arg_0, arg_1):
        """
        Compute the Func bounding box of this bounding box and another one.

        This is equivalent to drawing a bounding box around all corners points of both
        bounding boxes.

        Parameters
        ----------
        other : imgaug.BoundingBox
            Other bounding box with which to generate the Func.

        Returns
        -------
        imgaug.BoundingBox
            Union bounding box of the two bounding boxes.

        """
        return BoundingBox(
            x1=min(arg_0.x1, arg_1.x1),
            y1=min(arg_0.y1, arg_1.y1),
            x2=max(arg_0.x2, arg_1.x2),
            y2=max(arg_0.y2, arg_1.y2),
        )


def Func(arg_0, arg_1):
        """
        Estimate whether the bounding box is at least partially inside the image area.

        Parameters
        ----------
        image : (H,W,...) ndarray or tuple of int
            Image dimensions to use.
            If an ndarray, its shape will be used.
            If a tuple, it is assumed to represent the image shape
            and must contain at least two integers.

        Returns
        -------
        bool
            True if the bounding box is at least partially inside the image area. False otherwise.

        """
        arg_2 = normalize_shape(arg_1)
        arg_3, arg_4 = arg_2[0:2]
        arg_5 = np.finfo(np.float32).eps
        arg_6 = BoundingBox(x1=0, x2=arg_4-arg_5, y1=0, y2=arg_3-arg_5)
        return arg_0.intersection(arg_6) is not None


def Func(arg_0, arg_1, arg_2=True, arg_3=False):
        """
        Estimate whether the bounding box is partially or fully outside of the image area.

        Parameters
        ----------
        image : (H,W,...) ndarray or tuple of int
            Image dimensions to use. If an ndarray, its shape will be used. If a tuple, it is
            assumed to represent the image shape and must contain at least two integers.

        fully : bool, optional
            Whether to return True if the bounding box is fully outside fo the image area.

        partly : bool, optional
            Whether to return True if the bounding box is at least partially outside fo the
            image area.

        Returns
        -------
        bool
            True if the bounding box is partially/fully outside of the image area, depending
            on defined parameters. False otherwise.

        """
        if arg_0.is_fully_within_image(arg_1):
            return False
        elif arg_0.is_partly_within_image(arg_1):
            return arg_3
        else:
            return arg_2


def Func(arg_0, arg_1):
        """
        Clip off all parts of the bounding box that are outside of the image.

        Parameters
        ----------
        image : (H,W,...) ndarray or tuple of int
            Image dimensions to use for the clipping of the bounding box.
            If an ndarray, its shape will be used.
            If a tuple, it is assumed to represent the image shape and must contain at least two integers.

        Returns
        -------
        result : imgaug.BoundingBox
            Bounding box, clipped to fall within the image dimensions.

        """
        arg_2 = normalize_shape(arg_1)

        arg_3, arg_4 = arg_2[0:2]
        ia.do_assert(arg_3 > 0)
        ia.do_assert(arg_4 > 0)

        arg_5 = np.finfo(np.float32).eps
        arg_6 = np.clip(arg_0.x1, 0, arg_4 - arg_5)
        arg_7 = np.clip(arg_0.x2, 0, arg_4 - arg_5)
        arg_8 = np.clip(arg_0.y1, 0, arg_3 - arg_5)
        arg_9 = np.clip(arg_0.y2, 0, arg_3 - arg_5)

        return arg_0.copy(
            arg_6=arg_6,
            arg_8=arg_8,
            arg_7=arg_7,
            arg_9=arg_9,
            label=arg_0.label
        )


def Func(arg_0, arg_1, arg_2=(0, 255, 0), arg_3=1.0, arg_4=1,
                      arg_5=True, arg_6=False, arg_7=None):
        """
        Draw the bounding box on an image.

        Parameters
        ----------
        image : (H,W,C) ndarray(uint8)
            The image onto which to draw the bounding box.

        color : iterable of int, optional
            The color to use, corresponding to the channel layout of the image. Usually RGB.

        alpha : float, optional
            The transparency of the drawn bounding box, where 1.0 denotes no transparency and
            0.0 is invisible.

        size : int, optional
            The thickness of the bounding box in pixels. If the value is larger than 1, then
            additional pixels will be added around the bounding box (i.e. extension towards the
            outside).

        copy : bool, optional
            Whether to copy the input image or change it in-place.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the bounding box is fully outside of the
            image. If set to False, no error will be raised and only the parts inside the image
            will be drawn.

        thickness : None or int, optional
            Deprecated.

        Returns
        -------
        result : (H,W,C) ndarray(uint8)
            Image with bounding box drawn on it.

        """
        if arg_7 is not None:
            ia.warn_deprecated(
                "Usage of argument 'thickness' in BoundingBox.Func() "
                "is deprecated. The argument was renamed to 'size'."
            )
            arg_4 = arg_7

        if arg_6 and arg_0.is_out_of_image(arg_1):
            raise Exception("Cannot draw bounding box x1=%.8f, y1=%.8f, x2=%.8f, y2=%.8f on image with shape %s." % (
                arg_0.x1, arg_0.y1, arg_0.x2, arg_0.y2, arg_1.shape))

        arg_8 = np.copy(arg_1) if arg_5 else arg_1

        if isinstance(arg_2, (tuple, list)):
            arg_2 = np.uint8(arg_2)

        for arg_9 in range(arg_4):
            arg_10, arg_11, arg_12, arg_13 = arg_0.y1_int, arg_0.y2_int, arg_0.x1_int, arg_0.x2_int

            # When y values get into the range (H-0.5, H), the *_int functions round them to H.
            # That is technically sensible, but in the case of drawing means that the border lies
            # just barely outside of the image, making the border disappear, even though the BB
            # is fully inside the image. Here we correct for that because of beauty reasons.
            # Same is the case for x coordinates.
            if arg_0.is_fully_within_image(arg_1):
                arg_10 = np.clip(arg_10, 0, arg_1.shape[0]-1)
                arg_11 = np.clip(arg_11, 0, arg_1.shape[0]-1)
                arg_12 = np.clip(arg_12, 0, arg_1.shape[1]-1)
                arg_13 = np.clip(arg_13, 0, arg_1.shape[1]-1)

            arg_14 = [arg_10-arg_9, arg_10-arg_9, arg_11+arg_9, arg_11+arg_9]
            arg_15 = [arg_12-arg_9, arg_13+arg_9, arg_13+arg_9, arg_12-arg_9]
            arg_16, arg_17 = skimage.draw.polygon_perimeter(arg_14, arg_15, shape=arg_8.shape)
            if arg_3 >= 0.99:
                arg_8[arg_16, arg_17, :] = arg_2
            else:
                if ia.is_float_array(arg_8):
                    arg_8[arg_16, arg_17, :] = (1 - arg_3) * arg_8[arg_16, arg_17, :] + arg_3 * arg_2
                    arg_8 = np.clip(arg_8, 0, 255)
                else:
                    arg_18 = arg_8.dtype
                    arg_8 = arg_8.astype(np.float32)
                    arg_8[arg_16, arg_17, :] = (1 - arg_3) * arg_8[arg_16, arg_17, :] + arg_3 * arg_2
                    arg_8 = np.clip(arg_8, 0, 255).astype(arg_18)

        return arg_8


def Func(arg_0, arg_1, arg_2=True, arg_3=None,
                           arg_4=True):
        """
        Extract the image pixels within the bounding box.

        This function will zero-pad the image if the bounding box is partially/fully outside of
        the image.

        Parameters
        ----------
        image : (H,W) ndarray or (H,W,C) ndarray
            The image from which to extract the pixels within the bounding box.

        pad : bool, optional
            Whether to zero-pad the image if the object is partially/fully
            outside of it.

        pad_max : None or int, optional
            The maximum number of pixels that may be zero-paded on any side,
            i.e. if this has value ``N`` the total maximum of added pixels
            is ``4*N``.
            This option exists to prevent extremely large images as a result of
            single points being moved very far away during augmentation.

        prevent_zero_size : bool, optional
            Whether to prevent height or width of the extracted image from becoming zero.
            If this is set to True and height or width of the bounding box is below 1, the height/width will
            be increased to 1. This can be useful to prevent problems, e.g. with image saving or plotting.
            If it is set to False, images will be returned as ``(H', W')`` or ``(H', W', 3)`` with ``H`` or
            ``W`` potentially being 0.

        Returns
        -------
        image : (H',W') ndarray or (H',W',C) ndarray
            Pixels within the bounding box. Zero-padded if the bounding box is partially/fully
            outside of the image. If prevent_zero_size is activated, it is guarantueed that ``H'>0``
            and ``W'>0``, otherwise only ``H'>=0`` and ``W'>=0``.

        """
        arg_5 = 0
        arg_6 = 0
        arg_7 = 0
        arg_8 = 0

        arg_9, arg_10 = arg_1.shape[0], arg_1.shape[1]
        arg_11, arg_12, arg_13, arg_14 = arg_0.x1_int, arg_0.x2_int, arg_0.y1_int, arg_0.y2_int

        # When y values get into the range (H-0.5, H), the *_int functions round them to H.
        # That is technically sensible, but in the case of extraction leads to a black border,
        # which is both ugly and unexpected after calling cut_out_of_image(). Here we correct for
        # that because of beauty reasons.
        # Same is the case for x coordinates.
        arg_15 = arg_0.is_fully_within_image(arg_1)
        if arg_15:
            arg_13, arg_14 = np.clip([arg_13, arg_14], 0, arg_9-1)
            arg_11, arg_12 = np.clip([arg_11, arg_12], 0, arg_10-1)

        # TODO add test
        if arg_4:
            if abs(arg_12 - arg_11) < 1:
                arg_12 = arg_11 + 1
            if abs(arg_14 - arg_13) < 1:
                arg_14 = arg_13 + 1

        if arg_2:
            # if the bb is outside of the image area, the following pads the image
            # first with black pixels until the bb is inside the image
            # and only then extracts the image area
            # TODO probably more efficient to initialize an array of zeros
            # and copy only the portions of the bb into that array that are
            # natively inside the image area
            if arg_11 < 0:
                arg_8 = abs(arg_11)
                arg_12 = arg_12 + arg_8
                arg_10 = arg_10 + arg_8
                arg_11 = 0
            if arg_13 < 0:
                arg_5 = abs(arg_13)
                arg_14 = arg_14 + arg_5
                arg_9 = arg_9 + arg_5
                arg_13 = 0
            if arg_12 >= arg_10:
                arg_6 = arg_12 - arg_10
            if arg_14 >= arg_9:
                arg_7 = arg_14 - arg_9

            arg_16 = [arg_5, arg_6, arg_7, arg_8]
            arg_17 = any([val > 0 for val in arg_16])
            if arg_17:
                if arg_3 is None:
                    arg_3 = max(arg_16)

                arg_1 = ia.pad(
                    arg_1,
                    top=min(arg_5, arg_3),
                    right=min(arg_6, arg_3),
                    bottom=min(arg_7, arg_3),
                    left=min(arg_8, arg_3)
                )
            return arg_1[arg_13:arg_14, arg_11:arg_12]
        else:
            arg_18 = (
                (0, 0, 0, 0)
                <= (arg_11, arg_13, arg_12, arg_14)
                < (arg_10, arg_9, arg_10, arg_9)
            )
            arg_19, arg_20 = (arg_14 - arg_13), (arg_12 - arg_11)
            arg_21 = (arg_19 > 0)
            arg_22 = (arg_20 > 0)
            if arg_18 and arg_21 and arg_22:
                return arg_1[arg_13:arg_14, arg_11:arg_12]
            if arg_4:
                arg_19 = 1
                arg_20 = 1
            else:
                arg_19 = 0
                arg_20 = 0
            if arg_1.ndim == 2:
                return np.zeros((arg_19, arg_20), dtype=arg_1.dtype)
            return np.zeros((arg_19, arg_20, arg_1.shape[-1]),
                            dtype=arg_1.dtype)


def Func(arg_0, arg_1=True, arg_2=False):
        """
        Remove all bounding boxes that are fully or partially outside of the image.

        Parameters
        ----------
        fully : bool, optional
            Whether to remove bounding boxes that are fully outside of the image.

        partly : bool, optional
            Whether to remove bounding boxes that are partially outside of the image.

        Returns
        -------
        imgaug.BoundingBoxesOnImage
            Reduced set of bounding boxes, with those that were fully/partially outside of
            the image removed.

        """
        arg_3 = [bb for bb in arg_0.bounding_boxes
                     if not bb.is_out_of_image(arg_0.shape, arg_1=arg_1, arg_2=arg_2)]
        return BoundingBoxesOnImage(arg_3, shape=arg_0.shape)


def Func(arg_0):
        """
        Clip off all parts from all bounding boxes that are outside of the image.

        Returns
        -------
        imgaug.BoundingBoxesOnImage
            Bounding boxes, clipped to fall within the image dimensions.

        """
        arg_1 = [bb.Func(arg_0.shape)
                   for bb in arg_0.bounding_boxes if bb.is_partly_within_image(arg_0.shape)]
        return BoundingBoxesOnImage(arg_1, shape=arg_0.shape)


def Func(arg_0=0, arg_1=1, arg_2=None, arg_3=False, arg_4=None):
    """
    Augmenter that embosses images and overlays the result with the original
    image.

    The embossed version pronounces highlights and shadows,
    letting the image look as if it was recreated on a metal plate ("embossed").

    dtype support::

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

    Parameters
    ----------
    alpha : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Visibility of the sharpened image. At 0, only the original image is
        visible, at 1.0 only its sharpened version is visible.

            * If an int or float, 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.

    strength : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Parameter that controls the strength of the embossing.
        Sane values are somewhere in the range ``(0, 2)`` with 1 being the standard
        embossing effect. Default value is 1.

            * If an int or float, 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.

    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 = Func(alpha=(0.0, 1.0), strength=(0.5, 1.5))

    embosses an image with a variable strength in the range ``0.5 <= x <= 1.5``
    and overlays the result with a variable alpha in the range ``0.0 <= a <= 1.0``
    over the old image.

    """
    arg_5 = iap.handle_continuous_param(arg_0, "alpha", value_range=(0, 1.0), tuple_to_uniform=True,
                                              list_to_choice=True)
    arg_6 = iap.handle_continuous_param(arg_1, "strength", value_range=(0, None), tuple_to_uniform=True,
                                                 list_to_choice=True)

    def create_matrices(arg_7, arg_8, arg_9):
        arg_10 = arg_5.draw_sample(arg_4=arg_9)
        ia.do_assert(0 <= arg_10 <= 1.0)
        arg_11 = arg_6.draw_sample(arg_4=arg_9)
        arg_12 = np.array([
            [0, 0, 0],
            [0, 1, 0],
            [0, 0, 0]
        ], dtype=np.float32)
        arg_13 = np.array([
            [-1-arg_11, 0-arg_11, 0],
            [0-arg_11, 1, 0+arg_11],
            [0, 0+arg_11, 1+arg_11]
        ], dtype=np.float32)
        arg_14 = (1-arg_10) * arg_12 + arg_10 * arg_13
        return [arg_14] * arg_8

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

    return Convolve(create_matrices, arg_2=arg_2, arg_3=arg_3, arg_4=arg_4)


def Func(arg_0=0, arg_1=(0.0, 1.0), arg_2=None, arg_3=False, arg_4=None):
    """
    Augmenter that detects edges that have certain directions and marks them
    in a black and white image and then overlays the result with the original
    image.

    dtype support::

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

    Parameters
    ----------
    alpha : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Visibility of the sharpened image. At 0, only the original image is
        visible, at 1.0 only its sharpened version is visible.

            * If an int or float, 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
        Angle of edges to pronounce, where 0 represents 0 degrees and 1.0
        represents 360 degrees (both clockwise, starting at the top).
        Default value is ``(0.0, 1.0)``, i.e. pick a random angle per image.

            * If an int or float, 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.

    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 = Func(alpha=1.0, direction=0)

    turns input images into edge images in which edges are detected from
    top side of the image (i.e. the top sides of horizontal edges are
    added to the output).

    >>> aug = Func(alpha=1.0, direction=90/360)

    same as before, but detecting edges from the right (right side of each
    vertical edge).

    >>> aug = Func(alpha=1.0, direction=(0.0, 1.0))

    same as before, but detecting edges from a variable direction (anything
    between 0 and 1.0, i.e. 0 degrees and 360 degrees, starting from the
    top and moving clockwise).

    >>> aug = Func(alpha=(0.0, 0.3), direction=0)

    generates edge images (edges detected from the top) and overlays them
    with the input images by a variable amount between 0 and 30 percent
    (e.g. for 0.3 then ``0.7*old_image + 0.3*edge_image``).

    """
    arg_5 = iap.handle_continuous_param(arg_0, "alpha", value_range=(0, 1.0), tuple_to_uniform=True,
                                              list_to_choice=True)
    arg_6 = iap.handle_continuous_param(arg_1, "direction", value_range=None, tuple_to_uniform=True,
                                                  list_to_choice=True)

    def create_matrices(arg_7, arg_8, arg_9):
        arg_10 = arg_5.draw_sample(arg_4=arg_9)
        ia.do_assert(0 <= arg_10 <= 1.0)
        arg_11 = arg_6.draw_sample(arg_4=arg_9)

        arg_12 = int(arg_11 * 360) % 360
        arg_13 = np.deg2rad(arg_12)
        arg_14 = np.cos(arg_13 - 0.5*np.pi)
        arg_15 = np.sin(arg_13 - 0.5*np.pi)
        arg_16 = np.array([arg_14, arg_15])

        arg_17 = np.array([
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]
        ], dtype=np.float32)
        for arg_14 in [-1, 0, 1]:
            for arg_15 in [-1, 0, 1]:
                if (arg_14, arg_15) != (0, 0):
                    arg_18 = np.array([arg_14, arg_15])
                    arg_19 = np.rad2deg(ia.angle_between_vectors(arg_18, arg_16))
                    arg_20 = arg_19 / 180
                    arg_21 = (1 - arg_20)**4
                    arg_17[arg_15+1, arg_14+1] = arg_21
        arg_17 = arg_17 / np.sum(arg_17)
        arg_17 = arg_17 * (-1)
        arg_17[1, 1] = 1

        arg_22 = np.array([
            [0, 0, 0],
            [0, 1, 0],
            [0, 0, 0]
        ], dtype=np.float32)

        arg_23 = (1-arg_10) * arg_22 + arg_10 * arg_17

        return [arg_23] * arg_8

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

    return Convolve(create_matrices, arg_2=arg_2, arg_3=arg_3, arg_4=arg_4)


def Func(arg_0):
    """
    Normalize a shape tuple or array to a shape tuple.

    Parameters
    ----------
    shape : tuple of int or ndarray
        The input to normalize. May optionally be an array.

    Returns
    -------
    tuple of int
        Shape tuple.

    """
    if isinstance(arg_0, tuple):
        return arg_0
    assert ia.is_np_array(arg_0), (
        "Expected tuple of ints or array, got %s." % (type(arg_0),))
    return arg_0.shape


def Func(arg_0, arg_1, arg_2):
    """
    Project coordinates from one image shape to another.

    This performs a relative projection, e.g. a point at 60% of the old
    image width will be at 60% of the new image width after projection.

    Parameters
    ----------
    coords : ndarray or tuple of number
        Coordinates to project. Either a ``(N,2)`` numpy array or a tuple
        of `(x,y)` coordinates.

    from_shape : tuple of int or ndarray
        Old image shape.

    to_shape : tuple of int or ndarray
        New image shape.

    Returns
    -------
    ndarray
        Projected coordinates as ``(N,2)`` ``float32`` numpy array.

    """
    arg_1 = normalize_shape(arg_1)
    arg_2 = normalize_shape(arg_2)
    if arg_1[0:2] == arg_2[0:2]:
        return arg_0

    arg_3, arg_4 = arg_1[0:2]
    arg_5, arg_6 = arg_2[0:2]
    assert all([arg_7 > 0 for arg_7 in [arg_3, arg_4, arg_5, arg_6]])

    # make sure to not just call np.float32(coords) here as the following lines
    # perform in-place changes and np.float32(.) only copies if the input
    # was *not* a float32 array
    arg_8 = np.array(arg_0).astype(np.float32)
    arg_8[:, 0] = (arg_8[:, 0] / arg_4) * arg_6
    arg_8[:, 1] = (arg_8[:, 1] / arg_3) * arg_5
    return arg_8


def Func(arg_0=0, arg_1=False, arg_2=None, arg_3=False, arg_4=None):
    """
    Create an augmenter to add poisson noise to images.

    Poisson noise is comparable to gaussian noise as in ``AdditiveGaussianNoise``, but the values are sampled from
    a poisson distribution instead of a gaussian distribution. As poisson distributions produce only positive numbers,
    the sign of the sampled values are here randomly flipped.

    Values of around ``10.0`` for `lam` lead to visible noise (for uint8).
    Values of around ``20.0`` for `lam` lead to very visible noise (for uint8).
    It is recommended to usually set `per_channel` to True.

    dtype support::

        See ``imgaug.augmenters.arithmetic.AddElementwise``.

    Parameters
    ----------
    lam : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Lambda parameter of the poisson distribution. Recommended values are around ``0.0`` to ``10.0``.

            * 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.

    per_channel : bool or float, optional
        Whether to use the same noise value per pixel 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.

    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.Func(lam=5.0)

    Adds poisson noise sampled from ``Poisson(5.0)`` to images.

    >>> aug = iaa.Func(lam=(0.0, 10.0))

    Adds poisson noise sampled from ``Poisson(x)`` to images, where ``x`` is randomly sampled per image from the
    interval ``[0.0, 10.0]``.

    >>> aug = iaa.Func(lam=5.0, per_channel=True)

    Adds poisson noise sampled from ``Poisson(5.0)`` to images,
    where the values are different per pixel *and* channel (e.g. a
    different one for red, green and blue channels for the same pixel).

    >>> aug = iaa.Func(lam=(0.0, 10.0), per_channel=True)

    Adds poisson noise sampled from ``Poisson(x)`` to images,
    with ``x`` being sampled from ``uniform(0.0, 10.0)`` per image, pixel and channel.
    This is the *recommended* configuration.

    >>> aug = iaa.Func(lam=2, per_channel=0.5)

    Adds poisson noise sampled from the distribution ``Poisson(2)`` to images,
    where the values are sometimes (50 percent of all cases) the same
    per pixel for all channels and sometimes different (other 50 percent).

    """
    arg_5 = iap.handle_continuous_param(arg_0, "lam", value_range=(0, None), tuple_to_uniform=True,
                                       list_to_choice=True)

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

    return AddElementwise(iap.RandomSign(iap.Poisson(arg_0=arg_5)), arg_1=arg_1, arg_2=arg_2,
                          arg_3=arg_3, arg_4=arg_4)


def Func(arg_0=0, arg_1=False, arg_2=None, arg_3=False, arg_4=None):
    """
    Augmenter that sets a certain fraction of pixels in images to zero.

    dtype support::

        See ``imgaug.augmenters.arithmetic.MultiplyElementwise``.

    Parameters
    ----------
    p : float or tuple of float or imgaug.parameters.StochasticParameter, optional
        The probability of any pixel being dropped (i.e. set to zero).

            * If a float, then that value will be used for all images. A value
              of 1.0 would mean that all pixels will be dropped and 0.0 that
              no pixels would be dropped. A value of 0.05 corresponds to 5
              percent of all pixels dropped.
            * If a tuple ``(a, b)``, then a value p will be sampled from the
              range ``a <= p <= b`` per image and be used as the pixel's dropout
              probability.
            * If a StochasticParameter, then this parameter will be used to
              determine per pixel whether it should be dropped (sampled value
              of 0) or shouldn't (sampled value of 1).
              If you instead want to provide the probability as a stochastic
              parameter, you can usually do ``imgaug.parameters.Binomial(1-p)``
              to convert parameter `p` to a 0/1 representation.

    per_channel : bool or float, optional
        Whether to use the same value (is dropped / is not dropped)
        for all channels of a pixel (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.

    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.Func(0.02)

    drops 2 percent of all pixels.

    >>> aug = iaa.Func((0.0, 0.05))

    drops in each image a random fraction of all pixels, where the fraction
    is in the range ``0.0 <= x <= 0.05``.

    >>> aug = iaa.Func(0.02, per_channel=True)

    drops 2 percent of all pixels in a channel-wise fashion, i.e. it is unlikely
    for any pixel to have all channels set to zero (black pixels).

    >>> aug = iaa.Func(0.02, per_channel=0.5)

    same as previous example, but the `per_channel` feature is only active
    for 50 percent of all images.

    """
    if ia.is_single_number(arg_0):
        arg_5 = iap.Binomial(1 - arg_0)
    elif ia.is_iterable(arg_0):
        ia.do_assert(len(arg_0) == 2)
        ia.do_assert(arg_0[0] < arg_0[1])
        ia.do_assert(0 <= arg_0[0] <= 1.0)
        ia.do_assert(0 <= arg_0[1] <= 1.0)
        arg_5 = iap.Binomial(iap.Uniform(1 - arg_0[1], 1 - arg_0[0]))
    elif isinstance(arg_0, iap.StochasticParameter):
        arg_5 = arg_0
    else:
        raise Exception("Expected p to be float or int or StochasticParameter, got %s." % (type(arg_0),))

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

    return MultiplyElementwise(arg_5, arg_1=arg_1, arg_2=arg_2, arg_3=arg_3,
                               arg_4=arg_4)


def Func(arg_0=0, arg_1=None, arg_2=False, arg_3=None):
    """
    Creates an augmenter to apply impulse noise to an image.

    This is identical to ``SaltAndPepper``, except that per_channel is always set to True.

    dtype support::

        See ``imgaug.augmenters.arithmetic.SaltAndPepper``.

    """
    return SaltAndPepper(arg_0=arg_0, per_channel=True, arg_1=arg_1, arg_2=arg_2, arg_3=arg_3)


def Func(arg_0=0, arg_1=False, arg_2=None, arg_3=False, arg_4=None):
    """
    Adds salt and pepper noise to an image, i.e. some white-ish and black-ish pixels.

    dtype support::

        See ``imgaug.augmenters.arithmetic.ReplaceElementwise``.

    Parameters
    ----------
    p : float or tuple of float or list of float or imgaug.parameters.StochasticParameter, optional
        Probability of changing a pixel to salt/pepper noise.

            * If a float, then that value will be used for all images as the
              probability.
            * If a tuple ``(a, b)``, then a probability will be sampled per image
              from the range ``a <= x <= b``.
            * If a list, then a random value will be sampled from that list
              per image.
            * If a StochasticParameter, then this parameter will be used as
              the *mask*, i.e. it is expected to contain values between
              0.0 and 1.0, where 1.0 means that salt/pepper is to be added
              at that location.

    per_channel : bool or float, optional
        Whether to use the same value 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.

    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.Func(0.05)

    Replaces 5 percent of all pixels with salt/pepper.

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

    return ReplaceElementwise(
        mask=arg_0,
        replacement=iap.Beta(0.5, 0.5) * 255,
        arg_1=arg_1,
        arg_2=arg_2,
        arg_3=arg_3,
        arg_4=arg_4
    )


def Func(arg_0=0, arg_1=False, arg_2=None, arg_3=False, arg_4=None):
    """
    Adds pepper noise to an image, i.e. black-ish pixels.

    This is similar to dropout, but slower and the black pixels are not uniformly black.

    dtype support::

        See ``imgaug.augmenters.arithmetic.ReplaceElementwise``.

    Parameters
    ----------
    p : float or tuple of float or list of float or imgaug.parameters.StochasticParameter, optional
        Probability of changing a pixel to pepper noise.

            * If a float, then that value will be used for all images as the
              probability.
            * If a tuple ``(a, b)``, then a probability will be sampled per image
              from the range ``a <= x <= b``.
            * If a list, then a random value will be sampled from that list
              per image.
            * If a StochasticParameter, then this parameter will be used as
              the *mask*, i.e. it is expected to contain values between
              0.0 and 1.0, where 1.0 means that pepper is to be added
              at that location.

    per_channel : bool or float, optional
        Whether to use the same value 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.

    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.Func(0.05)

    Replaces 5 percent of all pixels with pepper.

    """

    arg_5 = iap.ForceSign(
        iap.Beta(0.5, 0.5) - 0.5,
        positive=False,
        mode="invert"
    ) + 0.5
    arg_6 = arg_5 * 255

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

    return ReplaceElementwise(
        mask=arg_0,
        arg_6=arg_6,
        arg_1=arg_1,
        arg_2=arg_2,
        arg_3=arg_3,
        arg_4=arg_4
    )


def Func(arg_0=0, arg_1=None, arg_2=None, arg_3=False, arg_4=4, arg_5=None, arg_6=False,
                 arg_7=None):
    """
    Adds coarse pepper noise to an image, i.e. rectangles that contain noisy black-ish pixels.

    dtype support::

        See ``imgaug.augmenters.arithmetic.ReplaceElementwise``.

    Parameters
    ----------
    p : float or tuple of float or list of float or imgaug.parameters.StochasticParameter, optional
        Probability of changing a pixel to pepper noise.

            * If a float, then that value will be used for all images as the
              probability.
            * If a tuple ``(a, b)``, then a probability will be sampled per image
              from the range ``a <= x <= b.``
            * If a list, then a random value will be sampled from that list
              per image.
            * If a StochasticParameter, then this parameter will be used as
              the *mask*, i.e. it is expected to contain values between
              0.0 and 1.0, where 1.0 means that pepper is to be added
              at that location.

    size_px : int or tuple of int or imgaug.parameters.StochasticParameter, optional
        The size of the lower resolution image from which to sample the noise
        mask in absolute pixel dimensions.

            * If an integer, then that size will be used for both height and
              width. E.g. a value of 3 would lead to a ``3x3`` mask, which is then
              upsampled to ``HxW``, where ``H`` is the image size and W the image width.
            * If a tuple ``(a, b)``, then two values ``M``, ``N`` will be sampled from the
              range ``[a..b]`` and the mask will be generated at size ``MxN``, then
              upsampled to ``HxW``.
            * If a StochasticParameter, then this parameter will be used to
              determine the sizes. It is expected to be discrete.

    size_percent : float or tuple of float or imgaug.parameters.StochasticParameter, optional
        The size of the lower resolution image from which to sample the noise
        mask *in percent* of the input image.

            * If a float, then that value will be used as the percentage of the
              height and width (relative to the original size). E.g. for value
              p, the mask will be sampled from ``(p*H)x(p*W)`` and later upsampled
              to ``HxW``.
            * If a tuple ``(a, b)``, then two values ``m``, ``n`` will be sampled from the
              interval ``(a, b)`` and used as the percentages, i.e the mask size
              will be ``(m*H)x(n*W)``.
            * If a StochasticParameter, then this parameter will be used to
              sample the percentage values. It is expected to be continuous.

    per_channel : bool or float, optional
        Whether to use the same value (is dropped / is not dropped)
        for all channels of a pixel (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.

    min_size : int, optional
        Minimum size of the low resolution mask, both width and height. If
        `size_percent` or `size_px` leads to a lower value than this, `min_size`
        will be used instead. This should never have a value of less than 2,
        otherwise one may end up with a 1x1 low resolution mask, leading easily
        to the whole image being replaced.

    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.Func(0.05, size_percent=(0.01, 0.1))

    Replaces 5 percent of all pixels with pepper in an image that has
    1 to 10 percent of the input image size, then upscales the results
    to the input image size, leading to large rectangular areas being replaced.

    """
    arg_8 = iap.handle_probability_param(arg_0, "p", tuple_to_uniform=True, list_to_choice=True)

    if arg_1 is not None:
        arg_9 = iap.FromLowerResolution(other_param=arg_8, arg_1=arg_1, arg_4=arg_4)
    elif arg_2 is not None:
        arg_9 = iap.FromLowerResolution(other_param=arg_8, arg_2=arg_2, arg_4=arg_4)
    else:
        raise Exception("Either size_px or size_percent must be set.")

    arg_10 = iap.ForceSign(
        iap.Beta(0.5, 0.5) - 0.5,
        positive=False,
        mode="invert"
    ) + 0.5
    arg_11 = arg_10 * 255

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

    return ReplaceElementwise(
        arg_8=arg_9,
        arg_11=arg_11,
        arg_3=arg_3,
        arg_5=arg_5,
        arg_6=arg_6,
        arg_7=arg_7
    )


def Func(arg_0=1.0, arg_1=False, arg_2=None, arg_3=False, arg_4=None):
    """
    Augmenter that changes the contrast of images.

    dtype support:

        See ``imgaug.augmenters.contrast.LinearContrast``.

    Parameters
    ----------
    alpha : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        Strength of the contrast normalization. Higher values than 1.0
        lead to higher contrast, lower values decrease the contrast.

            * If a number, then that value will be used for all images.
            * If a tuple ``(a, b)``, then a value will be sampled per image from
              the range ``a <= x <= b`` and be used as the alpha value.
            * If a list, then a random value will be sampled per image from
              that list.
            * If a StochasticParameter, then this parameter will be used to
              sample the alpha value per image.

    per_channel : bool or float, optional
        Whether to use the same value 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.

    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
    --------
    >>> iaa.Func((0.5, 1.5))

    Decreases oder improves contrast per image by a random factor between
    0.5 and 1.5. The factor 0.5 means that any difference from the center value
    (i.e. 128) will be halved, leading to less contrast.

    >>> iaa.Func((0.5, 1.5), per_channel=0.5)

    Same as before, but for 50 percent of all images the normalization is done
    independently per channel (i.e. factors can vary per channel for the same
    image). In the other 50 percent of all images, the factor is the same for
    all channels.

    """
    # placed here to avoid cyclic dependency
    from . import contrast as contrast_lib
    return contrast_lib.LinearContrast(arg_0=arg_0, arg_1=arg_1, arg_2=arg_2, arg_3=arg_3,
                                       arg_4=arg_4)


def Func(arg_0):
    """
    Checks whether a variable is a numpy integer array.

    Parameters
    ----------
    val
        The variable to check.

    Returns
    -------
    bool
        True if the variable is a numpy integer array. Otherwise False.

    """
    return is_np_array(arg_0) and issubclass(arg_0.dtype.type, np.integer)


def Func(arg_0):
    """
    Checks whether a variable is a numpy float array.

    Parameters
    ----------
    val
        The variable to check.

    Returns
    -------
    bool
        True if the variable is a numpy float array. Otherwise False.

    """
    return is_np_array(arg_0) and issubclass(arg_0.dtype.type, np.floating)


def Func(arg_0, arg_1=False):
    """
    Creates a copy of a random state.

    Parameters
    ----------
    random_state : numpy.random.RandomState
        The random state to copy.

    force_copy : bool, optional
        If True, this function will always create a copy of every random
        state. If False, it will not copy numpy's default random state,
        but all other random states.

    Returns
    -------
    rs_copy : numpy.random.RandomState
        The copied random state.

    """
    if arg_0 == np.random and not arg_1:
        return arg_0
    else:
        arg_2 = dummy_random_state()
        arg_3 = arg_0.get_state()
        arg_2.set_state(arg_3)
        return arg_2


def Func(arg_0, arg_1=1):
    """
    Create N new random states based on an existing random state or seed.

    Parameters
    ----------
    random_state : numpy.random.RandomState
        Random state or seed from which to derive new random states.

    n : int, optional
        Number of random states to derive.

    Returns
    -------
    list of numpy.random.RandomState
        Derived random states.

    """
    arg_2 = arg_0.randint(SEED_MIN_VALUE, SEED_MAX_VALUE, 1)[0]
    return [new_random_state(arg_2+arg_3) for arg_3 in sm.xrange(arg_1)]


def Func(arg_0):
    """
    Generate a normalized rectangle to be extract from the standard quokka image.

    Parameters
    ----------
    extract : 'square' or tuple of number or imgaug.BoundingBox or imgaug.BoundingBoxesOnImage
        Unnormalized representation of the image subarea to be extracted.

            * If string ``square``, then a squared area ``(x: 0 to max 643, y: 0 to max 643)``
              will be extracted from the image.
            * If a tuple, then expected to contain four numbers denoting ``x1``, ``y1``, ``x2``
              and ``y2``.
            * If a BoundingBox, then that bounding box's area will be extracted from the image.
            * If a BoundingBoxesOnImage, then expected to contain exactly one bounding box
              and a shape matching the full image dimensions (i.e. (643, 960, *)). Then the
              one bounding box will be used similar to BoundingBox.

    Returns
    -------
    bb : imgaug.BoundingBox
        Normalized representation of the area to extract from the standard quokka image.

    """
    # TODO get rid of this deferred import
    from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage

    if arg_0 == "square":
        arg_1 = BoundingBox(x1=0, y1=0, x2=643, y2=643)
    elif isinstance(arg_0, tuple) and len(arg_0) == 4:
        arg_1 = BoundingBox(x1=arg_0[0], y1=arg_0[1], x2=arg_0[2], y2=arg_0[3])
    elif isinstance(arg_0, BoundingBox):
        arg_1 = arg_0
    elif isinstance(arg_0, BoundingBoxesOnImage):
        do_assert(len(arg_0.bounding_boxes) == 1)
        do_assert(arg_0.shape[0:2] == (643, 960))
        arg_1 = arg_0.bounding_boxes[0]
    else:
        raise Exception(
            "Expected 'square' or tuple of four entries or BoundingBox or BoundingBoxesOnImage "
            + "for parameter 'extract', got %s." % (type(arg_0),)
        )
    return arg_1


def Func(arg_0, arg_1):
    """
    Computes the intended new shape of an image-like array after resizing.

    Parameters
    ----------
    from_shape : tuple or ndarray
        Old shape of the array. Usually expected to be a tuple of form ``(H, W)`` or ``(H, W, C)`` or
        alternatively an array with two or three dimensions.

    to_shape : None or tuple of ints or tuple of floats or int or float or ndarray
        New shape of the array.

            * If None, then `from_shape` will be used as the new shape.
            * If an int ``V``, then the new shape will be ``(V, V, [C])``, where ``C`` will be added if it
              is part of `from_shape`.
            * If a float ``V``, then the new shape will be ``(H*V, W*V, [C])``, where ``H`` and ``W`` are the old
              height/width.
            * If a tuple ``(H', W', [C'])`` of ints, then ``H'`` and ``W'`` will be used as the new height
              and width.
            * If a tuple ``(H', W', [C'])`` of floats (except ``C``), then ``H'`` and ``W'`` will
              be used as the new height and width.
            * If a numpy array, then the array's shape will be used.

    Returns
    -------
    to_shape_computed : tuple of int
        New shape.

    """
    if is_np_array(arg_0):
        arg_0 = arg_0.shape
    if is_np_array(arg_1):
        arg_1 = arg_1.shape

    arg_2 = list(arg_0)

    if arg_1 is None:
        pass
    elif isinstance(arg_1, tuple):
        do_assert(len(arg_0) in [2, 3])
        do_assert(len(arg_1) in [2, 3])

        if len(arg_0) == 3 and len(arg_1) == 3:
            do_assert(arg_0[2] == arg_1[2])
        elif len(arg_1) == 3:
            arg_2.append(arg_1[2])

        do_assert(all([arg_3 is None or is_single_number(arg_3) for arg_3 in arg_1[0:2]]),
                  "Expected the first two entries in to_shape to be None or numbers, "
                  + "got types %s." % (str([type(arg_3) for arg_3 in arg_1[0:2]]),))

        for arg_4, arg_5 in enumerate(arg_0[0:2]):
            if arg_1[arg_4] is None:
                arg_2[arg_4] = arg_5
            elif is_single_integer(arg_1[arg_4]):
                arg_2[arg_4] = arg_1[arg_4]
            else:  # float
                arg_2[arg_4] = int(np.round(arg_5 * arg_1[arg_4]))
    elif is_single_integer(arg_1) or is_single_float(arg_1):
        arg_2 = Func(arg_0, (arg_1, arg_1))
    else:
        raise Exception("Expected to_shape to be None or ndarray or tuple of floats or tuple of ints or single int "
                        + "or single float, got %s." % (type(arg_1),))

    return tuple(arg_2)


def Func(arg_0=None, arg_1=None):
    """
    Returns an image of a Func as a numpy array.

    Parameters
    ----------
    size : None or float or tuple of int, optional
        Size of the output image. Input into :func:`imgaug.imgaug.imresize_single_image`.
        Usually expected to be a tuple ``(H, W)``, where ``H`` is the desired height
        and ``W`` is the width. If None, then the image will not be resized.

    extract : None or 'square' or tuple of number or imgaug.BoundingBox or imgaug.BoundingBoxesOnImage
        Subarea of the Func image to extract:

            * If None, then the whole image will be used.
            * If string ``square``, then a squared area ``(x: 0 to max 643, y: 0 to max 643)`` will
              be extracted from the image.
            * If a tuple, then expected to contain four numbers denoting ``x1``, ``y1``, ``x2``
              and ``y2``.
            * If a BoundingBox, then that bounding box's area will be extracted from the image.
            * If a BoundingBoxesOnImage, then expected to contain exactly one bounding box
              and a shape matching the full image dimensions (i.e. ``(643, 960, *)``). Then the
              one bounding box will be used similar to BoundingBox.

    Returns
    -------
    img : (H,W,3) ndarray
        The image array of dtype uint8.

    """
    arg_2 = imageio.imread(QUOKKA_FP, pilmode="RGB")
    if arg_1 is not None:
        arg_3 = _Func_normalize_extract(arg_1)
        arg_2 = arg_3.extract_from_image(arg_2)
    if arg_0 is not None:
        arg_4 = _compute_resized_shape(arg_2.shape, arg_0)
        arg_2 = imresize_single_image(arg_2, arg_4[0:2])
    return arg_2


def Func(arg_0=None, arg_1=None):
    """
    Returns a segmentation map for the standard example quokka image.

    Parameters
    ----------
    size : None or float or tuple of int, optional
        See :func:`imgaug.quokka`.

    extract : None or 'square' or tuple of number or imgaug.BoundingBox or imgaug.BoundingBoxesOnImage
        See :func:`imgaug.quokka`.

    Returns
    -------
    result : imgaug.SegmentationMapOnImage
        Segmentation map object.

    """
    # TODO get rid of this deferred import
    from imgaug.augmentables.segmaps import SegmentationMapOnImage

    with open(QUOKKA_ANNOTATIONS_FP, "r") as f:
        arg_2 = json.load(f)

    arg_3 = []
    arg_4 = []
    for arg_5 in arg_2["polygons"][0]["keypoints"]:
        arg_6 = arg_5["x"]
        arg_7 = arg_5["y"]
        arg_3.append(arg_6)
        arg_4.append(arg_7)

    arg_8 = np.zeros((643, 960, 1), dtype=np.float32)
    arg_9, arg_10 = skimage.draw.polygon(np.array(arg_4), np.array(arg_3), arg_14=arg_8.shape)
    arg_8[arg_9, arg_10] = 1.0

    if arg_1 is not None:
        arg_11 = _quokka_normalize_extract(arg_1)
        arg_8 = arg_11.extract_from_image(arg_8)

    arg_12 = SegmentationMapOnImage(arg_8, arg_14=arg_8.shape[0:2] + (3,))

    if arg_0 is not None:
        arg_13 = _compute_resized_shape(arg_8.shape, arg_0)
        arg_12 = arg_12.resize(arg_13[0:2])
        arg_12.shape = tuple(arg_13[0:2]) + (3,)

    return arg_12


def Func(arg_0=None, arg_1=None):
    """
    Returns example keypoints on the standard example quokke image.

    The keypoints cover the eyes, ears, nose and paws.

    Parameters
    ----------
    size : None or float or tuple of int or tuple of float, optional
        Size of the output image on which the keypoints are placed. If None, then the keypoints
        are not projected to any new size (positions on the original image are used).
        Floats lead to relative size changes, ints to absolute sizes in pixels.

    extract : None or 'square' or tuple of number or imgaug.BoundingBox or imgaug.BoundingBoxesOnImage
        Subarea to extract from the image. See :func:`imgaug.quokka`.

    Returns
    -------
    kpsoi : imgaug.KeypointsOnImage
        Example keypoints on the quokka image.

    """
    # TODO get rid of this deferred import
    from imgaug.augmentables.kps import Keypoint, KeypointsOnImage

    arg_2, arg_3 = 0, 0
    if arg_1 is not None:
        arg_4 = _quokka_normalize_extract(arg_1)
        arg_2 = arg_4.x1
        arg_3 = arg_4.y1
    with open(QUOKKA_ANNOTATIONS_FP, "r") as f:
        arg_5 = json.load(f)
    arg_6 = []
    for arg_7 in arg_5["keypoints"]:
        arg_6.append(Keypoint(x=arg_7["x"] - arg_2, y=arg_7["y"] - arg_3))
    if arg_1 is not None:
        arg_8 = (arg_4.height, arg_4.width, 3)
    else:
        arg_8 = (643, 960, 3)
    arg_9 = KeypointsOnImage(arg_6, arg_8=arg_8)
    if arg_0 is not None:
        arg_10 = _compute_resized_shape(arg_8, arg_0)
        arg_9 = arg_9.on(arg_10)
    return arg_9


def Func(arg_0=None, arg_1=None):
    """
    Returns example bounding boxes on the standard example quokke image.

    Currently only a single bounding box is returned that covers the quokka.

    Parameters
    ----------
    size : None or float or tuple of int or tuple of float, optional
        Size of the output image on which the BBs are placed. If None, then the BBs
        are not projected to any new size (positions on the original image are used).
        Floats lead to relative size changes, ints to absolute sizes in pixels.

    extract : None or 'square' or tuple of number or imgaug.BoundingBox or imgaug.BoundingBoxesOnImage
        Subarea to extract from the image. See :func:`imgaug.quokka`.

    Returns
    -------
    bbsoi : imgaug.BoundingBoxesOnImage
        Example BBs on the quokka image.

    """
    # TODO get rid of this deferred import
    from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage

    arg_2, arg_3 = 0, 0
    if arg_1 is not None:
        arg_4 = _quokka_normalize_extract(arg_1)
        arg_2 = arg_4.x1
        arg_3 = arg_4.y1
    with open(QUOKKA_ANNOTATIONS_FP, "r") as f:
        arg_5 = json.load(f)
    arg_6 = []
    for arg_7 in arg_5["bounding_boxes"]:
        arg_6.append(
            BoundingBox(
                x1=arg_7["x1"] - arg_2,
                y1=arg_7["y1"] - arg_3,
                x2=arg_7["x2"] - arg_2,
                y2=arg_7["y2"] - arg_3
            )
        )
    if arg_1 is not None:
        arg_8 = (arg_4.height, arg_4.width, 3)
    else:
        arg_8 = (643, 960, 3)
    arg_9 = BoundingBoxesOnImage(arg_6, arg_8=arg_8)
    if arg_0 is not None:
        arg_10 = _compute_resized_shape(arg_8, arg_0)
        arg_9 = arg_9.on(arg_10)
    return arg_9


def Func(arg_0=None, arg_1=None):
    """
    Returns example polygons on the standard example quokke image.

    The result contains one polygon, covering the quokka's outline.

    Parameters
    ----------
    size : None or float or tuple of int or tuple of float, optional
        Size of the output image on which the polygons are placed. If None,
        then the polygons are not projected to any new size (positions on the
        original image are used). Floats lead to relative size changes, ints
        to absolute sizes in pixels.

    extract : None or 'square' or tuple of number or imgaug.BoundingBox or \
              imgaug.BoundingBoxesOnImage
        Subarea to extract from the image. See :func:`imgaug.quokka`.

    Returns
    -------
    psoi : imgaug.PolygonsOnImage
        Example polygons on the quokka image.

    """
    # TODO get rid of this deferred import
    from imgaug.augmentables.polys import Polygon, PolygonsOnImage

    arg_2, arg_3 = 0, 0
    if arg_1 is not None:
        arg_4 = _quokka_normalize_extract(arg_1)
        arg_2 = arg_4.x1
        arg_3 = arg_4.y1
    with open(QUOKKA_ANNOTATIONS_FP, "r") as f:
        arg_5 = json.load(f)
    arg_6 = []
    for arg_7 in arg_5["polygons"]:
        arg_6.append(
            Polygon([(arg_8["x"] - arg_2, arg_8["y"] - arg_3)
                    for arg_8 in arg_7["keypoints"]])
        )
    if arg_1 is not None:
        arg_9 = (arg_4.height, arg_4.width, 3)
    else:
        arg_9 = (643, 960, 3)
    arg_10 = PolygonsOnImage(arg_6, arg_9=arg_9)
    if arg_0 is not None:
        arg_11 = _compute_resized_shape(arg_9, arg_0)
        arg_10 = arg_10.on(arg_11)
    return arg_10


def Func(arg_0, arg_1):
    """
    Returns the angle in radians between vectors `v1` and `v2`.

    From http://stackoverflow.com/questions/2827393/angles-between-two-n-dimensional-vectors-in-python

    Parameters
    ----------
    v1 : (N,) ndarray
        First vector.

    v2 : (N,) ndarray
        Second vector.

    Returns
    -------
    out : float
        Angle in radians.

    Examples
    --------
    >>> Func(np.float32([1, 0, 0]), np.float32([0, 1, 0]))
    1.570796...

    >>> Func(np.float32([1, 0, 0]), np.float32([1, 0, 0]))
    0.0

    >>> Func(np.float32([1, 0, 0]), np.float32([-1, 0, 0]))
    3.141592...

    """
    arg_2 = np.linalg.norm(arg_0)
    arg_3 = np.linalg.norm(arg_1)
    arg_4 = (arg_0 / arg_2) if arg_2 > 0 else np.float32(arg_0) * 0
    arg_5 = (arg_1 / arg_3) if arg_3 > 0 else np.float32(arg_1) * 0
    return np.arccos(np.clip(np.dot(arg_4, arg_5), -1.0, 1.0))


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5, arg_6, arg_7):
    """
    Compute the intersection point of two lines.

    Taken from https://stackoverflow.com/a/20679579 .

    Parameters
    ----------
    x1 : number
        x coordinate of the first point on line 1. (The lines extends beyond this point.)

    y1 : number
        y coordinate of the first point on line 1. (The lines extends beyond this point.)

    x2 : number
        x coordinate of the second point on line 1. (The lines extends beyond this point.)

    y2 : number
        y coordinate of the second point on line 1. (The lines extends beyond this point.)

    x3 : number
        x coordinate of the first point on line 2. (The lines extends beyond this point.)

    y3 : number
        y coordinate of the first point on line 2. (The lines extends beyond this point.)

    x4 : number
        x coordinate of the second point on line 2. (The lines extends beyond this point.)

    y4 : number
        y coordinate of the second point on line 2. (The lines extends beyond this point.)

    Returns
    -------
    tuple of number or bool
        The coordinate of the intersection point as a tuple ``(x, y)``.
        If the lines are parallel (no intersection point or an infinite number of them), the result is False.

    """
    def _make_line(arg_8, arg_9):
        arg_10 = (arg_8[1] - arg_9[1])
        arg_11 = (arg_9[0] - arg_8[0])
        arg_12 = (arg_8[0]*arg_9[1] - arg_9[0]*arg_8[1])
        return arg_10, arg_11, -arg_12

    arg_13 = _make_line((arg_0, arg_1), (arg_2, arg_3))
    arg_14 = _make_line((arg_4, arg_5), (arg_6, arg_7))

    arg_15 = arg_13[0] * arg_14[1] - arg_13[1] * arg_14[0]
    arg_16 = arg_13[2] * arg_14[1] - arg_13[1] * arg_14[2]
    arg_17 = arg_13[0] * arg_14[2] - arg_13[2] * arg_14[0]
    if arg_15 != 0:
        arg_18 = arg_16 / arg_15
        arg_19 = arg_17 / arg_15
        return arg_18, arg_19
    else:
        return False


def Func(arg_0, arg_1, arg_2=None):
    """
    Resizes a single image.

    dtype support::

        See :func:`imgaug.imgaug.imresize_many_images`.

    Parameters
    ----------
    image : (H,W,C) ndarray or (H,W) ndarray
        Array of the image to resize.
        Usually recommended to be of dtype uint8.

    sizes : float or iterable of int or iterable of float
        See :func:`imgaug.imgaug.imresize_many_images`.

    interpolation : None or str or int, optional
        See :func:`imgaug.imgaug.imresize_many_images`.

    Returns
    -------
    out : (H',W',C) ndarray or (H',W') ndarray
        The resized image.

    """
    arg_3 = False
    if arg_0.ndim == 2:
        arg_3 = True
        arg_0 = arg_0[:, :, np.newaxis]
    do_assert(len(arg_0.shape) == 3, arg_0.shape)
    arg_4 = imresize_many_images(arg_0[np.newaxis, :, :, :], arg_1, arg_2=arg_2)
    if arg_3:
        return np.squeeze(arg_4[0, :, :, 0])
    else:
        return arg_4[0, ...]


def Func(arg_0, arg_1):
    """
    Compute the amount of pixels by which an array has to be padded to fulfill an aspect ratio.

    The aspect ratio is given as width/height.
    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
    ----------
    arr : (H,W) ndarray or (H,W,C) ndarray
        Image-like array for which to compute pad amounts.

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

    Returns
    -------
    result : tuple of int
        Required paddign amounts to reach the target aspect ratio, given as a tuple
        of the form ``(top, right, bottom, left)``.

    """
    do_assert(arg_0.ndim in [2, 3])
    do_assert(arg_1 > 0)
    arg_2, arg_3 = arg_0.shape[0:2]
    do_assert(arg_2 > 0)
    arg_4 = arg_3 / arg_2

    arg_5 = 0
    arg_6 = 0
    arg_7 = 0
    arg_8 = 0

    if arg_4 < arg_1:
        # vertical image, height > width
        arg_9 = (arg_1 * arg_2) - arg_3
        arg_6 = int(np.ceil(arg_9 / 2))
        arg_8 = int(np.floor(arg_9 / 2))
    elif arg_4 > arg_1:
        # horizontal image, width > height
        arg_9 = ((1/arg_1) * arg_3) - arg_2
        arg_5 = int(np.floor(arg_9 / 2))
        arg_7 = int(np.ceil(arg_9 / 2))

    return arg_5, arg_6, arg_7, arg_8


def Func(arg_0, arg_1, arg_2, arg_3=0, arg_4=True):
    """
    Resize an array by Funcing values within blocks.

    dtype support::

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

        - (1) results too inaccurate (at least when using np.average as func)
        - (2) Note that scikit-image documentation says that the wrapped Funcing function converts
              inputs to float64. Actual tests showed no indication of that happening (at least when
              using preserve_dtype=True).

    Parameters
    ----------
    arr : (H,W) ndarray or (H,W,C) ndarray
        Image-like array to Func. Ideally of datatype ``numpy.float64``.

    block_size : int or tuple of int
        Spatial size of each group of values to Func, aka kernel size.
        If a single integer, then a symmetric block of that size along height and width will be used.
        If a tuple of two values, it is assumed to be the block size along height and width of the image-like,
        with Funcing happening per channel.
        If a tuple of three values, it is assumed to be the block size along height, width and channels.

    func : callable
        Function to apply to a given block in order to convert it to a single number,
        e.g. :func:`numpy.average`, :func:`numpy.min`, :func:`numpy.max`.

    cval : number, optional
        Value to use in order to pad the array along its border if the array cannot be divided
        by `block_size` without remainder.

    preserve_dtype : bool, optional
        Whether to convert the array back to the input datatype if it is changed away from
        that in the Funcing process.

    Returns
    -------
    arr_reduced : (H',W') ndarray or (H',W',C') ndarray
        Array after Funcing.

    """
    # TODO find better way to avoid circular import
    from . import dtypes as iadt
    iadt.gate_dtypes(arg_0,
                     allowed=["bool", "uint8", "uint16", "uint32", "int8", "int16", "int32",
                              "float16", "float32", "float64", "float128"],
                     disallowed=["uint64", "uint128", "uint256", "int64", "int128", "int256",
                                 "float256"],
                     augmenter=None)

    do_assert(arg_0.ndim in [2, 3])
    arg_5 = is_single_integer(arg_1) and arg_1 >= 1
    arg_6 = is_iterable(arg_1) and len(arg_1) in [2, 3] \
        and [is_single_integer(val) and val >= 1 for val in arg_1]
    do_assert(arg_5 or arg_6)

    if is_single_integer(arg_1):
        arg_1 = [arg_1, arg_1]
    if len(arg_1) < arg_0.ndim:
        arg_1 = list(arg_1) + [1]

    arg_7 = arg_0.dtype
    arg_8 = skimage.measure.block_reduce(arg_0, tuple(arg_1), arg_2, arg_3=arg_3)
    if arg_4 and arg_8.dtype.type != arg_7:
        arg_8 = arg_8.astype(arg_7)
    return arg_8


def Func(arg_0, arg_1, arg_2=0, arg_3=True):
    """
    Resize an array using average pooling.

    dtype support::

        See :func:`imgaug.imgaug.pool`.

    Parameters
    ----------
    arr : (H,W) ndarray or (H,W,C) ndarray
        Image-like array to pool. See :func:`imgaug.pool` for details.

    block_size : int or tuple of int or tuple of int
        Size of each block of values to pool. See :func:`imgaug.pool` for details.

    cval : number, optional
        Padding value. See :func:`imgaug.pool` for details.

    preserve_dtype : bool, optional
        Whether to preserve the input array dtype. See :func:`imgaug.pool` for details.

    Returns
    -------
    arr_reduced : (H',W') ndarray or (H',W',C') ndarray
        Array after average pooling.

    """
    return pool(arg_0, arg_1, np.average, arg_2=arg_2, arg_3=arg_3)


def Func(arg_0, arg_1, arg_2=0, arg_3=True):
    """
    Resize an array using max-pooling.

    dtype support::

        See :func:`imgaug.imgaug.pool`.

    Parameters
    ----------
    arr : (H,W) ndarray or (H,W,C) ndarray
        Image-like array to pool. See :func:`imgaug.pool` for details.

    block_size : int or tuple of int or tuple of int
        Size of each block of values to pool. See `imgaug.pool` for details.

    cval : number, optional
        Padding value. See :func:`imgaug.pool` for details.

    preserve_dtype : bool, optional
        Whether to preserve the input array dtype. See :func:`imgaug.pool` for details.

    Returns
    -------
    arr_reduced : (H',W') ndarray or (H',W',C') ndarray
        Array after max-pooling.

    """
    return pool(arg_0, arg_1, np.max, arg_2=arg_2, arg_3=arg_3)


def Func(arg_0, arg_1=None, arg_2=None):
    """
    Converts the input images to a grid image and shows it in a new window.

    dtype support::

        minimum of (
            :func:`imgaug.imgaug.draw_grid`,
            :func:`imgaug.imgaug.imshow`
        )

    Parameters
    ----------
    images : (N,H,W,3) ndarray or iterable of (H,W,3) array
        See :func:`imgaug.draw_grid`.

    rows : None or int, optional
        See :func:`imgaug.draw_grid`.

    cols : None or int, optional
        See :func:`imgaug.draw_grid`.

    """
    arg_3 = draw_grid(arg_0, arg_1=arg_1, arg_2=arg_2)
    imshow(arg_3)


def Func(arg_0, arg_1=arg_2):
    """
    Shows an image in a window.

    dtype support::

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

    Parameters
    ----------
    image : (H,W,3) ndarray
        Image to show.

    backend : {'matplotlib', 'cv2'}, optional
        Library to use to show the image. May be either matplotlib or OpenCV ('cv2').
        OpenCV tends to be faster, but apparently causes more technical issues.

    """
    do_assert(arg_1 in ["matplotlib", "cv2"], "Expected backend 'matplotlib' or 'cv2', got %s." % (arg_1,))

    if arg_1 == "cv2":
        arg_3 = arg_0
        if arg_0.ndim == 3 and arg_0.shape[2] in [3, 4]:
            arg_3 = arg_0[..., 0:3][..., ::-1]

        arg_4 = "imgaug-default-window"
        cv2.namedWindow(arg_4, cv2.WINDOW_NORMAL)
        cv2.Func(arg_4, arg_3)
        cv2.waitKey(0)
        cv2.destroyWindow(arg_4)
    else:
        # import only when necessary (faster startup; optional dependency; less fragile -- see issue #225)
        import matplotlib.pyplot as plt

        arg_5 = 96
        arg_6, arg_7 = arg_0.shape[0] / arg_5, arg_0.shape[1] / arg_5
        arg_7 = max(arg_7, 6)  # if the figure is too narrow, the footer may appear and make the fig suddenly wider (ugly)
        arg_8, arg_9 = plt.subplots(figsize=(arg_7, arg_6), arg_5=arg_5)
        arg_8.canvas.set_window_title("imgaug.Func(%s)" % (arg_0.shape,))
        arg_9.Func(arg_0, cmap="gray")  # cmap is only activate for grayscale images
        plt.show()


def Func(arg_0, arg_1=2):
    """Generate a non-silent deprecation warning with stacktrace.

    The used warning is ``imgaug.imgaug.DeprecationWarning``.

    Parameters
    ----------
    msg : str
        The message of the warning.

    stacklevel : int, optional
        How many steps above this function to "jump" in the stacktrace for
        the displayed file and line number of the error message.
        Usually 2.

    """
    import warnings
    warnings.warn(arg_0,
                  category=DeprecationWarning,
                  arg_1=arg_1)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4):
        """
        Returns whether an augmenter may be executed.

        Returns
        -------
        bool
            If True, the augmenter may be executed. If False, it may not be executed.

        """
        if arg_0.activator is None:
            return arg_4
        else:
            return arg_0.activator(arg_1, arg_2, arg_3, arg_4)


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        A function to be called after the augmentation of images was
        performed.

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

        """
        if arg_0.Funcor is None:
            return arg_1
        else:
            return arg_0.Funcor(arg_1, arg_2, arg_3)


def Func(arg_0, arg_1, arg_2=None, arg_3=None, arg_4=None):
        """
        Augment batches asynchonously.

        Parameters
        ----------
        batches : list of imgaug.augmentables.batches.Batch
            The batches to augment.

        chunksize : None or int, optional
            Rough indicator of how many tasks should be sent to each worker. Increasing this number can improve
            performance.

        callback : None or callable, optional
            Function to call upon finish. See `multiprocessing.Pool`.

        error_callback : None or callable, optional
            Function to call upon errors. See `multiprocessing.Pool`.

        Returns
        -------
        multiprocessing.MapResult
            Asynchonous result. See `multiprocessing.Pool`.

        """
        assert isinstance(arg_1, list), ("Expected to get a list as 'batches', got type %s. "
                                           + "Call imap_batches() if you use generators.") % (type(arg_1),)
        return arg_0.pool.map_async(_Pool_starworker, arg_0._handle_batch_ids(arg_1),
                                   arg_2=arg_2, arg_3=arg_3, arg_4=arg_4)


def Func(arg_0, arg_1, arg_2=1):
        """
        Augment batches from a generator.

        Parameters
        ----------
        batches : generator of imgaug.augmentables.batches.Batch
            The batches to augment, provided as a generator. Each call to the generator should yield exactly one
            batch.

        chunksize : None or int, optional
            Rough indicator of how many tasks should be sent to each worker. Increasing this number can improve
            performance.

        Yields
        ------
        imgaug.augmentables.batches.Batch
            Augmented batch.

        """
        assert ia.is_generator(arg_1), ("Expected to get a generator as 'batches', got type %s. "
                                          + "Call map_batches() if you use lists.") % (type(arg_1),)
        # TODO change this to 'yield from' once switched to 3.3+
        arg_3 = arg_0.pool.imap(_Pool_starworker, arg_0._handle_batch_ids_gen(arg_1), arg_2=arg_2)
        for arg_4 in arg_3:
            yield arg_4


def Func(arg_0):
        """Terminate the pool immediately."""
        if arg_0._pool is not None:
            arg_0._pool.Func()
            arg_0._pool.join()
            arg_0._pool = None


def Func(arg_0):
        """
        Returns a batch from the queue of augmented batches.

        If workers are still running and there are no batches in the queue,
        it will automatically wait for the next batch.

        Returns
        -------
        out : None or imgaug.Batch
            One batch or None if all workers have finished.

        """
        if arg_0.all_finished():
            return None

        arg_1 = arg_0.queue_result.get()
        arg_2 = pickle.loads(arg_1)
        if arg_2 is not None:
            return arg_2
        else:
            arg_0.nb_workers_finished += 1
            if arg_0.nb_workers_finished >= arg_0.nb_workers:
                try:
                    arg_0.queue_source.get(timeout=0.001)  # remove the None from the source queue
                except QueueEmpty:
                    pass
                return None
            else:
                return arg_0.Func()


def Func(arg_0, arg_1="invert", arg_2=2):
    """
    Converts another parameter's results to negative values.

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

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

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

    Examples
    --------
    >>> param = Func(Normal(0, 1), mode="reroll")

    Generates a normal distribution that has only negative values.

    """
    return ForceSign(
        arg_0=arg_0,
        positive=False,
        arg_1=arg_1,
        arg_2=arg_2
    )


def Func(arg_0):
        """
        Estimate the Func of the polygon.

        Returns
        -------
        number
            Area of the polygon.

        """
        if len(arg_0.exterior) < 3:
            raise Exception("Cannot compute the polygon's Func because it contains less than three points.")
        arg_1 = arg_0.to_shapely_polygon()
        return arg_1.Func


def Func(arg_0, arg_1, arg_2):
        """
        Project the polygon onto an image with different shape.

        The relative coordinates of all points remain the same.
        E.g. a point at (x=20, y=20) on an image (width=100, height=200) will be
        Funced on a new image (width=200, height=100) to (x=40, y=10).

        This is intended for cases where the original image is resized.
        It cannot be used for more complex changes (e.g. padding, cropping).

        Parameters
        ----------
        from_shape : tuple of int
            Shape of the original image. (Before resize.)

        to_shape : tuple of int
            Shape of the new image. (After resize.)

        Returns
        -------
        imgaug.Polygon
            Polygon object with new coordinates.

        """
        if arg_1[0:2] == arg_2[0:2]:
            return arg_0.copy()
        arg_3 = arg_0.to_line_string(closed=False).Func(
            arg_1, arg_2)
        return arg_0.copy(exterior=arg_3.coords)


def Func(arg_0, arg_1, arg_2, arg_3=False):
        """
        Find the index of the point within the exterior that is closest to the given coordinates.

        "Closeness" is here defined based on euclidean distance.
        This method will raise an AssertionError if the exterior contains no points.

        Parameters
        ----------
        x : number
            X-coordinate around which to search for close points.

        y : number
            Y-coordinate around which to search for close points.

        return_distance : bool, optional
            Whether to also return the distance of the closest point.

        Returns
        -------
        int
            Index of the closest point.

        number
            Euclidean distance to the closest point.
            This value is only returned if `return_distance` was set to True.

        """
        ia.do_assert(len(arg_0.exterior) > 0)
        arg_4 = []
        for arg_5, arg_6 in arg_0.exterior:
            arg_7 = (arg_5 - arg_1) ** 2 + (arg_6 - arg_2) ** 2
            arg_4.append(arg_7)
        arg_4 = np.sqrt(arg_4)
        arg_8 = np.argmin(arg_4)
        if arg_3:
            return arg_8, arg_4[arg_8]
        return arg_8


def Func(arg_0, arg_1):
        """
        Estimate whether the polygon is fully inside the image area.

        Parameters
        ----------
        image : (H,W,...) ndarray or tuple of int
            Image dimensions to use.
            If an ndarray, its shape will be used.
            If a tuple, it is assumed to represent the image shape and must contain at least two integers.

        Returns
        -------
        bool
            True if the polygon is fully inside the image area.
            False otherwise.

        """
        return not arg_0.is_out_of_image(arg_1, fully=True, partly=True)


def Func(arg_0, arg_1):
        """
        Estimate whether the polygon is at least partially inside the image area.

        Parameters
        ----------
        image : (H,W,...) ndarray or tuple of int
            Image dimensions to use.
            If an ndarray, its shape will be used.
            If a tuple, it is assumed to represent the image shape and must contain at least two integers.

        Returns
        -------
        bool
            True if the polygon is at least partially inside the image area.
            False otherwise.

        """
        return not arg_0.is_out_of_image(arg_1, fully=True, partly=False)


def Func(arg_0, arg_1, arg_2=True, arg_3=False):
        """
        Estimate whether the polygon is partially or fully outside of the image area.

        Parameters
        ----------
        image : (H,W,...) ndarray or tuple of int
            Image dimensions to use.
            If an ndarray, its shape will be used.
            If a tuple, it is assumed to represent the image shape and must contain at least two integers.

        fully : bool, optional
            Whether to return True if the polygon is fully outside of the image area.

        partly : bool, optional
            Whether to return True if the polygon is at least partially outside fo the image area.

        Returns
        -------
        bool
            True if the polygon is partially/fully outside of the image area, depending
            on defined parameters. False otherwise.

        """
        # TODO this is inconsistent with line strings, which return a default
        #      value in these cases
        if len(arg_0.exterior) == 0:
            raise Exception("Cannot determine whether the polygon is inside the image, because it contains no points.")
        arg_4 = arg_0.to_line_string()
        return arg_4.Func(arg_1, arg_2=arg_2, arg_3=arg_3)


def Func(arg_0, arg_1):
        """
        Extract the image pixels within the polygon.

        This function will zero-pad the image if the polygon is partially/fully outside of
        the image.

        Parameters
        ----------
        image : (H,W) ndarray or (H,W,C) ndarray
            The image from which to extract the pixels within the polygon.

        Returns
        -------
        result : (H',W') ndarray or (H',W',C) ndarray
            Pixels within the polygon. Zero-padded if the polygon is partially/fully
            outside of the image.

        """
        ia.do_assert(arg_1.ndim in [2, 3])
        if len(arg_0.exterior) <= 2:
            raise Exception("Polygon must be made up of at least 3 points to extract its area from an image.")

        arg_2 = arg_0.to_bounding_box()
        arg_3 = arg_2.Func(arg_1)
        if arg_0.is_out_of_image(arg_1, fully=True, partly=False):
            return arg_3

        arg_4 = arg_0.xx_int
        arg_5 = arg_0.yy_int
        arg_6 = arg_4 - np.min(arg_4)
        arg_7 = arg_5 - np.min(arg_5)
        arg_8 = np.max(arg_7)
        arg_9 = np.max(arg_6)

        arg_10, arg_11 = skimage.draw.polygon(arg_7, arg_6, shape=(arg_8, arg_9))

        arg_12 = np.zeros((arg_8, arg_9), dtype=np.bool)
        arg_12[arg_10, arg_11] = True

        if arg_1.ndim == 3:
            arg_12 = np.tile(arg_12[:, :, np.newaxis], (1, 1, arg_1.shape[2]))

        return arg_3 * arg_12


def Func(arg_0, arg_1):
        """
        Set the first point of the exterior to the given point based on its index.

        Note: This method does *not* work in-place.

        Parameters
        ----------
        point_idx : int
            Index of the desired starting point.

        Returns
        -------
        imgaug.Polygon
            Copy of this polygon with the new point order.

        """
        ia.do_assert(0 <= arg_1 < len(arg_0.exterior))
        if arg_1 == 0:
            return arg_0.deepcopy()
        arg_2 = np.concatenate(
            (arg_0.exterior[arg_1:, :], arg_0.exterior[:arg_1, :]),
            axis=0
        )
        return arg_0.deepcopy(arg_2=arg_2)


def Func(arg_0):
        """
        Convert this polygon to a Shapely polygon.

        Returns
        -------
        shapely.geometry.Polygon
            The Shapely polygon matching this polygon's exterior.

        """
        # load shapely lazily, which makes the dependency more optional
        import shapely.geometry

        return shapely.geometry.Polygon([(arg_1[0], arg_1[1]) for arg_1 in arg_0.exterior])


def Func(arg_0, arg_1=False, arg_2=0):
        """
        Convert this polygon to a Shapely LineString object.

        Parameters
        ----------
        closed : bool, optional
            Whether to return the line string with the last point being identical to the first point.

        interpolate : int, optional
            Number of points to interpolate between any pair of two consecutive points. These points are added
            to the final line string.

        Returns
        -------
        shapely.geometry.LineString
            The Shapely LineString matching the polygon's exterior.

        """
        return _convert_points_Func(arg_0.exterior, arg_1=arg_1, arg_2=arg_2)


def Func(arg_0, arg_1=True):
        """
        Convert this polygon's `exterior` to a ``LineString`` instance.

        Parameters
        ----------
        closed : bool, optional
            Whether to close the line string, i.e. to add the first point of
            the `exterior` also as the last point at the end of the line string.
            This has no effect if the polygon has a single point or zero
            points.

        Returns
        -------
        imgaug.augmentables.lines.LineString
            Exterior of the polygon as a line string.

        """
        from imgaug.augmentables.lines import LineString
        if not arg_1 or len(arg_0.exterior) <= 1:
            return LineString(arg_0.exterior, label=arg_0.label)
        return LineString(
            np.concatenate([arg_0.exterior, arg_0.exterior[0:1, :]], axis=0),
            label=arg_0.label)


def Func(arg_0, arg_1, arg_2=1e-6, arg_3=8):
        """
        Estimate if this and other polygon's exterior are almost identical.

        The two exteriors can have different numbers of points, but any point
        randomly sampled on the exterior of one polygon should be close to the
        closest point on the exterior of the other polygon.

        Note that this method works approximately. One can come up with
        polygons with fairly different shapes that will still be estimated as
        equal by this method. In practice however this should be unlikely to be
        the case. The probability for something like that goes down as the
        interpolation parameter is increased.

        Parameters
        ----------
        other : imgaug.Polygon or (N,2) ndarray or list of tuple
            The other polygon with which to compare the exterior.
            If this is an ndarray, it is assumed to represent an exterior.
            It must then have dtype ``float32`` and shape ``(N,2)`` with the
            second dimension denoting xy-coordinates.
            If this is a list of tuples, it is assumed to represent an exterior.
            Each tuple then must contain exactly two numbers, denoting
            xy-coordinates.

        max_distance : number, optional
            The maximum euclidean distance between a point on one polygon and
            the closest point on the other polygon. If the distance is exceeded
            for any such pair, the two exteriors are not viewed as equal. The
            points are other the points contained in the polygon's exterior
            ndarray or interpolated points between these.

        points_per_edge : int, optional
            How many points to interpolate on each edge.

        Returns
        -------
        bool
            Whether the two polygon's exteriors can be viewed as equal
            (approximate test).

        """
        if isinstance(arg_1, list):
            arg_1 = Polygon(np.float32(arg_1))
        elif ia.is_np_array(arg_1):
            arg_1 = Polygon(arg_1)
        else:
            assert isinstance(arg_1, Polygon)
            arg_1 = arg_1

        return arg_0.to_line_string(closed=True).coords_almost_equals(
            arg_1.to_line_string(closed=True),
            arg_2=arg_2,
            arg_3=arg_3
        )


def Func(arg_0, arg_1=None, arg_2=None):
        """
        Create a shallow Func of the Polygon object.

        Parameters
        ----------
        exterior : list of imgaug.Keypoint or list of tuple or (N,2) ndarray, optional
            List of points defining the polygon. See :func:`imgaug.Polygon.__init__` for details.

        label : None or str, optional
            If not None, then the label of the copied object will be set to this value.

        Returns
        -------
        imgaug.Polygon
            Shallow Func.

        """
        return arg_0.deepFunc(arg_1=arg_1, arg_2=arg_2)


def Func(arg_0, arg_1=None, arg_2=None):
        """
        Create a deep copy of the Polygon object.

        Parameters
        ----------
        exterior : list of Keypoint or list of tuple or (N,2) ndarray, optional
            List of points defining the polygon. See `imgaug.Polygon.__init__` for details.

        label : None or str
            If not None, then the label of the copied object will be set to this value.

        Returns
        -------
        imgaug.Polygon
            Deep copy.

        """
        return Polygon(
            arg_1=np.copy(arg_0.exterior) if arg_1 is None else arg_1,
            arg_2=arg_0.label if arg_2 is None else arg_2
        )


def Func(arg_0, arg_1=True, arg_2=False):
        """
        Remove all polygons that are fully or partially outside of the image.

        Parameters
        ----------
        fully : bool, optional
            Whether to remove polygons that are fully outside of the image.

        partly : bool, optional
            Whether to remove polygons that are partially outside of the image.

        Returns
        -------
        imgaug.PolygonsOnImage
            Reduced set of polygons, with those that were fully/partially
            outside of the image removed.

        """
        arg_3 = [
            poly for poly in arg_0.polygons
            if not poly.is_out_of_image(arg_0.shape, arg_1=arg_1, arg_2=arg_2)
        ]
        # TODO use deepcopy() here
        return PolygonsOnImage(arg_3, shape=arg_0.shape)


def Func(arg_0):
        """
        Clip off all parts from all polygons that are outside of the image.

        NOTE: The result can contain less polygons than the input did. That
        happens when a polygon is fully outside of the image plane.

        NOTE: The result can also contain *more* polygons than the input
        did. That happens when distinct parts of a polygon are only
        connected by areas that are outside of the image plane and hence will
        be clipped off, resulting in two or more unconnected polygon parts that
        are left in the image plane.

        Returns
        -------
        imgaug.PolygonsOnImage
            Polygons, clipped to fall within the image dimensions. Count of
            output polygons may differ from the input count.

        """
        arg_1 = [
            poly.Func(arg_0.shape)
            for poly
            in arg_0.polygons
            if poly.is_partly_within_image(arg_0.shape)
        ]
        arg_2 = [poly for poly_lst in arg_1 for poly in poly_lst]
        # TODO use deepcopy() here
        return PolygonsOnImage(arg_2, shape=arg_0.shape)


def Func(arg_0):
        """
        Create a deep copy of the PolygonsOnImage object.

        Returns
        -------
        imgaug.PolygonsOnImage
            Deep copy.

        """
        # Manual copy is far faster than Func for PolygonsOnImage,
        # so use manual copy here too
        arg_1 = [poly.Func() for poly in arg_0.polygons]
        return PolygonsOnImage(arg_1, tuple(arg_0.shape))


def Func(arg_0, arg_1=None):
        """
        Create a MultiPolygon from a Shapely MultiPolygon, a Shapely Polygon or a Shapely GeometryCollection.

        This also creates all necessary Polygons contained by this MultiPolygon.

        Parameters
        ----------
        geometry : shapely.geometry.MultiPolygon or shapely.geometry.Polygon\
                   or shapely.geometry.collection.GeometryCollection
            The object to convert to a MultiPolygon.

        label : None or str, optional
            A label assigned to all Polygons within the MultiPolygon.

        Returns
        -------
        imgaug.MultiPolygon
            The derived MultiPolygon.

        """
        # load shapely lazily, which makes the dependency more optional
        import shapely.geometry

        if isinstance(arg_0, shapely.geometry.MultiPolygon):
            return MultiPolygon([Polygon.Func(arg_2, arg_1=arg_1) for arg_2 in arg_0.geoms])
        elif isinstance(arg_0, shapely.geometry.Polygon):
            return MultiPolygon([Polygon.Func(arg_0, arg_1=arg_1)])
        elif isinstance(arg_0, shapely.geometry.collection.GeometryCollection):
            ia.do_assert(all([isinstance(arg_2, shapely.geometry.Polygon) for arg_2 in arg_0.geoms]))
            return MultiPolygon([Polygon.Func(arg_2, arg_1=arg_1) for arg_2 in arg_0.geoms])
        else:
            raise Exception("Unknown datatype '%s'. Expected shapely.geometry.Polygon or "
                            "shapely.geometry.MultiPolygon or "
                            "shapely.geometry.collections.GeometryCollection." % (type(arg_0),))


def Func(arg_0):
        """
        Return a list of unordered intersection points.
        """
        if Real is float:
            return list(arg_0.intersections.keys())
        else:
            return [(float(arg_1[0]), float(arg_1[1])) for arg_1 in arg_0.intersections.keys()]


def Func(arg_0, arg_1, arg_2=arg_3):
        """Get predecessor to key, raises KeyError if key is min key
        or key does not exist.
        """
        arg_4 = arg_0.prev_item(arg_1, arg_2)
        return arg_2 if arg_4 is arg_2 else arg_4[0]


def Func(arg_0, arg_1, arg_2=arg_3):
        """Get successor to key, raises KeyError if key is max key
        or key does not exist.
        """
        arg_4 = arg_0.succ_item(arg_1, arg_2)
        return arg_2 if arg_4 is arg_2 else arg_4[0]


def Func(arg_0, arg_1, arg_2):
        """
        Generate 2D OpenSimplex noise from X,Y coordinates.
        """
        # Place input coordinates onto grid.
        arg_3 = (arg_1 + arg_2) * STRETCH_CONSTANT_2D
        arg_4 = arg_1 + arg_3
        arg_5 = arg_2 + arg_3

        # Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
        arg_6 = floor(arg_4)
        arg_7 = floor(arg_5)

        # Skew out to get actual coordinates of rhombus origin. We'll need these later.
        arg_8 = (arg_6 + arg_7) * SQUISH_CONSTANT_2D
        arg_9 = arg_6 + arg_8
        arg_10 = arg_7 + arg_8

        # Compute grid coordinates relative to rhombus origin.
        arg_11 = arg_4 - arg_6
        arg_12 = arg_5 - arg_7

        # Sum those together to get a value that determines which region we're in.
        arg_13 = arg_11 + arg_12

        # Positions relative to origin point.
        arg_14 = arg_1 - arg_9
        arg_15 = arg_2 - arg_10

        arg_16 = 0

        # Contribution (1,0)
        arg_17 = arg_14 - 1 - SQUISH_CONSTANT_2D
        arg_18 = arg_15 - 0 - SQUISH_CONSTANT_2D
        arg_19 = 2 - arg_17 * arg_17 - arg_18 * arg_18
        arg_20 = arg_0._extrapolate2d
        if arg_19 > 0:
            arg_19 *= arg_19
            arg_16 += arg_19 * arg_19 * arg_20(arg_6 + 1, arg_7 + 0, arg_17, arg_18)

        # Contribution (0,1)
        arg_21 = arg_14 - 0 - SQUISH_CONSTANT_2D
        arg_22 = arg_15 - 1 - SQUISH_CONSTANT_2D
        arg_23 = 2 - arg_21 * arg_21 - arg_22 * arg_22
        if arg_23 > 0:
            arg_23 *= arg_23
            arg_16 += arg_23 * arg_23 * arg_20(arg_6 + 0, arg_7 + 1, arg_21, arg_22)

        if arg_13 <= 1: # We're inside the triangle (2-Simplex) at (0,0)
            arg_24 = 1 - arg_13
            if arg_24 > arg_11 or arg_24 > arg_12: # (0,0) is one of the closest two triangular vertices
                if arg_11 > arg_12:
                    arg_25 = arg_6 + 1
                    arg_26 = arg_7 - 1
                    arg_27 = arg_14 - 1
                    arg_28 = arg_15 + 1
                else:
                    arg_25 = arg_6 - 1
                    arg_26 = arg_7 + 1
                    arg_27 = arg_14 + 1
                    arg_28 = arg_15 - 1
            else: # (1,0) and (0,1) are the closest two vertices.
                arg_25 = arg_6 + 1
                arg_26 = arg_7 + 1
                arg_27 = arg_14 - 1 - 2 * SQUISH_CONSTANT_2D
                arg_28 = arg_15 - 1 - 2 * SQUISH_CONSTANT_2D
        else: # We're inside the triangle (2-Simplex) at (1,1)
            arg_24 = 2 - arg_13
            if arg_24 < arg_11 or arg_24 < arg_12: # (0,0) is one of the closest two triangular vertices
                if arg_11 > arg_12:
                    arg_25 = arg_6 + 2
                    arg_26 = arg_7 + 0
                    arg_27 = arg_14 - 2 - 2 * SQUISH_CONSTANT_2D
                    arg_28 = arg_15 + 0 - 2 * SQUISH_CONSTANT_2D
                else:
                    arg_25 = arg_6 + 0
                    arg_26 = arg_7 + 2
                    arg_27 = arg_14 + 0 - 2 * SQUISH_CONSTANT_2D
                    arg_28 = arg_15 - 2 - 2 * SQUISH_CONSTANT_2D
            else: # (1,0) and (0,1) are the closest two vertices.
                arg_27 = arg_14
                arg_28 = arg_15
                arg_25 = arg_6
                arg_26 = arg_7
            arg_6 += 1
            arg_7 += 1
            arg_14 = arg_14 - 1 - 2 * SQUISH_CONSTANT_2D
            arg_15 = arg_15 - 1 - 2 * SQUISH_CONSTANT_2D

        # Contribution (0,0) or (1,1)
        arg_29 = 2 - arg_14 * arg_14 - arg_15 * arg_15
        if arg_29 > 0:
            arg_29 *= arg_29
            arg_16 += arg_29 * arg_29 * arg_20(arg_6, arg_7, arg_14, arg_15)

        # Extra Vertex
        arg_30 = 2 - arg_27 * arg_27 - arg_28 * arg_28
        if arg_30 > 0:
            arg_30 *= arg_30
            arg_16 += arg_30 * arg_30 * arg_20(arg_25, arg_26, arg_27, arg_28)

        return arg_16 / NORM_CONSTANT_2D


def Func(arg_0):
        """Get the Func of a bounding box encapsulating the line."""
        if len(arg_0.coords) <= 1:
            return 0
        return np.max(arg_0.yy) - np.min(arg_0.yy)


def Func(arg_0):
        """Get the Func of a bounding box encapsulating the line."""
        if len(arg_0.coords) <= 1:
            return 0
        return np.max(arg_0.xx) - np.min(arg_0.xx)