:py:mod:`kwimage.structs.segmentation` ====================================== .. py:module:: kwimage.structs.segmentation .. autoapi-nested-parse:: Generic segmentation object that can use either a Mask or (Multi)Polygon backend. Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: kwimage.structs.segmentation._WrapperObject kwimage.structs.segmentation.Segmentation kwimage.structs.segmentation.SegmentationList Functions ~~~~~~~~~ .. autoapisummary:: kwimage.structs.segmentation._coerce_coco_segmentation .. py:class:: _WrapperObject Bases: :py:obj:`ubelt.NiceRepr` Inherit from this class and define ``__nice__`` to "nicely" print your objects. Defines ``__str__`` and ``__repr__`` in terms of ``__nice__`` function Classes that inherit from :class:`NiceRepr` should redefine ``__nice__``. If the inheriting class has a ``__len__``, method then the default ``__nice__`` method will return its length. .. rubric:: Example >>> import ubelt as ub >>> class Foo(ub.NiceRepr): ... def __nice__(self): ... return 'info' >>> foo = Foo() >>> assert str(foo) == '' >>> assert repr(foo).startswith('>> import ubelt as ub >>> class Bar(ub.NiceRepr): ... pass >>> bar = Bar() >>> import pytest >>> with pytest.warns(RuntimeWarning) as record: >>> assert 'object at' in str(bar) >>> assert 'object at' in repr(bar) .. rubric:: Example >>> import ubelt as ub >>> class Baz(ub.NiceRepr): ... def __len__(self): ... return 5 >>> baz = Baz() >>> assert str(baz) == '' .. rubric:: Example >>> import ubelt as ub >>> # If your nice message has a bug, it shouldn't bring down the house >>> class Foo(ub.NiceRepr): ... def __nice__(self): ... assert False >>> foo = Foo() >>> import pytest >>> with pytest.warns(RuntimeWarning) as record: >>> print('foo = {!r}'.format(foo)) foo = <...Foo ...> .. py:method:: __nice__(self) .. py:method:: draw(self, *args, **kw) .. py:method:: draw_on(self, *args, **kw) .. py:method:: warp(self, *args, **kw) .. py:method:: translate(self, *args, **kw) .. py:method:: scale(self, *args, **kw) .. py:method:: to_coco(self, *args, **kw) .. py:method:: numpy(self, *args, **kw) .. py:method:: tensor(self, *args, **kw) .. py:class:: Segmentation(data, format=None) Bases: :py:obj:`_WrapperObject` Either holds a MultiPolygon, Polygon, or Mask :Parameters: * **data** (*object*) -- the underlying object * **format** (*str*) -- either 'mask', 'polygon', or 'multipolygon' .. py:method:: random(cls, rng=None) :classmethod: .. rubric:: Example >>> self = Segmentation.random() >>> print('self = {!r}'.format(self)) >>> # xdoc: +REQUIRES(--show) >>> import kwplot >>> kwplot.autompl() >>> kwplot.figure(fnum=1, doclf=True) >>> self.draw() >>> kwplot.show_if_requested() .. py:method:: to_multi_polygon(self) .. py:method:: to_mask(self, dims=None) .. py:method:: meta(self) :property: .. py:method:: coerce(cls, data, dims=None) :classmethod: .. py:class:: SegmentationList Bases: :py:obj:`kwimage.structs._generic.ObjectList` Store and manipulate multiple segmentations (masks or polygons), usually within the same image .. py:method:: to_polygon_list(self) Converts all mask objects to multi-polygon objects .. py:method:: to_mask_list(self, dims=None) Converts all mask objects to multi-polygon objects .. py:method:: to_segmentation_list(self) .. py:method:: coerce(cls, data) :classmethod: Interpret data as a list of Segmentations .. py:function:: _coerce_coco_segmentation(data, dims=None) Attempts to auto-inspect the format of segmentation data :Parameters: * **data** -- the data to coerce 2D-C-ndarray -> C_MASK 2D-F-ndarray -> F_MASK Dict(counts=bytes) -> BYTES_RLE Dict(counts=ndarray) -> ARRAY_RLE Dict(exterior=ndarray) -> ARRAY_RLE # List[List[int]] -> Polygon List[int] -> Polygon List[Dict] -> MultPolygon * **dims** (*Tuple*) -- required for certain formats like polygons height / width of the source image :returns: Mask | Polygon | MultiPolygon - depending on which is appropriate .. rubric:: Example >>> segmentation = {'size': [5, 9], 'counts': ';?1B10O30O4'} >>> dims = (9, 5) >>> raw_mask = (np.random.rand(32, 32) > .5).astype(np.uint8) >>> _coerce_coco_segmentation(segmentation) >>> _coerce_coco_segmentation(raw_mask) >>> coco_polygon = [ >>> np.array([[3, 0],[2, 1],[2, 4],[4, 4],[4, 3],[7, 0]]), >>> np.array([[2, 1],[2, 2],[4, 2],[4, 1]]), >>> ] >>> self = _coerce_coco_segmentation(coco_polygon, dims) >>> print('self = {!r}'.format(self)) >>> coco_polygon = [ >>> np.array([[3, 0],[2, 1],[2, 4],[4, 4],[4, 3],[7, 0]]), >>> ] >>> self = _coerce_coco_segmentation(coco_polygon, dims) >>> print('self = {!r}'.format(self))