phenotypic.Image.objmap#
- property Image.objmap: ObjectMap#
Returns the ObjectMap accessor; The object map is a mutable integer gray that identifies the different objects in an image to be analyzed. Changes to elements of the object_map sync to the object_mask.
The object_map is stored as a compressed sparse column gray in the backend. This is to save on memory consumption at the cost of adding increased computational overhead between converting between sparse and dense matrices.
Note
Has accessor methods to get sparse representations of the object map that can streamline measurement calculations.
- Returns:
A mutable integer gray that identifies the different objects in an image to be analyzed.
- Return type:
ObjectMap
See Also:
ObjectMap
ObjectMap API#
- class phenotypic.core._image_parts.accessors.ObjectMap(root_image: Image)[source]
Bases:
SingleChannelAccessorManages an object map for labeled regions in an image.
This class provides a mechanism to manipulate and access labeled object maps within a given image. It is tightly coupled with the parent image object and provides methods for accessing sparse and dense representations, relabeling, resetting, and visualization.
The object map is stored internally as a compressed sparse column (CSC) matrix for memory efficiency. All public methods expose the data through dense array interfaces for ease of use while maintaining the sparse representation backend. Changes to the object map shapes are automatically reflected in the object mask.
The class supports array-like indexing and slicing operations, sparse format conversion, and visualization with matplotlib.
- Parameters:
root_image (Image)
- _root_image
The parent Image object that this accessor is associated with.
Note
Changes to the object map shapes will be automatically reflected in the object mask.
- __array__(dtype=None, copy=None)[source]
Implement the array interface for NumPy compatibility.
This method enables NumPy functions to operate directly on ObjectMap instances by converting the sparse representation to a dense array. It allows usage patterns such as np.sum(objmap), np.max(objmap), and array unpacking operations.
- Parameters:
dtype (type, optional) – Optional NumPy dtype to cast the array to. If None, the array maintains its native dtype. Defaults to None.
copy (bool, optional) – Control whether the underlying data is copied. If True, a copy is guaranteed. If False (NumPy 2.0+), no copy is made. If None, a copy is made only if necessary for dtype conversion. Defaults to None.
- Returns:
- A dense NumPy array representation of the object map
with shape matching the image dimensions (height, width).
- Return type:
np.ndarray
Examples
Using ObjectMap with NumPy functions
import numpy as np objmap = image.objmap max_label = np.max(objmap) unique_labels = np.unique(objmap) arr = np.asarray(objmap, dtype=np.uint32)
- __getitem__(key)[source]
Return a slice of the object map as if it were a dense array.
This method implements NumPy-style slicing and indexing for the ObjectMap. The sparse representation is converted to dense for the indexing operation, allowing all standard NumPy slicing patterns including integer indexing, boolean masking, and multi-dimensional slicing.
- Parameters:
key – Index or slice specification. Can be an integer, tuple of integers, slice object, boolean array, or integer array for advanced indexing. All NumPy indexing patterns are supported.
- Returns:
- The sliced portion of the object map as a dense array.
The returned shape depends on the indexing pattern. Returns a scalar if a single element is indexed, otherwise returns an ndarray.
- Return type:
np.ndarray
Examples
NumPy-style indexing and slicing
objmap = image.objmap row = objmap[5] # Get row 5 region = objmap[10:20, 30:40] # Get a rectangular region pixel = objmap[5, 10] # Get a single pixel mask = objmap[objmap > 0] # Boolean indexing
- __len__() int
Returns the length of the subject array.
This method calculates and returns the total number of elements contained in the underlying array.
- Returns:
The number of elements in the underlying array attribute.
- Return type:
- __setitem__(key, value)[source]
Set values in the object map as if it were a dense array.
This method implements NumPy-style assignment for the ObjectMap. It accepts both array and scalar values, validates shapes and types, and atomically updates the internal sparse representation. The operation is atomic with respect to the backend reference.
- Parameters:
key – Index or slice specification for the location to update. Can be an integer, tuple of integers, slice object, boolean array, or integer array. All NumPy indexing patterns are supported.
value – The value(s) to assign. Can be: - A NumPy array matching the shape of the key selection - A scalar integer, bool, or float (converted to int)
- Raises:
ArrayKeyValueShapeMismatchError – If the shape or dtype of a supplied array does not match the shape of the key selection, or if the dtypes are incompatible.
InvalidMapValueError – If value is not a supported type (not an array, int, bool, or float).
Notes
After assignment, the sparse matrix is compressed and zeros are eliminated to maintain memory efficiency.
All values are internally cast to uint16 to match the sparse matrix dtype and represent object labels.
The operation is atomic: if an exception occurs, the map is not modified.
Examples
Assigning values to the object map
objmap = image.objmap # Set a single pixel objmap[5, 10] = 3 # Set a region with a scalar value objmap[10:20, 30:40] = 0 # Set a region with an array region_labels = np.array([[1, 1], [1, 1]]) objmap[10:12, 30:32] = region_labels
- as_coo() coo_matrix[source]
Return the object map in COOrdinate (ijv) sparse format.
Converts the internal object map representation to COO (Coordinate or ijv) format, which stores non-zero elements as (row, column, value) tuples. This format is useful for constructing sparse matrices or analyzing individual non-zero entries.
- Returns:
A copy of the object map in COO sparse format.
- Return type:
Examples
Converting to COO sparse format and accessing entries
sparse_coo = image.objmap.as_coo() # Access non-zero entries directly for i, j, v in zip(sparse_coo.row, sparse_coo.col, sparse_coo.data): print(f"Object label {v} at position ({i}, {j})")
- as_csc() csc_matrix[source]
Return the object map as a compressed sparse column matrix.
Converts the internal object map representation to CSC (Compressed Sparse Column) format. CSC format is optimized for column slicing and matrix operations.
- Returns:
A copy of the object map in CSC sparse format.
- Return type:
Examples
Converting to CSC sparse format
sparse_csc = image.objmap.as_csc() # Efficient column operations first_column = sparse_csc[:, 0].toarray()
- copy() numpy.ndarray[source]
Return a dense copy of the object map.
Creates and returns a dense NumPy array copy of the object map. The returned array is independent and modifications to it will not affect the original object map.
- Returns:
- A dense copy of the object map with shape (height, width)
and dtype uint16.
- Return type:
np.ndarray
Examples
Creating an independent copy of the object map
objmap_copy = image.objmap.copy() objmap_copy[0, 0] = 999 # Modifications don't affect the original assert image.objmap[0, 0] != 999
- foreground()
Extracts and returns the foreground of the image by masking out the background.
This method generates a foreground image by applying the object mask stored in the Image to the current array representation. Pixels outside the object mask are set to zero in the resulting foreground image. This is useful in image processing tasks to isolate the region of interest in the image, such as microbe colonies on an agar plate.
- Returns:
A numpy array containing only the foreground portion of the image, with all non-foreground pixels set to zero.
- Return type:
- histogram(figsize: Tuple[int, int] = (10, 5), *, cmap='gray', linewidth=1, channel_names: list | None = None) Tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]
Plots the histogram(s) of an image along with the image itself. The behavior depends on the dimensionality of the image array (2D or 3D). In the case of 2D, a single image and its histogram are produced. For 3D (multi-channel images), histograms for each channel are created alongside the image. This method supports customization such as figure size, colormap, line width of histograms, and labeling of channels.
- Parameters:
figsize (Tuple[int, int]) – The size of the figure to create. Default is (10, 5).
cmap (str) – Colormap used to render the image when the data is single channel. Default is ‘gray’.
linewidth (int) – Line width of the plotted histograms. Default is 1.
channel_names (list | None) – Optional names for the channels in 3D data. These are used as titles for channel-specific histograms. If None, channels are instead labeled numerically.
- Returns:
The Matplotlib figure and axes objects representing the plotted image and its histograms.
- Return type:
Tuple[plt.Figure, plt.Axes]
- Raises:
ValueError – If the dimensionality of the input image array is unsupported.
Notes
This method uses skimage.exposure.histogram for computing the histogram data.
- imsave(filepath: str | Path | None = None) None
Save the image array to a file with PhenoTypic metadata embedded.
Metadata is embedded in format-specific locations: - JPEG: EXIF UserComment tag - PNG: tEXt chunk with key ‘phenotypic’ - TIFF: ImageDescription tag (270)
- Parameters:
filepath (str | Path | None) – Path to save the image file. Extension determines format.
- Raises:
ValueError – If file extension is not supported.
- Return type:
None
- isempty()
- classmethod load(filepath: str | Path) numpy.ndarray
Load an image array from file and verify it was saved from this accessor type.
Checks if the image contains PhenoTypic metadata indicating it was saved from the same accessor type (e.g., Image.gray, Image.rgb). If metadata doesn’t match or is missing, a warning is raised but the array is still loaded.
- Parameters:
- Returns:
The loaded image array.
- Return type:
np.ndarray
- Warns:
UserWarning – If metadata is missing or indicates the image was saved from a different accessor type.
Examples
Load a grayscale image from file
>>> from phenotypic.core._image_parts.accessors import Grayscale >>> arr = Grayscale.load("my_gray_image.png")
- relabel(connectivity: int = 1)[source]
Relabel all connected components in the object map.
This method reassigns labels to all connected components in the current object map based on the specified connectivity criterion. It uses scikit-image’s label function to identify connected components and assigns them new sequential labels starting from 1. This is useful when:
Object labels are non-sequential or have gaps
The labeling needs to be reset to sequential labels
Connectivity needs to be changed (e.g., from 8-connectivity to 4-connectivity)
The operation treats the current object map as a binary mask (foreground vs. background) and relabels the foreground regions.
- Parameters:
connectivity (int, optional) – Maximum number of orthogonal hops to consider a pixel as a neighbor of another. For 2D images: - 1: 4-connectivity (horizontal and vertical neighbors only) - 2: 8-connectivity (including diagonal neighbors) Higher values are supported for higher dimensional data. Defaults to 1.
- Returns:
The operation modifies the object map in-place.
- Return type:
None
Notes
Background (label 0) is preserved in its original location.
After relabeling, object labels will be sequential (1, 2, 3, …).
The relabeling process may change existing label values.
Examples
Relabeling connected components
# Relabel with 4-connectivity image.objmap.relabel(connectivity=1) # Relabel with 8-connectivity for diagonal neighbors image.objmap.relabel(connectivity=2)
See also
scikit-image.measure.label(): The underlying function used for connected component labeling.
- reset() None[source]
Reset the object map to an empty state with no labeled objects.
Clears all object labels from the object map, effectively removing all detected or manually-set objects. The resulting map contains only zeros (background). The shape of the map is preserved to match the parent image’s dimensions.
This method is useful when you want to clear the current segmentation and prepare for a new detection or labeling operation.
Examples
Clearing all objects from the object map
image.objmap.reset() # Now image.objmap contains no objects assert image.objmap[:].max() == 0
- Return type:
None
- show(figsize=None, title=None, cmap: str = 'nipy_spectral', ax: None | plt.Axes = None, mpl_params: None | dict = None)[source]
Display the object map using matplotlib’s imshow.
This method visualizes the labeled object map using matplotlib. Each unique label is assigned a distinct color from the specified colormap, allowing visual distinction between labeled objects. The background (label 0) is typically shown in a neutral color.
- Parameters:
figsize (tuple[int, int], optional) – Tuple specifying the figure size in inches (width, height). If None, uses the default matplotlib figure size. Defaults to None.
title (str, optional) – Title text for the plot. If None, no title is displayed. Defaults to None.
cmap (str, optional) – The colormap name used for rendering the labeled object map. A diverse colormap like ‘nipy_spectral’ is recommended for clearly distinguishing between many objects. Defaults to ‘nipy_spectral’.
ax (plt.Axes, optional) – Existing Matplotlib Axes object where the object map will be plotted. If None, a new figure and axes are created. Defaults to None.
mpl_params (dict, optional) – Additional parameters passed to matplotlib’s imshow function for plot customization (e.g., interpolation, normalization). If None, no extra parameters are applied. Defaults to None.
- Returns:
- A tuple containing the matplotlib Figure
and Axes objects where the object map is rendered. If an existing axes was provided, its parent figure is returned.
- Return type:
tuple[plt.Figure, plt.Axes]
Examples
Displaying the object map with various options
# Basic visualization fig, ax = image.objmap.show() # Custom figure size and title fig, ax = image.objmap.show(figsize=(10, 8), title='Labeled Objects') # Use a different colormap fig, ax = image.objmap.show(cmap='tab20') # Plot on an existing axes fig, ax = plt.subplots(1, 2, figsize=(12, 5)) image.objmap.show(ax=ax[0]) image.gray.show(ax=ax[1])
- show_overlay(object_label: int | None = None, figsize: tuple[int, int] | None = None, title: str | None = None, show_labels: bool = False, ax: matplotlib.axes.Axes | None = None, *, label_settings: dict | None = None, overlay_settings: dict | None = None, imshow_settings: dict | None = None) tuple[matplotlib.figure.Figure, matplotlib.axes.Axes]
Displays an overlay of the object map on the parent image with optional annotations.
- This method enables visualization by overlaying object regions on the parent image. It
provides options for customization, including the ability to show_labels specific objects
and adjust visual styles like figure size, colors, and annotation properties.
- Parameters:
object_label (None | int) – Specific object label to be highlighted. If None, all objects are displayed.
figsize (tuple[int, int]) – Size of the figure in inches (width, height).
title (None | str) – Title for the plot. If None, the parent image’s name is used.
show_labels (bool) – If True, displays annotations for object labels on the object centroids.
label_settings (None | dict) – Additional parameters for customization of the object annotations. Defaults: size=12, color=’white’, facecolor=’red’. Other kwargs are passed to the matplotlib.axes.text () method.
ax (plt.Axes) – Optional Matplotlib Axes object. If None, a new Axes is created.
overlay_settings (None | dict) – Additional parameters for customization of the overlay.
imshow_settings (None|dict) – Additional Matplotlib imshow configuration parameters for customization. If None, default Matplotlib settings will apply.
- Returns:
Matplotlib Figure and Axes objects containing the generated plot.
- Return type:
tuple[plt.Figure, plt.Axes]
- val_range() pd.Interval
Return the closed interval [min, max] of the subject array values.
- Returns:
A single closed interval including both endpoints.
- Return type:
pd.Interval
- property dtype
- property ndim: int
Returns the number of dimensions of the underlying array.
The ndim property provides access to the dimensionality of the array being encapsulated in the object. This value corresponds to the number of axes or dimensions the underlying array possesses. It can be useful for understanding the structure of the contained data.
- Returns:
The number of dimensions of the underlying array.
- Return type:
- property shape: tuple[int, int]
Return the shape of the object map.
Returns the dimensions of the object map as a tuple of (height, width). This matches the shape of the parent image’s grayscale representation.
- Returns:
- A tuple (height, width) representing the spatial
dimensions of the object map.
- Return type:
Examples
Getting object map dimensions
height, width = image.objmap.shape print(f"Object map dimensions: {width}x{height}")