Skip to content

Conversation

@srivarra
Copy link
Collaborator

@srivarra srivarra commented Sep 15, 2025

Add NGFF-Compliant Labels Support for Positions/FOVs

Implements labels group support for NGFF Positions, see the OME-NGFF specification for more information.

Usage

import numpy as np
from iohub.ngff.nodes import open_ome_zarr

# Create segmentation mask (TZYX format, no channel dimension)
segmentation = np.zeros((1, 1, 1024, 1024), dtype=np.uint16)
segmentation[0, 0, 100:200, 100:200] = 1  # Cell region

with open_ome_zarr("dataset.zarr", mode="r+") as position:
    # Create multiscale label image with colors
    cells = position.create_label(
        name="cells",
        data=segmentation,
        colors={1: [255, 0, 0, 255]},
    )

    # Access different resolutions
    high_res = cells["0"].numpy()     # Full resolution data
    downscaled = cells["1"].numpy()   # Empty (fill manually like images)

    # Iterate over all labels
    for name, label_image in position.labels():
        print(f"{name}: {label_image.array_keys()}")
    
    # Select a single label group based on it's name.
    positions.get_label("cells")

Changes

  • Added LabelImage class for multiscale label management
  • Extended Position with create_label(), get_label(), labels() methods

@srivarra srivarra linked an issue Sep 15, 2025 that may be closed by this pull request
Copy link
Contributor

@ziw-liu ziw-liu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seem to be significant code duplication, largely copy-pasting Position/ImageArray. Is this necessary or just an LLM-generated proof-of-concept?

@srivarra
Copy link
Collaborator Author

@ziw-liu Largely copy pasted for now just to test with. I plan consolidating the shared functionality in a following commit.

@ieivanov
Copy link
Contributor

@Soorya19Pradeep could you link one example annotation from the DynaCell datasets such that @srivarra can prototype turning it into this new format?

@srivarra do you compute pyramid levels on the labels array yourself? How do you do that currently? When doing that you'd need to be careful not to create extra labels - the number of unique labels should be the same at all pyramid levels. If you are to simply block average an image with 0s and 1s you'd end up 0.5s at the border which wouldn't make sense. You could use the median instead of the mean to compute the lower pyramid levels - there may be proper / better algorithms to do that.

@Soorya19Pradeep
Copy link

@ieivanov, the human annotations are saved from Napari as a CSV. This information, combined with tracking information, creates the format we use with the embedding for that FOV. Do you need the raw version or the curated one?

@srivarra, you can find such a raw files inside: /hpc/projects/intracellular_dashboard/organelle_dynamics/2024_11_07_A549_SEC61_DENV/4-phenotyping/0-annotation/B/3/001000/ as infected.csv and uninfected.csv and the curated version for that FOV here: /hpc/projects/intracellular_dashboard/organelle_dynamics/2024_11_07_A549_SEC61_DENV/4-phenotyping/0-annotation/track_infection_annotation_B_3_001000.csv.

@srivarra srivarra self-assigned this Oct 28, 2025
@srivarra srivarra marked this pull request as ready for review October 28, 2025 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Save grayscale data and binary masks in the OME-zarr store

4 participants