SegmentationImage

class photutils.segmentation.SegmentationImage(data)[source]

Bases: object

Class for a segmentation image.

Parameters
dataarray_like (int)

A segmentation array where source regions are labeled by different positive integer values. A value of zero is reserved for the background. The segmentation image must contain at least one non-zero pixel and must not contain any non-finite values (e.g., NaN, inf).

Attributes Summary

areas

A 1D array of areas (in pixel**2) of the non-zero labeled regions.

background_area

The area (in pixel**2) of the background (label=0) region.

bbox

A list of BoundingBox of the minimal bounding boxes containing the labeled regions.

data

The segmentation array.

data_ma

A MaskedArray version of the segmentation array where the background (label = 0) has been masked.

is_consecutive

Determine whether or not the non-zero labels in the segmentation array are consecutive and start from 1.

labels

The sorted non-zero labels in the segmentation array.

max_label

The maximum non-zero label in the segmentation array.

missing_labels

A 1D ndarray of the sorted non-zero labels that are missing in the consecutive sequence from one to the maximum label number.

nlabels

The number of non-zero labels in the segmentation array.

segments

A list of Segment objects.

shape

The shape of the segmentation array.

slices

A list of tuples, where each tuple contains two slices representing the minimal box that contains the labeled region.

Methods Summary

check_label(label)

Check that the input label is a valid label number within the segmentation array.

check_labels(labels)

Check that the input label(s) are valid label numbers within the segmentation array.

copy()

Return a deep copy of this class instance.

get_area(label)

The area (in pixel**2) of the region for the input label.

get_areas(labels)

The areas (in pixel**2) of the regions for the input labels.

get_index(label)

Find the index of the input label.

get_indices(labels)

Find the indices of the input labels.

keep_label(label[, relabel])

Keep only the specified label.

keep_labels(labels[, relabel])

Keep only the specified labels.

make_cmap([background_color, seed])

Define a matplotlib colormap consisting of (random) muted colors.

outline_segments([mask_background])

Outline the labeled segments.

reassign_label(label, new_label[, relabel])

Reassign a label number to a new number.

reassign_labels(labels, new_label[, relabel])

Reassign one or more label numbers.

relabel_consecutive([start_label])

Reassign the label numbers consecutively starting from a given label number.

remove_border_labels(border_width[, …])

Remove labeled segments near the array border.

remove_label(label[, relabel])

Remove the label number.

remove_labels(labels[, relabel])

Remove one or more labels.

remove_masked_labels(mask[, …])

Remove labeled segments located within a masked region.

Attributes Documentation

areas

A 1D array of areas (in pixel**2) of the non-zero labeled regions.

The ndarray starts with the non-zero label. The returned array has a length equal to the number of labels and matches the order of the labels attribute.

background_area

The area (in pixel**2) of the background (label=0) region.

bbox

A list of BoundingBox of the minimal bounding boxes containing the labeled regions.

data

The segmentation array.

data_ma

A MaskedArray version of the segmentation array where the background (label = 0) has been masked.

is_consecutive

Determine whether or not the non-zero labels in the segmentation array are consecutive and start from 1.

labels

The sorted non-zero labels in the segmentation array.

max_label

The maximum non-zero label in the segmentation array.

missing_labels

A 1D ndarray of the sorted non-zero labels that are missing in the consecutive sequence from one to the maximum label number.

nlabels

The number of non-zero labels in the segmentation array.

segments

A list of Segment objects.

The list starts with the non-zero label. The returned list has a length equal to the number of labels and matches the order of the labels attribute.

shape

The shape of the segmentation array.

slices

A list of tuples, where each tuple contains two slices representing the minimal box that contains the labeled region.

The list starts with the non-zero label. The returned list has a length equal to the number of labels and matches the order of the labels attribute.

Methods Documentation

check_label(label)[source]

Check that the input label is a valid label number within the segmentation array.

Parameters
labelint

The label number to check.

Raises
ValueError

If the input label is invalid.

check_labels(labels)[source]

Check that the input label(s) are valid label numbers within the segmentation array.

Parameters
labelsint, 1D array-like (int)

The label(s) to check.

Raises
ValueError

If any input labels are invalid.

copy()[source]

Return a deep copy of this class instance.

get_area(label)[source]

The area (in pixel**2) of the region for the input label.

Parameters
labelint

The label whose area to return. Label must be non-zero.

Returns
areandarray

The area of the labeled region.

get_areas(labels)[source]

The areas (in pixel**2) of the regions for the input labels.

Parameters
labelsint, 1D array-like (int)

The label(s) for which to return areas. Label must be non-zero.

Returns
areasndarray

The areas of the labeled regions.

get_index(label)[source]

Find the index of the input label.

Parameters
labelsint

The label numbers to find.

Returns
indexint

The array index.

Raises
ValueError

If label is invalid.

get_indices(labels)[source]

Find the indices of the input labels.

Parameters
labelsint, array-like (1D, int)

The label numbers(s) to find.

Returns
indicesint ndarray

An integer array of indices with the same shape as labels. If labels is a scalar, then the returned index will also be a scalar.

Raises
ValueError

If any input labels are invalid.

keep_label(label, relabel=False)[source]

Keep only the specified label.

Parameters
labelint

The label number to keep.

relabelbool, optional

If True, then the single segment will be assigned a label value of 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.keep_label(label=3)
>>> segm.data
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 3, 3, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.keep_label(label=3, relabel=True)
>>> segm.data
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])
keep_labels(labels, relabel=False)[source]

Keep only the specified labels.

Parameters
labelsint, array-like (1D, int)

The label number(s) to keep.

relabelbool, optional

If True, then the segmentation array will be relabeled such that the labels are in consecutive order starting from 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.keep_labels(labels=[5, 3])
>>> segm.data
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 3, 3, 0, 0],
       [0, 0, 0, 0, 0, 5],
       [0, 0, 0, 5, 5, 5],
       [0, 0, 0, 0, 5, 5]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.keep_labels(labels=[5, 3], relabel=True)
>>> segm.data
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 2],
       [0, 0, 0, 2, 2, 2],
       [0, 0, 0, 0, 2, 2]])
make_cmap(background_color='#000000', seed=None)[source]

Define a matplotlib colormap consisting of (random) muted colors.

This is very useful for plotting the segmentation array.

Parameters
background_colorstr or None, optional

A hex string in the “#rrggbb” format defining the first color in the colormap. This color will be used as the background color (label = 0) when plotting the segmentation array. The default is black (‘#000000’).

seedint, optional

A seed to initialize the numpy.random.BitGenerator. If None, then fresh, unpredictable entropy will be pulled from the OS. Separate function calls with the same seed will generate the same colormap.

Returns
cmapmatplotlib.colors.ListedColormap

The matplotlib colormap.

outline_segments(mask_background=False)[source]

Outline the labeled segments.

The “outlines” represent the pixels just inside the segments, leaving the background pixels unmodified.

Parameters
mask_backgroundbool, optional

Set to True to mask the background pixels (labels = 0) in the returned array. This is useful for overplotting the segment outlines. The default is False.

Returns
boundariesndarray or MaskedArray

An array with the same shape of the segmentation array containing only the outlines of the labeled segments. The pixel values in the outlines correspond to the labels in the segmentation array. If mask_background is True, then a MaskedArray is returned.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[0, 0, 0, 0, 0, 0],
...                           [0, 2, 2, 2, 2, 0],
...                           [0, 2, 2, 2, 2, 0],
...                           [0, 2, 2, 2, 2, 0],
...                           [0, 2, 2, 2, 2, 0],
...                           [0, 0, 0, 0, 0, 0]])
>>> segm.outline_segments()
array([[0, 0, 0, 0, 0, 0],
       [0, 2, 2, 2, 2, 0],
       [0, 2, 0, 0, 2, 0],
       [0, 2, 0, 0, 2, 0],
       [0, 2, 2, 2, 2, 0],
       [0, 0, 0, 0, 0, 0]])
reassign_label(label, new_label, relabel=False)[source]

Reassign a label number to a new number.

If new_label is already present in the segmentation array, then it will be combined with the input label number.

Parameters
labelsint

The label number to reassign.

new_labelint

The newly assigned label number.

relabelbool, optional

If True, then the segmentation array will be relabeled such that the labels are in consecutive order starting from 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.reassign_label(label=1, new_label=2)
>>> segm.data
array([[2, 2, 0, 0, 4, 4],
       [0, 0, 0, 0, 0, 4],
       [0, 0, 3, 3, 0, 0],
       [7, 0, 0, 0, 0, 5],
       [7, 7, 0, 5, 5, 5],
       [7, 7, 0, 0, 5, 5]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.reassign_label(label=1, new_label=4)
>>> segm.data
array([[4, 4, 0, 0, 4, 4],
       [0, 0, 0, 0, 0, 4],
       [0, 0, 3, 3, 0, 0],
       [7, 0, 0, 0, 0, 5],
       [7, 7, 0, 5, 5, 5],
       [7, 7, 0, 0, 5, 5]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.reassign_label(label=1, new_label=4, relabel=True)
>>> segm.data
array([[2, 2, 0, 0, 2, 2],
       [0, 0, 0, 0, 0, 2],
       [0, 0, 1, 1, 0, 0],
       [4, 0, 0, 0, 0, 3],
       [4, 4, 0, 3, 3, 3],
       [4, 4, 0, 0, 3, 3]])
reassign_labels(labels, new_label, relabel=False)[source]

Reassign one or more label numbers.

Multiple input labels will all be reassigned to the same new_label number. If new_label is already present in the segmentation array, then it will be combined with the input labels.

Parameters
labelsint, array-like (1D, int)

The label numbers(s) to reassign.

new_labelint

The reassigned label number.

relabelbool, optional

If True, then the segmentation array will be relabeled such that the labels are in consecutive order starting from 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.reassign_labels(labels=[1, 7], new_label=2)
>>> segm.data
array([[2, 2, 0, 0, 4, 4],
       [0, 0, 0, 0, 0, 4],
       [0, 0, 3, 3, 0, 0],
       [2, 0, 0, 0, 0, 5],
       [2, 2, 0, 5, 5, 5],
       [2, 2, 0, 0, 5, 5]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.reassign_labels(labels=[1, 7], new_label=4)
>>> segm.data
array([[4, 4, 0, 0, 4, 4],
       [0, 0, 0, 0, 0, 4],
       [0, 0, 3, 3, 0, 0],
       [4, 0, 0, 0, 0, 5],
       [4, 4, 0, 5, 5, 5],
       [4, 4, 0, 0, 5, 5]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.reassign_labels(labels=[1, 7], new_label=2, relabel=True)
>>> segm.data
array([[1, 1, 0, 0, 3, 3],
       [0, 0, 0, 0, 0, 3],
       [0, 0, 2, 2, 0, 0],
       [1, 0, 0, 0, 0, 4],
       [1, 1, 0, 4, 4, 4],
       [1, 1, 0, 0, 4, 4]])
relabel_consecutive(start_label=1)[source]

Reassign the label numbers consecutively starting from a given label number.

Parameters
start_labelint, optional

The starting label number, which should be a strictly positive integer. The default is 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.relabel_consecutive()
>>> segm.data
array([[1, 1, 0, 0, 3, 3],
       [0, 0, 0, 0, 0, 3],
       [0, 0, 2, 2, 0, 0],
       [5, 0, 0, 0, 0, 4],
       [5, 5, 0, 4, 4, 4],
       [5, 5, 0, 0, 4, 4]])
remove_border_labels(border_width, partial_overlap=True, relabel=False)[source]

Remove labeled segments near the array border.

Labels within the defined border region will be removed.

Parameters
border_widthint

The width of the border region in pixels.

partial_overlapbool, optional

If this is set to True (the default), a segment that partially extends into the border region will be removed. Segments that are completely within the border region are always removed.

relabelbool, optional

If True, then the segmentation array will be relabeled such that the labels are in consecutive order starting from 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.remove_border_labels(border_width=1)
>>> segm.data
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 3, 3, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.remove_border_labels(border_width=1,
...                           partial_overlap=False)
>>> segm.data
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 3, 3, 0, 0],
       [7, 0, 0, 0, 0, 5],
       [7, 7, 0, 5, 5, 5],
       [7, 7, 0, 0, 5, 5]])
remove_label(label, relabel=False)[source]

Remove the label number.

The removed label is assigned a value of zero (i.e., background).

Parameters
labelint

The label number to remove.

relabelbool, optional

If True, then the segmentation array will be relabeled such that the labels are in consecutive order starting from 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.remove_label(label=5)
>>> segm.data
array([[1, 1, 0, 0, 4, 4],
       [0, 0, 0, 0, 0, 4],
       [0, 0, 3, 3, 0, 0],
       [7, 0, 0, 0, 0, 0],
       [7, 7, 0, 0, 0, 0],
       [7, 7, 0, 0, 0, 0]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.remove_label(label=5, relabel=True)
>>> segm.data
array([[1, 1, 0, 0, 3, 3],
       [0, 0, 0, 0, 0, 3],
       [0, 0, 2, 2, 0, 0],
       [4, 0, 0, 0, 0, 0],
       [4, 4, 0, 0, 0, 0],
       [4, 4, 0, 0, 0, 0]])
remove_labels(labels, relabel=False)[source]

Remove one or more labels.

Removed labels are assigned a value of zero (i.e., background).

Parameters
labelsint, array-like (1D, int)

The label number(s) to remove.

relabelbool, optional

If True, then the segmentation array will be relabeled such that the labels are in consecutive order starting from 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.remove_labels(labels=[5, 3])
>>> segm.data
array([[1, 1, 0, 0, 4, 4],
       [0, 0, 0, 0, 0, 4],
       [0, 0, 0, 0, 0, 0],
       [7, 0, 0, 0, 0, 0],
       [7, 7, 0, 0, 0, 0],
       [7, 7, 0, 0, 0, 0]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.remove_labels(labels=[5, 3], relabel=True)
>>> segm.data
array([[1, 1, 0, 0, 2, 2],
       [0, 0, 0, 0, 0, 2],
       [0, 0, 0, 0, 0, 0],
       [3, 0, 0, 0, 0, 0],
       [3, 3, 0, 0, 0, 0],
       [3, 3, 0, 0, 0, 0]])
remove_masked_labels(mask, partial_overlap=True, relabel=False)[source]

Remove labeled segments located within a masked region.

Parameters
maskarray_like (bool)

A boolean mask, with the same shape as the segmentation array, where True values indicate masked pixels.

partial_overlapbool, optional

If this is set to True (default), a segment that partially extends into a masked region will also be removed. Segments that are completely within a masked region are always removed.

relabelbool, optional

If True, then the segmentation array will be relabeled such that the labels are in consecutive order starting from 1.

Examples

>>> from photutils.segmentation import SegmentationImage
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> mask = np.zeros(segm.data.shape, dtype=bool)
>>> mask[0, :] = True  # mask the first row
>>> segm.remove_masked_labels(mask)
>>> segm.data
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 3, 3, 0, 0],
       [7, 0, 0, 0, 0, 5],
       [7, 7, 0, 5, 5, 5],
       [7, 7, 0, 0, 5, 5]])
>>> segm = SegmentationImage([[1, 1, 0, 0, 4, 4],
...                           [0, 0, 0, 0, 0, 4],
...                           [0, 0, 3, 3, 0, 0],
...                           [7, 0, 0, 0, 0, 5],
...                           [7, 7, 0, 5, 5, 5],
...                           [7, 7, 0, 0, 5, 5]])
>>> segm.remove_masked_labels(mask, partial_overlap=False)
>>> segm.data
array([[0, 0, 0, 0, 4, 4],
       [0, 0, 0, 0, 0, 4],
       [0, 0, 3, 3, 0, 0],
       [7, 0, 0, 0, 0, 5],
       [7, 7, 0, 5, 5, 5],
       [7, 7, 0, 0, 5, 5]])