def Positive(other_param, mode="invert", reroll_count_max=2):
    """
    Converts another parameter's results to positive values.

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

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

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

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

    Generates a normal distribution that has only positive values.

    """
    return ForceSign(
        other_param=other_param,
        positive=True,
        mode=mode,
        reroll_count_max=reroll_count_max
    )

def Positive ( other_param , mode = "invert" , reroll_count_max = 2 ) : return ForceSign ( other_param = other_param , positive = True , mode = mode , reroll_count_max = reroll_count_max )

Converts another parameter s results to positive values .


def Negative(other_param, mode="invert", reroll_count_max=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 = Negative(Normal(0, 1), mode="reroll")

    Generates a normal distribution that has only negative values.

    """
    return ForceSign(
        other_param=other_param,
        positive=False,
        mode=mode,
        reroll_count_max=reroll_count_max
    )

def Negative ( other_param , mode = "invert" , reroll_count_max = 2 ) : return ForceSign ( other_param = other_param , positive = False , mode = mode , reroll_count_max = reroll_count_max )

Converts another parameter s results to negative values .


def area(self):
        """
        Estimate the area of the polygon.

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

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


def project(self, from_shape, to_shape):
        """
        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
        projected 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 from_shape[0:2] == to_shape[0:2]:
            return self.copy()
        ls_proj = self.to_line_string(closed=False).project(
            from_shape, to_shape)
        return self.copy(exterior=ls_proj.coords)

def project ( self , from_shape , to_shape ) : if from_shape [ 0 : 2 ] == to_shape [ 0 : 2 ] : return self . copy ( ) ls_proj = self . to_line_string ( closed = False ) . project ( from_shape , to_shape ) return self . copy ( exterior = ls_proj . coords )

Project the polygon onto an image with different shape .


def find_closest_point_index(self, x, y, return_distance=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(self.exterior) > 0)
        distances = []
        for x2, y2 in self.exterior:
            d = (x2 - x) ** 2 + (y2 - y) ** 2
            distances.append(d)
        distances = np.sqrt(distances)
        closest_idx = np.argmin(distances)
        if return_distance:
            return closest_idx, distances[closest_idx]
        return closest_idx

def find_closest_point_index ( self , x , y , return_distance = False ) : ia . do_assert ( len ( self . exterior ) > 0 ) distances = [ ] for x2 , y2 in self . exterior : d = ( x2 - x ) ** 2 + ( y2 - y ) ** 2 distances . append ( d ) distances = np . sqrt ( distances ) closest_idx = np . argmin ( distances ) if return_distance : return closest_idx , distances [ closest_idx ] return closest_idx

Find the index of the point within the exterior that is closest to the given coordinates .


def is_fully_within_image(self, image):
        """
        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 self.is_out_of_image(image, fully=True, partly=True)

def is_fully_within_image ( self , image ) : return not self . is_out_of_image ( image , fully = True , partly = True )

Estimate whether the polygon is fully inside the image area .


def is_partly_within_image(self, image):
        """
        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 self.is_out_of_image(image, fully=True, partly=False)

def is_partly_within_image ( self , image ) : return not self . is_out_of_image ( image , fully = True , partly = False )

Estimate whether the polygon is at least partially inside the image area .


def is_out_of_image(self, image, fully=True, partly=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(self.exterior) == 0:
            raise Exception("Cannot determine whether the polygon is inside the image, because it contains no points.")
        ls = self.to_line_string()
        return ls.is_out_of_image(image, fully=fully, partly=partly)

Estimate whether the polygon is partially or fully outside of the image area .


def clip_out_of_image(self, image):
        """
        Cut off all parts of the polygon that are outside of the image.

        This operation may lead to new points being created.
        As a single polygon may be split into multiple new polygons, the result
        is always a list, which may contain more than one output polygon.

        This operation will return an empty list if the polygon is completely
        outside of the image plane.

        Parameters
        ----------
        image : (H,W,...) ndarray or tuple of int
            Image dimensions to use for the clipping of the polygon.
            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
        -------
        list of imgaug.Polygon
            Polygon, clipped to fall within the image dimensions.
            Returned as a list, because the clipping can split the polygon into
            multiple parts. The list may also be empty, if the polygon was
            fully outside of the image plane.

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

        # if fully out of image, clip everything away, nothing remaining
        if self.is_out_of_image(image, fully=True, partly=False):
            return []

        h, w = image.shape[0:2] if ia.is_np_array(image) else image[0:2]
        poly_shapely = self.to_shapely_polygon()
        poly_image = shapely.geometry.Polygon([(0, 0), (w, 0), (w, h), (0, h)])
        multipoly_inter_shapely = poly_shapely.intersection(poly_image)
        if not isinstance(multipoly_inter_shapely, shapely.geometry.MultiPolygon):
            ia.do_assert(isinstance(multipoly_inter_shapely, shapely.geometry.Polygon))
            multipoly_inter_shapely = shapely.geometry.MultiPolygon([multipoly_inter_shapely])

        polygons = []
        for poly_inter_shapely in multipoly_inter_shapely.geoms:
            polygons.append(Polygon.from_shapely(poly_inter_shapely, label=self.label))

        # shapely changes the order of points, we try here to preserve it as
        # much as possible
        polygons_reordered = []
        for polygon in polygons:
            found = False
            for x, y in self.exterior:
                closest_idx, dist = polygon.find_closest_point_index(x=x, y=y, return_distance=True)
                if dist < 1e-6:
                    polygon_reordered = polygon.change_first_point_by_index(closest_idx)
                    polygons_reordered.append(polygon_reordered)
                    found = True
                    break
            ia.do_assert(found)  # could only not find closest points if new polys are empty

        return polygons_reordered

Cut off all parts of the polygon that are outside of the image .


def extract_from_image(self, image):
        """
        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(image.ndim in [2, 3])
        if len(self.exterior) <= 2:
            raise Exception("Polygon must be made up of at least 3 points to extract its area from an image.")

        bb = self.to_bounding_box()
        bb_area = bb.extract_from_image(image)
        if self.is_out_of_image(image, fully=True, partly=False):
            return bb_area

        xx = self.xx_int
        yy = self.yy_int
        xx_mask = xx - np.min(xx)
        yy_mask = yy - np.min(yy)
        height_mask = np.max(yy_mask)
        width_mask = np.max(xx_mask)

        rr_face, cc_face = skimage.draw.polygon(yy_mask, xx_mask, shape=(height_mask, width_mask))

        mask = np.zeros((height_mask, width_mask), dtype=np.bool)
        mask[rr_face, cc_face] = True

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

        return bb_area * mask

Extract the image pixels within the polygon .


def change_first_point_by_coords(self, x, y, max_distance=1e-4,
                                     raise_if_too_far_away=True):
        """
        Set the first point of the exterior to the given point based on its coordinates.

        If multiple points are found, the closest one will be picked.
        If no matching points are found, an exception is raised.

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

        Parameters
        ----------
        x : number
            X-coordinate of the point.

        y : number
            Y-coordinate of the point.

        max_distance : None or number, optional
            Maximum distance past which possible matches are ignored.
            If ``None`` the distance limit is deactivated.

        raise_if_too_far_away : bool, optional
            Whether to raise an exception if the closest found point is too
            far away (``True``) or simply return an unchanged copy if this
            object (``False``).

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

        """
        if len(self.exterior) == 0:
            raise Exception("Cannot reorder polygon points, because it contains no points.")

        closest_idx, closest_dist = self.find_closest_point_index(x=x, y=y, return_distance=True)
        if max_distance is not None and closest_dist > max_distance:
            if not raise_if_too_far_away:
                return self.deepcopy()

            closest_point = self.exterior[closest_idx, :]
            raise Exception(
                "Closest found point (%.9f, %.9f) exceeds max_distance of %.9f exceeded" % (
                    closest_point[0], closest_point[1], closest_dist)
            )
        return self.change_first_point_by_index(closest_idx)

Set the first point of the exterior to the given point based on its coordinates .


def change_first_point_by_index(self, point_idx):
        """
        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 <= point_idx < len(self.exterior))
        if point_idx == 0:
            return self.deepcopy()
        exterior = np.concatenate(
            (self.exterior[point_idx:, :], self.exterior[:point_idx, :]),
            axis=0
        )
        return self.deepcopy(exterior=exterior)

def change_first_point_by_index ( self , point_idx ) : ia . do_assert ( 0 <= point_idx < len ( self . exterior ) ) if point_idx == 0 : return self . deepcopy ( ) exterior = np . concatenate ( ( self . exterior [ point_idx : , : ] , self . exterior [ : point_idx , : ] ) , axis = 0 ) return self . deepcopy ( exterior = exterior )

Set the first point of the exterior to the given point based on its index .


def to_shapely_polygon(self):
        """
        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([(point[0], point[1]) for point in self.exterior])

Convert this polygon to a Shapely polygon .


def to_shapely_line_string(self, closed=False, interpolate=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_to_shapely_line_string(self.exterior, closed=closed, interpolate=interpolate)

def to_shapely_line_string ( self , closed = False , interpolate = 0 ) : return _convert_points_to_shapely_line_string ( self . exterior , closed = closed , interpolate = interpolate )

Convert this polygon to a Shapely LineString object .


def to_bounding_box(self):
        """
        Convert this polygon to a bounding box tightly containing the whole polygon.

        Returns
        -------
        imgaug.BoundingBox
            Tight bounding box around the polygon.

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

        xx = self.xx
        yy = self.yy
        return BoundingBox(x1=min(xx), x2=max(xx), y1=min(yy), y2=max(yy), label=self.label)

def
to_bounding_box
(
self
)
:
# TODO get rid of this deferred import
from
imgaug
.
augmentables
.
bbs
import
BoundingBox
xx
=
self
.
xx
yy
=
self
.
yy
return
BoundingBox
(
x1
=
min
(
xx
)
,
x2
=
max
(
xx
)
,
y1
=
min
(
yy
)
,
y2
=
max
(
yy
)
,
label
=
self
.
label
)

Convert this polygon to a bounding box tightly containing the whole polygon .


def to_keypoints(self):
        """
        Convert this polygon's `exterior` to ``Keypoint`` instances.

        Returns
        -------
        list of imgaug.Keypoint
            Exterior vertices as ``Keypoint`` instances.

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

        return [Keypoint(x=point[0], y=point[1]) for point in self.exterior]

def
to_keypoints
(
self
)
:
# TODO get rid of this deferred import
from
imgaug
.
augmentables
.
kps
import
Keypoint
return
[
Keypoint
(
x
=
point
[
0
]
,
y
=
point
[
1
]
)
for
point
in
self
.
exterior
]

Convert this polygon s exterior to Keypoint instances .


def to_line_string(self, closed=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 closed or len(self.exterior) <= 1:
            return LineString(self.exterior, label=self.label)
        return LineString(
            np.concatenate([self.exterior, self.exterior[0:1, :]], axis=0),
            label=self.label)

def to_line_string ( self , closed = True ) : from imgaug . augmentables . lines import LineString if not closed or len ( self . exterior ) <= 1 : return LineString ( self . exterior , label = self . label ) return LineString ( np . concatenate ( [ self . exterior , self . exterior [ 0 : 1 , : ] ] , axis = 0 ) , label = self . label )

Convert this polygon s exterior to a LineString instance .


def from_shapely(polygon_shapely, label=None):
        """
        Create a polygon from a Shapely polygon.

        Note: This will remove any holes in the Shapely polygon.

        Parameters
        ----------
        polygon_shapely : shapely.geometry.Polygon
             The shapely polygon.

        label : None or str, optional
            The label of the new polygon.

        Returns
        -------
        imgaug.Polygon
            A polygon with the same exterior as the Shapely polygon.

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

        ia.do_assert(isinstance(polygon_shapely, shapely.geometry.Polygon))
        # polygon_shapely.exterior can be None if the polygon was instantiated without points
        if polygon_shapely.exterior is None or len(polygon_shapely.exterior.coords) == 0:
            return Polygon([], label=label)
        exterior = np.float32([[x, y] for (x, y) in polygon_shapely.exterior.coords])
        return Polygon(exterior, label=label)

Create a polygon from a Shapely polygon .


def exterior_almost_equals(self, other, max_distance=1e-6, points_per_edge=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(other, list):
            other = Polygon(np.float32(other))
        elif ia.is_np_array(other):
            other = Polygon(other)
        else:
            assert isinstance(other, Polygon)
            other = other

        return self.to_line_string(closed=True).coords_almost_equals(
            other.to_line_string(closed=True),
            max_distance=max_distance,
            points_per_edge=points_per_edge
        )

def exterior_almost_equals ( self , other , max_distance = 1e-6 , points_per_edge = 8 ) : if isinstance ( other , list ) : other = Polygon ( np . float32 ( other ) ) elif ia . is_np_array ( other ) : other = Polygon ( other ) else : assert isinstance ( other , Polygon ) other = other return self . to_line_string ( closed = True ) . coords_almost_equals ( other . to_line_string ( closed = True ) , max_distance = max_distance , points_per_edge = points_per_edge )

Estimate if this and other polygon s exterior are almost identical .


def copy(self, exterior=None, label=None):
        """
        Create a shallow copy 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 copy.

        """
        return self.deepcopy(exterior=exterior, label=label)

def copy ( self , exterior = None , label = None ) : return self . deepcopy ( exterior = exterior , label = label )

Create a shallow copy of the Polygon object .


def deepcopy(self, exterior=None, label=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(
            exterior=np.copy(self.exterior) if exterior is None else exterior,
            label=self.label if label is None else label
        )

def deepcopy ( self , exterior = None , label = None ) : return Polygon ( exterior = np . copy ( self . exterior ) if exterior is None else exterior , label = self . label if label is None else label )

Create a deep copy of the Polygon object .


def on(self, image):
        """
        Project polygons from one image to a new one.

        Parameters
        ----------
        image : ndarray or tuple of int
            New image onto which the polygons are to be projected.
            May also simply be that new image's shape tuple.

        Returns
        -------
        imgaug.PolygonsOnImage
            Object containing all projected polygons.

        """
        shape = normalize_shape(image)
        if shape[0:2] == self.shape[0:2]:
            return self.deepcopy()
        polygons = [poly.project(self.shape, shape) for poly in self.polygons]
        # TODO use deepcopy() here
        return PolygonsOnImage(polygons, shape)

def
on
(
self
,
image
)
:
shape
=
normalize_shape
(
image
)
if
shape
[
0
:
2
]
==
self
.
shape
[
0
:
2
]
:
return
self
.
deepcopy
(
)
polygons
=
[
poly
.
project
(
self
.
shape
,
shape
)
for
poly
in
self
.
polygons
]
# TODO use deepcopy() here
return
PolygonsOnImage
(
polygons
,
shape
)

Project polygons from one image to a new one .


def draw_on_image(self,
                      image,
                      color=(0, 255, 0), color_face=None,
                      color_lines=None, color_points=None,
                      alpha=1.0, alpha_face=None,
                      alpha_lines=None, alpha_points=None,
                      size=1, size_lines=None, size_points=None,
                      raise_if_out_of_image=False):
        """
        Draw all polygons onto a given image.

        Parameters
        ----------
        image : (H,W,C) ndarray
            The image onto which to draw the bounding boxes.
            This image should usually have the same shape as set in
            ``PolygonsOnImage.shape``.

        color : iterable of int, optional
            The color to use for the whole polygons.
            Must correspond to the channel layout of the image. Usually RGB.
            The values for `color_face`, `color_lines` and `color_points`
            will be derived from this color if they are set to ``None``.
            This argument has no effect if `color_face`, `color_lines`
            and `color_points` are all set anything other than ``None``.

        color_face : None or iterable of int, optional
            The color to use for the inner polygon areas (excluding perimeters).
            Must correspond to the channel layout of the image. Usually RGB.
            If this is ``None``, it will be derived from ``color * 1.0``.

        color_lines : None or iterable of int, optional
            The color to use for the lines (aka perimeters/borders) of the
            polygons. Must correspond to the channel layout of the image.
            Usually RGB. If this is ``None``, it will be derived
            from ``color * 0.5``.

        color_points : None or iterable of int, optional
            The color to use for the corner points of the polygons.
            Must correspond to the channel layout of the image. Usually RGB.
            If this is ``None``, it will be derived from ``color * 0.5``.

        alpha : float, optional
            The opacity of the whole polygons, where ``1.0`` denotes
            completely visible polygons and ``0.0`` invisible ones.
            The values for `alpha_face`, `alpha_lines` and `alpha_points`
            will be derived from this alpha value if they are set to ``None``.
            This argument has no effect if `alpha_face`, `alpha_lines`
            and `alpha_points` are all set anything other than ``None``.

        alpha_face : None or number, optional
            The opacity of the polygon's inner areas (excluding the perimeters),
            where ``1.0`` denotes completely visible inner areas and ``0.0``
            invisible ones.
            If this is ``None``, it will be derived from ``alpha * 0.5``.

        alpha_lines : None or number, optional
            The opacity of the polygon's lines (aka perimeters/borders),
            where ``1.0`` denotes completely visible perimeters and ``0.0``
            invisible ones.
            If this is ``None``, it will be derived from ``alpha * 1.0``.

        alpha_points : None or number, optional
            The opacity of the polygon's corner points, where ``1.0`` denotes
            completely visible corners and ``0.0`` invisible ones.
            Currently this is an on/off choice, i.e. only ``0.0`` or ``1.0``
            are allowed.
            If this is ``None``, it will be derived from ``alpha * 1.0``.

        size : int, optional
            Size of the polygons.
            The sizes of the line and points are derived from this value,
            unless they are set.

        size_lines : None or int, optional
            Thickness of the polygon lines (aka perimeter/border).
            If ``None``, this value is derived from `size`.

        size_points : int, optional
            The size of all corner points. If set to ``C``, each corner point
            will be drawn as a square of size ``C x C``.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if any polygon 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.

        Returns
        -------
        image : (H,W,C) ndarray
            Image with drawn polygons.

        """
        for poly in self.polygons:
            image = poly.draw_on_image(
                image,
                color=color,
                color_face=color_face,
                color_lines=color_lines,
                color_points=color_points,
                alpha=alpha,
                alpha_face=alpha_face,
                alpha_lines=alpha_lines,
                alpha_points=alpha_points,
                size=size,
                size_lines=size_lines,
                size_points=size_points,
                raise_if_out_of_image=raise_if_out_of_image
            )
        return image

def draw_on_image ( self , image , color = ( 0 , 255 , 0 ) , color_face = None , color_lines = None , color_points = None , alpha = 1.0 , alpha_face = None , alpha_lines = None , alpha_points = None , size = 1 , size_lines = None , size_points = None , raise_if_out_of_image = False ) : for poly in self . polygons : image = poly . draw_on_image ( image , color = color , color_face = color_face , color_lines = color_lines , color_points = color_points , alpha = alpha , alpha_face = alpha_face , alpha_lines = alpha_lines , alpha_points = alpha_points , size = size , size_lines = size_lines , size_points = size_points , raise_if_out_of_image = raise_if_out_of_image ) return image


def remove_out_of_image(self, fully=True, partly=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.

        """
        polys_clean = [
            poly for poly in self.polygons
            if not poly.is_out_of_image(self.shape, fully=fully, partly=partly)
        ]
        # TODO use deepcopy() here
        return PolygonsOnImage(polys_clean, shape=self.shape)

def
remove_out_of_image
(
self
,
fully
=
True
,
partly
=
False
)
:
polys_clean
=
[
poly
for
poly
in
self
.
polygons
if
not
poly
.
is_out_of_image
(
self
.
shape
,
fully
=
fully
,
partly
=
partly
)
]
# TODO use deepcopy() here
return
PolygonsOnImage
(
polys_clean
,
shape
=
self
.
shape
)

Remove all polygons that are fully or partially outside of the image .


def clip_out_of_image(self):
        """
        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.

        """
        polys_cut = [
            poly.clip_out_of_image(self.shape)
            for poly
            in self.polygons
            if poly.is_partly_within_image(self.shape)
        ]
        polys_cut_flat = [poly for poly_lst in polys_cut for poly in poly_lst]
        # TODO use deepcopy() here
        return PolygonsOnImage(polys_cut_flat, shape=self.shape)

def
clip_out_of_image
(
self
)
:
polys_cut
=
[
poly
.
clip_out_of_image
(
self
.
shape
)
for
poly
in
self
.
polygons
if
poly
.
is_partly_within_image
(
self
.
shape
)
]
polys_cut_flat
=
[
poly
for
poly_lst
in
polys_cut
for
poly
in
poly_lst
]
# TODO use deepcopy() here
return
PolygonsOnImage
(
polys_cut_flat
,
shape
=
self
.
shape
)

Clip off all parts from all polygons that are outside of the image .


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

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

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

Create a deep copy of the PolygonsOnImage object .


def from_shapely(geometry, label=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(geometry, shapely.geometry.MultiPolygon):
            return MultiPolygon([Polygon.from_shapely(poly, label=label) for poly in geometry.geoms])
        elif isinstance(geometry, shapely.geometry.Polygon):
            return MultiPolygon([Polygon.from_shapely(geometry, label=label)])
        elif isinstance(geometry, shapely.geometry.collection.GeometryCollection):
            ia.do_assert(all([isinstance(poly, shapely.geometry.Polygon) for poly in geometry.geoms]))
            return MultiPolygon([Polygon.from_shapely(poly, label=label) for poly in geometry.geoms])
        else:
            raise Exception("Unknown datatype '%s'. Expected shapely.geometry.Polygon or "
                            "shapely.geometry.MultiPolygon or "
                            "shapely.geometry.collections.GeometryCollection." % (type(geometry),))

Create a MultiPolygon from a Shapely MultiPolygon a Shapely Polygon or a Shapely GeometryCollection .


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

def get_intersections ( self ) : if Real is float : return list ( self . intersections . keys ( ) ) else : return [ ( float ( p [ 0 ] ) , float ( p [ 1 ] ) ) for p in self . intersections . keys ( ) ]

Return a list of unordered intersection points .


def min_item(self):
        """Get item with min key of tree, raises ValueError if tree is empty."""
        if self.is_empty():
            raise ValueError("Tree is empty")
        node = self._root
        while node.left is not None:
            node = node.left
        return node.key, node.value

def
min_item
(
self
)
:
if
self
.
is_empty
(
)
:
raise
ValueError
(
"Tree is empty"
)
node
=
self
.
_root
while
node
.
left
is
not
:
node
=
node
.
left
return
node
.
key
,
node
.
value

Get item with min key of tree raises ValueError if tree is empty .


def max_item(self):
        """Get item with max key of tree, raises ValueError if tree is empty."""
        if self.is_empty():
            raise ValueError("Tree is empty")
        node = self._root
        while node.right is not None:
            node = node.right
        return node.key, node.value

def
max_item
(
self
)
:
if
self
.
is_empty
(
)
:
raise
ValueError
(
"Tree is empty"
)
node
=
self
.
_root
while
node
.
right
is
not
:
node
=
node
.
right
return
node
.
key
,
node
.
value

Get item with max key of tree raises ValueError if tree is empty .


def prev_key(self, key, default=_sentinel):
        """Get predecessor to key, raises KeyError if key is min key
        or key does not exist.
        """
        item = self.prev_item(key, default)
        return default if item is default else item[0]

def prev_key ( self , key , default = _sentinel ) : item = self . prev_item ( key , default ) return default if item is default else item [ 0 ]

Get predecessor to key raises KeyError if key is min key or key does not exist .


def succ_key(self, key, default=_sentinel):
        """Get successor to key, raises KeyError if key is max key
        or key does not exist.
        """
        item = self.succ_item(key, default)
        return default if item is default else item[0]

def succ_key ( self , key , default = _sentinel ) : item = self . succ_item ( key , default ) return default if item is default else item [ 0 ]

Get successor to key raises KeyError if key is max key or key does not exist .


def noise2d(self, x, y):
        """
        Generate 2D OpenSimplex noise from X,Y coordinates.
        """
        # Place input coordinates onto grid.
        stretch_offset = (x + y) * STRETCH_CONSTANT_2D
        xs = x + stretch_offset
        ys = y + stretch_offset

        # Floor to get grid coordinates of rhombus (stretched square) super-cell origin.
        xsb = floor(xs)
        ysb = floor(ys)

        # Skew out to get actual coordinates of rhombus origin. We'll need these later.
        squish_offset = (xsb + ysb) * SQUISH_CONSTANT_2D
        xb = xsb + squish_offset
        yb = ysb + squish_offset

        # Compute grid coordinates relative to rhombus origin.
        xins = xs - xsb
        yins = ys - ysb

        # Sum those together to get a value that determines which region we're in.
        in_sum = xins + yins

        # Positions relative to origin point.
        dx0 = x - xb
        dy0 = y - yb

        value = 0

        # Contribution (1,0)
        dx1 = dx0 - 1 - SQUISH_CONSTANT_2D
        dy1 = dy0 - 0 - SQUISH_CONSTANT_2D
        attn1 = 2 - dx1 * dx1 - dy1 * dy1
        extrapolate = self._extrapolate2d
        if attn1 > 0:
            attn1 *= attn1
            value += attn1 * attn1 * extrapolate(xsb + 1, ysb + 0, dx1, dy1)

        # Contribution (0,1)
        dx2 = dx0 - 0 - SQUISH_CONSTANT_2D
        dy2 = dy0 - 1 - SQUISH_CONSTANT_2D
        attn2 = 2 - dx2 * dx2 - dy2 * dy2
        if attn2 > 0:
            attn2 *= attn2
            value += attn2 * attn2 * extrapolate(xsb + 0, ysb + 1, dx2, dy2)

        if in_sum <= 1: # We're inside the triangle (2-Simplex) at (0,0)
            zins = 1 - in_sum
            if zins > xins or zins > yins: # (0,0) is one of the closest two triangular vertices
                if xins > yins:
                    xsv_ext = xsb + 1
                    ysv_ext = ysb - 1
                    dx_ext = dx0 - 1
                    dy_ext = dy0 + 1
                else:
                    xsv_ext = xsb - 1
                    ysv_ext = ysb + 1
                    dx_ext = dx0 + 1
                    dy_ext = dy0 - 1
            else: # (1,0) and (0,1) are the closest two vertices.
                xsv_ext = xsb + 1
                ysv_ext = ysb + 1
                dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D
                dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D
        else: # We're inside the triangle (2-Simplex) at (1,1)
            zins = 2 - in_sum
            if zins < xins or zins < yins: # (0,0) is one of the closest two triangular vertices
                if xins > yins:
                    xsv_ext = xsb + 2
                    ysv_ext = ysb + 0
                    dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D
                    dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D
                else:
                    xsv_ext = xsb + 0
                    ysv_ext = ysb + 2
                    dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D
                    dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D
            else: # (1,0) and (0,1) are the closest two vertices.
                dx_ext = dx0
                dy_ext = dy0
                xsv_ext = xsb
                ysv_ext = ysb
            xsb += 1
            ysb += 1
            dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D
            dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D

        # Contribution (0,0) or (1,1)
        attn0 = 2 - dx0 * dx0 - dy0 * dy0
        if attn0 > 0:
            attn0 *= attn0
            value += attn0 * attn0 * extrapolate(xsb, ysb, dx0, dy0)

        # Extra Vertex
        attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext
        if attn_ext > 0:
            attn_ext *= attn_ext
            value += attn_ext * attn_ext * extrapolate(xsv_ext, ysv_ext, dx_ext, dy_ext)

        return value / NORM_CONSTANT_2D

Generate 2D OpenSimplex noise from X Y coordinates .


def InColorspace(to_colorspace, from_colorspace="RGB", children=None, name=None, deterministic=False,
                 random_state=None):
    """Convert images to another colorspace."""
    return WithColorspace(to_colorspace, from_colorspace, children, name, deterministic, random_state)

def InColorspace ( to_colorspace , from_colorspace = "RGB" , children = None , name = None , deterministic = False , random_state = None ) : return WithColorspace ( to_colorspace , from_colorspace , children , name , deterministic , random_state )


def Grayscale(alpha=0, from_colorspace="RGB", name=None, deterministic=False, random_state=None):
    """
    Augmenter to convert images to their grayscale versions.

    NOTE: Number of output channels is still 3, i.e. this augmenter just "removes" color.

    TODO check dtype support

    dtype support::

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

    Parameters
    ----------
    alpha : number or tuple of number or list of number or imgaug.parameters.StochasticParameter, optional
        The alpha value of the grayscale image when overlayed over the
        old image. A value close to 1.0 means, that mostly the new grayscale
        image is visible. A value close to 0.0 means, that mostly the
        old image is visible.

            * If a number, exactly that value will always 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.

    from_colorspace : str, optional
        The source colorspace (of the input images).
        Allowed strings are: ``RGB``, ``BGR``, ``GRAY``, ``CIE``, ``YCrCb``, ``HSV``, ``HLS``, ``Lab``, ``Luv``.
        See :func:`imgaug.augmenters.color.ChangeColorspace.__init__`.

    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.Grayscale(alpha=1.0)

    creates an augmenter that turns images to their grayscale versions.

    >>> aug = iaa.Grayscale(alpha=(0.0, 1.0))

    creates an augmenter that turns images to their grayscale versions with
    an alpha value in the range ``0 <= alpha <= 1``. An alpha value of 0.5 would
    mean, that the output image is 50 percent of the input image and 50
    percent of the grayscale image (i.e. 50 percent of color removed).

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

    return ChangeColorspace(to_colorspace=ChangeColorspace.GRAY, alpha=alpha, from_colorspace=from_colorspace,
                            name=name, deterministic=deterministic, random_state=random_state)

def Grayscale ( alpha = 0 , from_colorspace = "RGB" , name = None , deterministic = False , random_state = None ) : if name is None : name = "Unnamed%s" % ( ia . caller_name ( ) , ) return ChangeColorspace ( to_colorspace = ChangeColorspace . GRAY , alpha = alpha , from_colorspace = from_colorspace , name = name , deterministic = deterministic , random_state = random_state )

Augmenter to convert images to their grayscale versions .


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

def height ( self ) : if len ( self . coords ) <= 1 : return 0 return np . max ( self . yy ) - np . min ( self . yy )

Get the height of a bounding box encapsulating the line .


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

def width ( self ) : if len ( self . coords ) <= 1 : return 0 return np . max ( self . xx ) - np . min ( self . xx )

Get the width of a bounding box encapsulating the line .


def get_pointwise_inside_image_mask(self, image):
        """
        Get for each point whether it is inside of the given image plane.

        Parameters
        ----------
        image : ndarray or tuple of int
            Either an image with shape ``(H,W,[C])`` or a tuple denoting
            such an image shape.

        Returns
        -------
        ndarray
            Boolean array with one value per point indicating whether it is
            inside of the provided image plane (``True``) or not (``False``).

        """
        if len(self.coords) == 0:
            return np.zeros((0,), dtype=bool)
        shape = normalize_shape(image)
        height, width = shape[0:2]
        x_within = np.logical_and(0 <= self.xx, self.xx < width)
        y_within = np.logical_and(0 <= self.yy, self.yy < height)
        return np.logical_and(x_within, y_within)

def get_pointwise_inside_image_mask ( self , image ) : if len ( self . coords ) == 0 : return np . zeros ( ( 0 , ) , dtype = bool ) shape = normalize_shape ( image ) height , width = shape [ 0 : 2 ] x_within = np . logical_and ( 0 <= self . xx , self . xx < width ) y_within = np . logical_and ( 0 <= self . yy , self . yy < height ) return np . logical_and ( x_within , y_within )

Get for each point whether it is inside of the given image plane .


def compute_neighbour_distances(self):
        """
        Get the euclidean distance between each two consecutive points.

        Returns
        -------
        ndarray
            Euclidean distances between point pairs.
            Same order as in `coords`. For ``N`` points, ``N-1`` distances
            are returned.

        """
        if len(self.coords) <= 1:
            return np.zeros((0,), dtype=np.float32)
        return np.sqrt(
            np.sum(
                (self.coords[:-1, :] - self.coords[1:, :]) ** 2,
                axis=1
            )
        )

def compute_neighbour_distances ( self ) : if len ( self . coords ) <= 1 : return np . zeros ( ( 0 , ) , dtype = np . float32 ) return np . sqrt ( np . sum ( ( self . coords [ : - 1 , : ] - self . coords [ 1 : , : ] ) ** 2 , axis = 1 ) )

Get the euclidean distance between each two consecutive points .


def compute_pointwise_distances(self, other, default=None):
        """
        Compute the minimal distance between each point on self and other.

        Parameters
        ----------
        other : tuple of number \
                or imgaug.augmentables.kps.Keypoint \
                or imgaug.augmentables.LineString
            Other object to which to compute the distances.

        default
            Value to return if `other` contains no points.

        Returns
        -------
        list of float
            Distances to `other` or `default` if not distance could be computed.

        """
        import shapely.geometry
        from .kps import Keypoint

        if isinstance(other, Keypoint):
            other = shapely.geometry.Point((other.x, other.y))
        elif isinstance(other, LineString):
            if len(other.coords) == 0:
                return default
            elif len(other.coords) == 1:
                other = shapely.geometry.Point(other.coords[0, :])
            else:
                other = shapely.geometry.LineString(other.coords)
        elif isinstance(other, tuple):
            assert len(other) == 2
            other = shapely.geometry.Point(other)
        else:
            raise ValueError(
                ("Expected Keypoint or LineString or tuple (x,y), "
                 + "got type %s.") % (type(other),))

        return [shapely.geometry.Point(point).distance(other)
                for point in self.coords]

Compute the minimal distance between each point on self and other .


def compute_distance(self, other, default=None):
        """
        Compute the minimal distance between the line string and `other`.

        Parameters
        ----------
        other : tuple of number \
                or imgaug.augmentables.kps.Keypoint \
                or imgaug.augmentables.LineString
            Other object to which to compute the distance.

        default
            Value to return if this line string or `other` contain no points.

        Returns
        -------
        float
            Distance to `other` or `default` if not distance could be computed.

        """
        # FIXME this computes distance pointwise, does not have to be identical
        #       with the actual min distance (e.g. edge center to other's point)
        distances = self.compute_pointwise_distances(other, default=[])
        if len(distances) == 0:
            return default
        return min(distances)

Compute the minimal distance between the line string and other .


def project(self, from_shape, to_shape):
        """
        Project the line string onto a differently shaped image.

        E.g. if a point of the line string is on its original image at
        ``x=(10 of 100 pixels)`` and ``y=(20 of 100 pixels)`` and is projected
        onto a new image with size ``(width=200, height=200)``, its new
        position will be ``(x=20, y=40)``.

        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 or ndarray
            Shape of the original image. (Before resize.)

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

        Returns
        -------
        out : imgaug.augmentables.lines.LineString
            Line string with new coordinates.

        """
        coords_proj = project_coords(self.coords, from_shape, to_shape)
        return self.copy(coords=coords_proj)

def project ( self , from_shape , to_shape ) : coords_proj = project_coords ( self . coords , from_shape , to_shape ) return self . copy ( coords = coords_proj )

Project the line string onto a differently shaped image .


def is_fully_within_image(self, image, default=False):
        """
        Estimate whether the line string is fully inside the image area.

        Parameters
        ----------
        image : ndarray or tuple of int
            Either an image with shape ``(H,W,[C])`` or a tuple denoting
            such an image shape.

        default
            Default value to return if the line string contains no points.

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

        """
        if len(self.coords) == 0:
            return default
        return np.all(self.get_pointwise_inside_image_mask(image))

def is_fully_within_image ( self , image , default = False ) : if len ( self . coords ) == 0 : return default return np . all ( self . get_pointwise_inside_image_mask ( image ) )

Estimate whether the line string is fully inside the image area .


def is_partly_within_image(self, image, default=False):
        """
        Estimate whether the line string is at least partially inside the image.

        Parameters
        ----------
        image : ndarray or tuple of int
            Either an image with shape ``(H,W,[C])`` or a tuple denoting
            such an image shape.

        default
            Default value to return if the line string contains no points.

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

        """
        if len(self.coords) == 0:
            return default
        # check mask first to avoid costly computation of intersection points
        # whenever possible
        mask = self.get_pointwise_inside_image_mask(image)
        if np.any(mask):
            return True
        return len(self.clip_out_of_image(image)) > 0

Estimate whether the line string is at least partially inside the image .


def find_intersections_with(self, other):
        """
        Find all intersection points between the line string and `other`.

        Parameters
        ----------
        other : tuple of number or list of tuple of number or \
                list of LineString or LineString
            The other geometry to use during intersection tests.

        Returns
        -------
        list of list of tuple of number
            All intersection points. One list per pair of consecutive start
            and end point, i.e. `N-1` lists of `N` points. Each list may
            be empty or may contain multiple points.

        """
        import shapely.geometry

        geom = _convert_var_to_shapely_geometry(other)

        result = []
        for p_start, p_end in zip(self.coords[:-1], self.coords[1:]):
            ls = shapely.geometry.LineString([p_start, p_end])
            intersections = ls.intersection(geom)
            intersections = list(_flatten_shapely_collection(intersections))

            intersections_points = []
            for inter in intersections:
                if isinstance(inter, shapely.geometry.linestring.LineString):
                    inter_start = (inter.coords[0][0], inter.coords[0][1])
                    inter_end = (inter.coords[-1][0], inter.coords[-1][1])
                    intersections_points.extend([inter_start, inter_end])
                else:
                    assert isinstance(inter, shapely.geometry.point.Point), (
                        "Expected to find shapely.geometry.point.Point or "
                        "shapely.geometry.linestring.LineString intersection, "
                        "actually found %s." % (type(inter),))
                    intersections_points.append((inter.x, inter.y))

            # sort by distance to start point, this makes it later on easier
            # to remove duplicate points
            inter_sorted = sorted(
                intersections_points,
                key=lambda p: np.linalg.norm(np.float32(p) - p_start)
            )

            result.append(inter_sorted)
        return result

Find all intersection points between the line string and other .


def draw_mask(self, image_shape, size_lines=1, size_points=0,
                  raise_if_out_of_image=False):
        """
        Draw this line segment as a binary image mask.

        Parameters
        ----------
        image_shape : tuple of int
            The shape of the image onto which to draw the line mask.

        size_lines : int, optional
            Thickness of the line segments.

        size_points : int, optional
            Size of the points in pixels.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        ndarray
            Boolean line mask of shape `image_shape` (no channel axis).

        """
        heatmap = self.draw_heatmap_array(
            image_shape,
            alpha_lines=1.0, alpha_points=1.0,
            size_lines=size_lines, size_points=size_points,
            antialiased=False,
            raise_if_out_of_image=raise_if_out_of_image)
        return heatmap > 0.5

Draw this line segment as a binary image mask .


def draw_lines_heatmap_array(self, image_shape, alpha=1.0,
                                 size=1, antialiased=True,
                                 raise_if_out_of_image=False):
        """
        Draw the line segments of the line string as a heatmap array.

        Parameters
        ----------
        image_shape : tuple of int
            The shape of the image onto which to draw the line mask.

        alpha : float, optional
            Opacity of the line string. Higher values denote a more visible
            line string.

        size : int, optional
            Thickness of the line segments.

        antialiased : bool, optional
            Whether to draw the line with anti-aliasing activated.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        ndarray
            Float array of shape `image_shape` (no channel axis) with drawn
            line string. All values are in the interval ``[0.0, 1.0]``.

        """
        assert len(image_shape) == 2 or (
            len(image_shape) == 3 and image_shape[-1] == 1), (
            "Expected (H,W) or (H,W,1) as image_shape, got %s." % (
                image_shape,))

        arr = self.draw_lines_on_image(
            np.zeros(image_shape, dtype=np.uint8),
            color=255, alpha=alpha, size=size,
            antialiased=antialiased,
            raise_if_out_of_image=raise_if_out_of_image
        )
        return arr.astype(np.float32) / 255.0

Draw the line segments of the line string as a heatmap array .


def draw_points_heatmap_array(self, image_shape, alpha=1.0,
                                  size=1, raise_if_out_of_image=False):
        """
        Draw the points of the line string as a heatmap array.

        Parameters
        ----------
        image_shape : tuple of int
            The shape of the image onto which to draw the point mask.

        alpha : float, optional
            Opacity of the line string points. Higher values denote a more
            visible points.

        size : int, optional
            Size of the points in pixels.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        ndarray
            Float array of shape `image_shape` (no channel axis) with drawn
            line string points. All values are in the interval ``[0.0, 1.0]``.

        """
        assert len(image_shape) == 2 or (
            len(image_shape) == 3 and image_shape[-1] == 1), (
            "Expected (H,W) or (H,W,1) as image_shape, got %s." % (
                image_shape,))

        arr = self.draw_points_on_image(
            np.zeros(image_shape, dtype=np.uint8),
            color=255, alpha=alpha, size=size,
            raise_if_out_of_image=raise_if_out_of_image
        )
        return arr.astype(np.float32) / 255.0

Draw the points of the line string as a heatmap array .


def draw_heatmap_array(self, image_shape, alpha_lines=1.0, alpha_points=1.0,
                           size_lines=1, size_points=0, antialiased=True,
                           raise_if_out_of_image=False):
        """
        Draw the line segments and points of the line string as a heatmap array.

        Parameters
        ----------
        image_shape : tuple of int
            The shape of the image onto which to draw the line mask.

        alpha_lines : float, optional
            Opacity of the line string. Higher values denote a more visible
            line string.

        alpha_points : float, optional
            Opacity of the line string points. Higher values denote a more
            visible points.

        size_lines : int, optional
            Thickness of the line segments.

        size_points : int, optional
            Size of the points in pixels.

        antialiased : bool, optional
            Whether to draw the line with anti-aliasing activated.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        ndarray
            Float array of shape `image_shape` (no channel axis) with drawn
            line segments and points. All values are in the
            interval ``[0.0, 1.0]``.

        """
        heatmap_lines = self.draw_lines_heatmap_array(
            image_shape,
            alpha=alpha_lines,
            size=size_lines,
            antialiased=antialiased,
            raise_if_out_of_image=raise_if_out_of_image)
        if size_points <= 0:
            return heatmap_lines

        heatmap_points = self.draw_points_heatmap_array(
            image_shape,
            alpha=alpha_points,
            size=size_points,
            raise_if_out_of_image=raise_if_out_of_image)

        heatmap = np.dstack([heatmap_lines, heatmap_points])
        return np.max(heatmap, axis=2)

def draw_heatmap_array ( self , image_shape , alpha_lines = 1.0 , alpha_points = 1.0 , size_lines = 1 , size_points = 0 , antialiased = True , raise_if_out_of_image = False ) : heatmap_lines = self . draw_lines_heatmap_array ( image_shape , alpha = alpha_lines , size = size_lines , antialiased = antialiased , raise_if_out_of_image = raise_if_out_of_image ) if size_points <= 0 : return heatmap_lines heatmap_points = self . draw_points_heatmap_array ( image_shape , alpha = alpha_points , size = size_points , raise_if_out_of_image = raise_if_out_of_image ) heatmap = np . dstack ( [ heatmap_lines , heatmap_points ] ) return np . max ( heatmap , axis = 2 )

Draw the line segments and points of the line string as a heatmap array .


def draw_points_on_image(self, image, color=(0, 128, 0),
                             alpha=1.0, size=3,
                             copy=True, raise_if_out_of_image=False):
        """
        Draw the points of the line string on a given image.

        Parameters
        ----------
        image : ndarray or tuple of int
            The image onto which to draw.
            Expected to be ``uint8`` and of shape ``(H, W, C)`` with ``C``
            usually being ``3`` (other values are not tested).
            If a tuple, expected to be ``(H, W, C)`` and will lead to a new
            ``uint8`` array of zeros being created.

        color : iterable of int
            Color to use as RGB, i.e. three values.

        alpha : float, optional
            Opacity of the line string points. Higher values denote a more
            visible points.

        size : int, optional
            Size of the points in pixels.

        copy : bool, optional
            Whether it is allowed to draw directly in the input
            array (``False``) or it has to be copied (``True``).
            The routine may still have to copy, even if ``copy=False`` was
            used. Always use the return value.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        ndarray
            Float array of shape `image_shape` (no channel axis) with drawn
            line string points. All values are in the interval ``[0.0, 1.0]``.

        """
        from .kps import KeypointsOnImage
        kpsoi = KeypointsOnImage.from_xy_array(self.coords, shape=image.shape)
        image = kpsoi.draw_on_image(
            image, color=color, alpha=alpha,
            size=size, copy=copy,
            raise_if_out_of_image=raise_if_out_of_image)

        return image

def draw_points_on_image ( self , image , color = ( 0 , 128 , 0 ) , alpha = 1.0 , size = 3 , copy = True , raise_if_out_of_image = False ) : from . kps import KeypointsOnImage kpsoi = KeypointsOnImage . from_xy_array ( self . coords , shape = image . shape ) image = kpsoi . draw_on_image ( image , color = color , alpha = alpha , size = size , copy = copy , raise_if_out_of_image = raise_if_out_of_image ) return image

Draw the points of the line string on a given image .


def draw_on_image(self, image,
                      color=(0, 255, 0), color_lines=None, color_points=None,
                      alpha=1.0, alpha_lines=None, alpha_points=None,
                      size=1, size_lines=None, size_points=None,
                      antialiased=True,
                      raise_if_out_of_image=False):
        """
        Draw the line string on an image.

        Parameters
        ----------
        image : ndarray
            The `(H,W,C)` `uint8` image onto which to draw the line string.

        color : iterable of int, optional
            Color to use as RGB, i.e. three values.
            The color of the line and points are derived from this value,
            unless they are set.

        color_lines : None or iterable of int
            Color to use for the line segments as RGB, i.e. three values.
            If ``None``, this value is derived from `color`.

        color_points : None or iterable of int
            Color to use for the points as RGB, i.e. three values.
            If ``None``, this value is derived from ``0.5 * color``.

        alpha : float, optional
            Opacity of the line string. Higher values denote more visible
            points.
            The alphas of the line and points are derived from this value,
            unless they are set.

        alpha_lines : None or float, optional
            Opacity of the line string. Higher values denote more visible
            line string.
            If ``None``, this value is derived from `alpha`.

        alpha_points : None or float, optional
            Opacity of the line string points. Higher values denote more
            visible points.
            If ``None``, this value is derived from `alpha`.

        size : int, optional
            Size of the line string.
            The sizes of the line and points are derived from this value,
            unless they are set.

        size_lines : None or int, optional
            Thickness of the line segments.
            If ``None``, this value is derived from `size`.

        size_points : None or int, optional
            Size of the points in pixels.
            If ``None``, this value is derived from ``3 * size``.

        antialiased : bool, optional
            Whether to draw the line with anti-aliasing activated.
            This does currently not affect the point drawing.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        ndarray
            Image with line string drawn on it.

        """
        assert color is not None
        assert alpha is not None
        assert size is not None

        color_lines = color_lines if color_lines is not None \
            else np.float32(color)
        color_points = color_points if color_points is not None \
            else np.float32(color) * 0.5

        alpha_lines = alpha_lines if alpha_lines is not None \
            else np.float32(alpha)
        alpha_points = alpha_points if alpha_points is not None \
            else np.float32(alpha)

        size_lines = size_lines if size_lines is not None else size
        size_points = size_points if size_points is not None else size * 3

        image = self.draw_lines_on_image(
            image, color=np.array(color_lines).astype(np.uint8),
            alpha=alpha_lines, size=size_lines,
            antialiased=antialiased,
            raise_if_out_of_image=raise_if_out_of_image)

        image = self.draw_points_on_image(
            image, color=np.array(color_points).astype(np.uint8),
            alpha=alpha_points, size=size_points,
            copy=False,
            raise_if_out_of_image=raise_if_out_of_image)

        return image

def draw_on_image ( self , image , color = ( 0 , 255 , 0 ) , color_lines = None , color_points = None , alpha = 1.0 , alpha_lines = None , alpha_points = None , size = 1 , size_lines = None , size_points = None , antialiased = True , raise_if_out_of_image = False ) : assert color is not None assert alpha is not None assert size is not None color_lines = color_lines if color_lines is not None else np . float32 ( color ) color_points = color_points if color_points is not None else np . float32 ( color ) * 0.5 alpha_lines = alpha_lines if alpha_lines is not None else np . float32 ( alpha ) alpha_points = alpha_points if alpha_points is not None else np . float32 ( alpha ) size_lines = size_lines if size_lines is not None else size size_points = size_points if size_points is not None else size * 3 image = self . draw_lines_on_image ( image , color = np . array ( color_lines ) . astype ( np . uint8 ) , alpha = alpha_lines , size = size_lines , antialiased = antialiased , raise_if_out_of_image = raise_if_out_of_image ) image = self . draw_points_on_image ( image , color = np . array ( color_points ) . astype ( np . uint8 ) , alpha = alpha_points , size = size_points , copy = False , raise_if_out_of_image = raise_if_out_of_image ) return image


def extract_from_image(self, image, size=1, pad=True, pad_max=None,
                           antialiased=True, prevent_zero_size=True):
        """
        Extract the image pixels covered by the line string.

        It will only extract pixels overlapped by the line string.

        This function will by default zero-pad the image if the line string is
        partially/fully outside of the image. This is for consistency with
        the same implementations for bounding boxes and polygons.

        Parameters
        ----------
        image : ndarray
            The image of shape `(H,W,[C])` from which to extract the pixels
            within the line string.

        size : int, optional
            Thickness of the line.

        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.

        antialiased : bool, optional
            Whether to apply anti-aliasing to the line string.

        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
            line string 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 overlapping with the line string. Zero-padded if the
            line string is partially/fully outside of the image and
            ``pad=True``. If `prevent_zero_size` is activated, it is
            guarantueed that ``H'>0`` and ``W'>0``, otherwise only
            ``H'>=0`` and ``W'>=0``.

        """
        from .bbs import BoundingBox

        assert image.ndim in [2, 3], (
            "Expected image of shape (H,W,[C]), "
            "got shape %s." % (image.shape,))

        if len(self.coords) == 0 or size <= 0:
            if prevent_zero_size:
                return np.zeros((1, 1) + image.shape[2:], dtype=image.dtype)
            return np.zeros((0, 0) + image.shape[2:], dtype=image.dtype)

        xx = self.xx_int
        yy = self.yy_int

        # this would probably work if drawing was subpixel-accurate
        # x1 = np.min(self.coords[:, 0]) - (size / 2)
        # y1 = np.min(self.coords[:, 1]) - (size / 2)
        # x2 = np.max(self.coords[:, 0]) + (size / 2)
        # y2 = np.max(self.coords[:, 1]) + (size / 2)

        # this works currently with non-subpixel-accurate drawing
        sizeh = (size - 1) / 2
        x1 = np.min(xx) - sizeh
        y1 = np.min(yy) - sizeh
        x2 = np.max(xx) + 1 + sizeh
        y2 = np.max(yy) + 1 + sizeh
        bb = BoundingBox(x1=x1, y1=y1, x2=x2, y2=y2)

        if len(self.coords) == 1:
            return bb.extract_from_image(image, pad=pad, pad_max=pad_max,
                                         prevent_zero_size=prevent_zero_size)

        heatmap = self.draw_lines_heatmap_array(
            image.shape[0:2], alpha=1.0, size=size, antialiased=antialiased)
        if image.ndim == 3:
            heatmap = np.atleast_3d(heatmap)
        image_masked = image.astype(np.float32) * heatmap
        extract = bb.extract_from_image(image_masked, pad=pad, pad_max=pad_max,
                                        prevent_zero_size=prevent_zero_size)
        return np.clip(np.round(extract), 0, 255).astype(np.uint8)

Extract the image pixels covered by the line string .


def concatenate(self, other):
        """
        Concatenate this line string with another one.

        This will add a line segment between the end point of this line string
        and the start point of `other`.

        Parameters
        ----------
        other : imgaug.augmentables.lines.LineString or ndarray \
                or iterable of tuple of number
            The points to add to this line string.

        Returns
        -------
        imgaug.augmentables.lines.LineString
            New line string with concatenated points.
            The `label` of this line string will be kept.

        """
        if not isinstance(other, LineString):
            other = LineString(other)
        return self.deepcopy(
            coords=np.concatenate([self.coords, other.coords], axis=0))

def concatenate ( self , other ) : if not isinstance ( other , LineString ) : other = LineString ( other ) return self . deepcopy ( coords = np . concatenate ( [ self . coords , other . coords ] , axis = 0 ) )

Concatenate this line string with another one .


def subdivide(self, points_per_edge):
        """
        Adds ``N`` interpolated points with uniform spacing to each edge.

        For each edge between points ``A`` and ``B`` this adds points
        at ``A + (i/(1+N)) * (B - A)``, where ``i`` is the index of the added
        point and ``N`` is the number of points to add per edge.

        Calling this method two times will split each edge at its center
        and then again split each newly created edge at their center.
        It is equivalent to calling `subdivide(3)`.

        Parameters
        ----------
        points_per_edge : int
            Number of points to interpolate on each edge.

        Returns
        -------
        LineString
            Line string with subdivided edges.

        """
        if len(self.coords) <= 1 or points_per_edge < 1:
            return self.deepcopy()
        coords = interpolate_points(self.coords, nb_steps=points_per_edge,
                                    closed=False)
        return self.deepcopy(coords=coords)

def subdivide ( self , points_per_edge ) : if len ( self . coords ) <= 1 or points_per_edge < 1 : return self . deepcopy ( ) coords = interpolate_points ( self . coords , nb_steps = points_per_edge , closed = False ) return self . deepcopy ( coords = coords )

Adds N interpolated points with uniform spacing to each edge .


def to_keypoints(self):
        """
        Convert the line string points to keypoints.

        Returns
        -------
        list of imgaug.augmentables.kps.Keypoint
            Points of the line string as keypoints.

        """
        # TODO get rid of this deferred import
        from imgaug.augmentables.kps import Keypoint
        return [Keypoint(x=x, y=y) for (x, y) in self.coords]

def
to_keypoints
(
self
)
:
# TODO get rid of this deferred import
from
imgaug
.
augmentables
.
kps
import
Keypoint
return
[
Keypoint
(
x
=
x
,
y
=
y
)
for
(
x
,
y
)
in
self
.
coords
]

Convert the line string points to keypoints .


def to_bounding_box(self):
        """
        Generate a bounding box encapsulating the line string.

        Returns
        -------
        None or imgaug.augmentables.bbs.BoundingBox
            Bounding box encapsulating the line string.
            ``None`` if the line string contained no points.

        """
        from .bbs import BoundingBox
        # we don't have to mind the case of len(.) == 1 here, because
        # zero-sized BBs are considered valid
        if len(self.coords) == 0:
            return None
        return BoundingBox(x1=np.min(self.xx), y1=np.min(self.yy),
                           x2=np.max(self.xx), y2=np.max(self.yy),
                           label=self.label)

Generate a bounding box encapsulating the line string .


def to_polygon(self):
        """
        Generate a polygon from the line string points.

        Returns
        -------
        imgaug.augmentables.polys.Polygon
            Polygon with the same corner points as the line string.
            Note that the polygon might be invalid, e.g. contain less than 3
            points or have self-intersections.

        """
        from .polys import Polygon
        return Polygon(self.coords, label=self.label)

def to_polygon ( self ) : from . polys import Polygon return Polygon ( self . coords , label = self . label )

Generate a polygon from the line string points .


def to_heatmap(self, image_shape, size_lines=1, size_points=0,
                   antialiased=True, raise_if_out_of_image=False):
        """
        Generate a heatmap object from the line string.

        This is similar to
        :func:`imgaug.augmentables.lines.LineString.draw_lines_heatmap_array`
        executed with ``alpha=1.0``. The result is wrapped in a
        ``HeatmapsOnImage`` object instead of just an array.
        No points are drawn.

        Parameters
        ----------
        image_shape : tuple of int
            The shape of the image onto which to draw the line mask.

        size_lines : int, optional
            Thickness of the line.

        size_points : int, optional
            Size of the points in pixels.

        antialiased : bool, optional
            Whether to draw the line with anti-aliasing activated.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapOnImage
            Heatmap object containing drawn line string.

        """
        from .heatmaps import HeatmapsOnImage
        return HeatmapsOnImage(
            self.draw_heatmap_array(
                image_shape, size_lines=size_lines, size_points=size_points,
                antialiased=antialiased,
                raise_if_out_of_image=raise_if_out_of_image),
            shape=image_shape
        )

def to_heatmap ( self , image_shape , size_lines = 1 , size_points = 0 , antialiased = True , raise_if_out_of_image = False ) : from . heatmaps import HeatmapsOnImage return HeatmapsOnImage ( self . draw_heatmap_array ( image_shape , size_lines = size_lines , size_points = size_points , antialiased = antialiased , raise_if_out_of_image = raise_if_out_of_image ) , shape = image_shape )

Generate a heatmap object from the line string .


def to_segmentation_map(self, image_shape, size_lines=1, size_points=0,
                            raise_if_out_of_image=False):
        """
        Generate a segmentation map object from the line string.

        This is similar to
        :func:`imgaug.augmentables.lines.LineString.draw_mask`.
        The result is wrapped in a ``SegmentationMapOnImage`` object
        instead of just an array.

        Parameters
        ----------
        image_shape : tuple of int
            The shape of the image onto which to draw the line mask.

        size_lines : int, optional
            Thickness of the line.

        size_points : int, optional
            Size of the points in pixels.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if the line string 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.

        Returns
        -------
        imgaug.augmentables.segmaps.SegmentationMapOnImage
            Segmentation map object containing drawn line string.

        """
        from .segmaps import SegmentationMapOnImage
        return SegmentationMapOnImage(
            self.draw_mask(
                image_shape, size_lines=size_lines, size_points=size_points,
                raise_if_out_of_image=raise_if_out_of_image),
            shape=image_shape
        )

def to_segmentation_map ( self , image_shape , size_lines = 1 , size_points = 0 , raise_if_out_of_image = False ) : from . segmaps import SegmentationMapOnImage return SegmentationMapOnImage ( self . draw_mask ( image_shape , size_lines = size_lines , size_points = size_points , raise_if_out_of_image = raise_if_out_of_image ) , shape = image_shape )

Generate a segmentation map object from the line string .


def coords_almost_equals(self, other, max_distance=1e-6, points_per_edge=8):
        """
        Compare this and another LineString's coordinates.

        This is an approximate method based on pointwise distances and can
        in rare corner cases produce wrong outputs.

        Parameters
        ----------
        other : imgaug.augmentables.lines.LineString \
                or tuple of number \
                or ndarray \
                or list of ndarray \
                or list of tuple of number
            The other line string or its coordinates.

        max_distance : float
            Max distance of any point from the other line string before
            the two line strings are evaluated to be unequal.

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

        Returns
        -------
        bool
            Whether the two LineString's coordinates are almost identical,
            i.e. the max distance is below the threshold.
            If both have no coordinates, ``True`` is returned.
            If only one has no coordinates, ``False`` is returned.
            Beyond that, the number of points is not evaluated.

        """
        if isinstance(other, LineString):
            pass
        elif isinstance(other, tuple):
            other = LineString([other])
        else:
            other = LineString(other)

        if len(self.coords) == 0 and len(other.coords) == 0:
            return True
        elif 0 in [len(self.coords), len(other.coords)]:
            # only one of the two line strings has no coords
            return False

        self_subd = self.subdivide(points_per_edge)
        other_subd = other.subdivide(points_per_edge)

        dist_self2other = self_subd.compute_pointwise_distances(other_subd)
        dist_other2self = other_subd.compute_pointwise_distances(self_subd)
        dist = max(np.max(dist_self2other), np.max(dist_other2self))
        return  dist < max_distance

Compare this and another LineString s coordinates .


def almost_equals(self, other, max_distance=1e-4, points_per_edge=8):
        """
        Compare this and another LineString.

        Parameters
        ----------
        other: imgaug.augmentables.lines.LineString
            The other line string. Must be a LineString instance, not just
            its coordinates.

        max_distance : float, optional
            See :func:`imgaug.augmentables.lines.LineString.coords_almost_equals`.

        points_per_edge : int, optional
            See :func:`imgaug.augmentables.lines.LineString.coords_almost_equals`.

        Returns
        -------
        bool
            ``True`` if the coordinates are almost equal according to
            :func:`imgaug.augmentables.lines.LineString.coords_almost_equals`
            and additionally the labels are identical. Otherwise ``False``.

        """
        if self.label != other.label:
            return False
        return self.coords_almost_equals(
            other, max_distance=max_distance, points_per_edge=points_per_edge)

def almost_equals ( self , other , max_distance = 1e-4 , points_per_edge = 8 ) : if self . label != other . label : return False return self . coords_almost_equals ( other , max_distance = max_distance , points_per_edge = points_per_edge )


def copy(self, coords=None, label=None):
        """
        Create a shallow copy of the LineString object.

        Parameters
        ----------
        coords : None or iterable of tuple of number or ndarray
            If not ``None``, then the coords of the copied object will be set
            to this value.

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

        Returns
        -------
        imgaug.augmentables.lines.LineString
            Shallow copy.

        """
        return LineString(coords=self.coords if coords is None else coords,
                          label=self.label if label is None else label)

def copy ( self , coords = None , label = None ) : return LineString ( coords = self . coords if coords is None else coords , label = self . label if label is None else label )

Create a shallow copy of the LineString object .


def draw_on_image(self, image,
                      color=(0, 255, 0), color_lines=None, color_points=None,
                      alpha=1.0, alpha_lines=None, alpha_points=None,
                      size=1, size_lines=None, size_points=None,
                      antialiased=True,
                      raise_if_out_of_image=False):
        """
        Draw all line strings onto a given image.

        Parameters
        ----------
        image : ndarray
            The `(H,W,C)` `uint8` image onto which to draw the line strings.

        color : iterable of int, optional
            Color to use as RGB, i.e. three values.
            The color of the lines and points are derived from this value,
            unless they are set.

        color_lines : None or iterable of int
            Color to use for the line segments as RGB, i.e. three values.
            If ``None``, this value is derived from `color`.

        color_points : None or iterable of int
            Color to use for the points as RGB, i.e. three values.
            If ``None``, this value is derived from ``0.5 * color``.

        alpha : float, optional
            Opacity of the line strings. Higher values denote more visible
            points.
            The alphas of the line and points are derived from this value,
            unless they are set.

        alpha_lines : None or float, optional
            Opacity of the line strings. Higher values denote more visible
            line string.
            If ``None``, this value is derived from `alpha`.

        alpha_points : None or float, optional
            Opacity of the line string points. Higher values denote more
            visible points.
            If ``None``, this value is derived from `alpha`.

        size : int, optional
            Size of the line strings.
            The sizes of the line and points are derived from this value,
            unless they are set.

        size_lines : None or int, optional
            Thickness of the line segments.
            If ``None``, this value is derived from `size`.

        size_points : None or int, optional
            Size of the points in pixels.
            If ``None``, this value is derived from ``3 * size``.

        antialiased : bool, optional
            Whether to draw the lines with anti-aliasing activated.
            This does currently not affect the point drawing.

        raise_if_out_of_image : bool, optional
            Whether to raise an error if a line string 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.

        Returns
        -------
        ndarray
            Image with line strings drawn on it.

        """
        # TODO improve efficiency here by copying only once
        for ls in self.line_strings:
            image = ls.draw_on_image(
                image,
                color=color, color_lines=color_lines, color_points=color_points,
                alpha=alpha, alpha_lines=alpha_lines, alpha_points=alpha_points,
                size=size, size_lines=size_lines, size_points=size_points,
                antialiased=antialiased,
                raise_if_out_of_image=raise_if_out_of_image
            )

        return image

Draw all line strings onto a given image .


def clip_out_of_image(self):
        """
        Clip off all parts of the line strings that are outside of the image.

        Returns
        -------
        imgaug.augmentables.lines.LineStringsOnImage
            Line strings, clipped to fall within the image dimensions.

        """
        lss_cut = [ls_clipped
                   for ls in self.line_strings
                   for ls_clipped in ls.clip_out_of_image(self.shape)]
        return LineStringsOnImage(lss_cut, shape=self.shape)

def clip_out_of_image ( self ) : lss_cut = [ ls_clipped for ls in self . line_strings for ls_clipped in ls . clip_out_of_image ( self . shape ) ] return LineStringsOnImage ( lss_cut , shape = self . shape )

Clip off all parts of the line strings that are outside of the image .


def copy(self, line_strings=None, shape=None):
        """
        Create a shallow copy of the LineStringsOnImage object.

        Parameters
        ----------
        line_strings : None \
                       or list of imgaug.augmentables.lines.LineString, optional
            List of line strings on the image.
            If not ``None``, then the ``line_strings`` attribute of the copied
            object will be set to this value.

        shape : None or tuple of int or ndarray, optional
            The shape of the image on which the objects are placed.
            Either an image with shape ``(H,W,[C])`` or a tuple denoting
            such an image shape.
            If not ``None``, then the ``shape`` attribute of the copied object
            will be set to this value.

        Returns
        -------
        imgaug.augmentables.lines.LineStringsOnImage
            Shallow copy.

        """
        lss = self.line_strings if line_strings is None else line_strings
        shape = self.shape if shape is None else shape
        return LineStringsOnImage(line_strings=lss, shape=shape)

def copy ( self , line_strings = None , shape = None ) : lss = self . line_strings if line_strings is None else line_strings shape = self . shape if shape is None else shape return LineStringsOnImage ( line_strings = lss , shape = shape )

Create a shallow copy of the LineStringsOnImage object .


def deepcopy(self, line_strings=None, shape=None):
        """
        Create a deep copy of the LineStringsOnImage object.

        Parameters
        ----------
        line_strings : None \
                       or list of imgaug.augmentables.lines.LineString, optional
            List of line strings on the image.
            If not ``None``, then the ``line_strings`` attribute of the copied
            object will be set to this value.

        shape : None or tuple of int or ndarray, optional
            The shape of the image on which the objects are placed.
            Either an image with shape ``(H,W,[C])`` or a tuple denoting
            such an image shape.
            If not ``None``, then the ``shape`` attribute of the copied object
            will be set to this value.

        Returns
        -------
        imgaug.augmentables.lines.LineStringsOnImage
            Deep copy.

        """
        lss = self.line_strings if line_strings is None else line_strings
        shape = self.shape if shape is None else shape
        return LineStringsOnImage(
            line_strings=[ls.deepcopy() for ls in lss],
            shape=tuple(shape))

def deepcopy ( self , line_strings = None , shape = None ) : lss = self . line_strings if line_strings is None else line_strings shape = self . shape if shape is None else shape return LineStringsOnImage ( line_strings = [ ls . deepcopy ( ) for ls in lss ] , shape = tuple ( shape ) )

Create a deep copy of the LineStringsOnImage object .