Skip to main content

Convert between itk and napari data structures

Project description

itk-napari-conversion

PyPI License tests

Convert between itk and napari data structures.

Installation

pip install itk-napari-conversion

Usage

Image Conversion

Convert ITK Image to napari Image Layer

Convert an itk.Image to a napari.layers.Image:

from itk_napari_conversion import image_layer_from_image

image_layer = image_layer_from_image(image)

Features:

  • Automatically detects and handles RGB/RGBA images
  • Preserves image metadata (spacing, origin, direction, custom metadata)
  • Converts ITK's physical space information to napari's layer transformations:
    • spacingscale
    • origintranslate
    • directionrotate

Example:

import itk
import napari
from itk_napari_conversion import image_layer_from_image

# Read an image
image = itk.imread('path/to/image.nrrd')

# Add custom metadata
image['units'] = 'mm'
image['patient_id'] = '12345'

# Convert to napari layer
image_layer = image_layer_from_image(image)

# The layer will have:
# - image_layer.scale = image spacing (in reverse order for NumPy)
# - image_layer.translate = image origin (in reverse order for NumPy)
# - image_layer.rotate = image direction matrix (in reverse order for NumPy)
# - image_layer.metadata = all custom metadata

Convert napari Image Layer to ITK Image

Convert a napari.layers.Image to an itk.Image:

from itk_napari_conversion import image_from_image_layer

image = image_from_image_layer(image_layer)

Features:

  • Automatically handles RGB/RGBA layers
  • Converts napari layer transformations back to ITK physical space:
    • scalespacing
    • translateorigin
    • rotatedirection
  • Preserves all metadata from the layer

Example:

import numpy as np
import napari
from itk_napari_conversion import image_from_image_layer

# Create a napari image layer with transformations
viewer = napari.Viewer()
data = np.random.rand(100, 100, 100)

# 45 degree rotation around z-axis
angle = np.radians(45)
rotate = np.array([
    [np.cos(angle), -np.sin(angle), 0],
    [np.sin(angle), np.cos(angle), 0],
    [0, 0, 1]
], dtype=np.float64)

layer = viewer.add_image(
    data,
    scale=[2.0, 1.5, 1.5],  # anisotropic spacing
    rotate=rotate,
    translate=[10.0, 20.0, 30.0],
    metadata={'description': 'My volume'}
)

# Convert to ITK
image = image_from_image_layer(layer)

# The ITK image will have:
# - spacing: coordinates in ITK order, so reversed from napari `scale`: [1.5, 1.5, 2.0]
# - origin: coordinates in ITK order, so reversed from napari `translate`: [30.0, 20.0, 10.0]
# The ITK image will have:
# - spacing: coordinates in ITK order, so reversed from napari `scale`: [1.5, 1.5, 2.0]
# - origin: coordinates in ITK order, so reversed from napari `translate`: [30.0, 20.0, 10.0]
# - direction: transpose of napari `rotate` matrix

# Access the direction matrix via dictionary access (recommended):
direction = image["direction"]
print(direction)
# [[0.70710678 0.70710678 0.        ]
#  [-0.70710678 0.70710678 0.        ]
#  [0.         0.         1.        ]]

# This is the transpose of napari's rotate matrix:
#   [[cos(45°), sin(45°), 0],
#    [-sin(45°), cos(45°), 0],
#    [0, 0, 1]]

# Note: image.GetDirection() may return a different matrix because it accesses
# the underlying ITK image metadata differently. Use dictionary access for
# consistency with how the direction was set.

Point Set Conversion

Convert ITK PointSet to napari Points Layer

Convert an itk.PointSet to a napari.layers.Points:

from itk_napari_conversion import points_layer_from_point_set

points_layer = points_layer_from_point_set(point_set)

Features:

  • Extracts point coordinates from ITK PointSet using itk.array_from_vector_container()
  • Converts point data (if present) to napari features dictionary
    • Uses the first component as the 'feature' key
  • Returns a napari.layers.Points object

Example:

import itk
import numpy as np
from itk_napari_conversion import points_layer_from_point_set

# Create ITK PointSet
PointSetType = itk.PointSet[itk.F, 3]
point_set = PointSetType.New()

# Add points
points_data = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=np.float32)
points = itk.vector_container_from_array(points_data.flatten())
point_set.SetPoints(points)

# Add point data (features)
feature_data = np.array([10.0, 20.0], dtype=np.float32)
point_data = itk.vector_container_from_array(feature_data)
point_set.SetPointData(point_data)

# Convert to napari
points_layer = points_layer_from_point_set(point_set)
# points_layer.features['feature'] will contain [10.0, 20.0]

Convert napari Points Layer to ITK PointSet

Convert a napari.layers.Points to an itk.PointSet:

from itk_napari_conversion import point_set_from_points_layer

point_set = point_set_from_points_layer(points_layer)

Features:

  • Applies napari transformations (scale, rotate, translate) to point coordinates before conversion
  • Extracts points from napari layer data
  • Converts the first feature column (if present) to ITK point data
  • Returns an itk.PointSet object with dimension determined from the data

Example:

import napari
import numpy as np
from itk_napari_conversion import point_set_from_points_layer

# Create napari Points layer with transformations
data = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
features = {'intensity': np.array([10.0, 20.0])}
scale = np.array([2.0, 2.0, 2.0])
translate = np.array([100.0, 200.0, 300.0])

# Optional: add rotation (90 degrees around z-axis)
angle = np.radians(90)
rotate = np.array([
    [np.cos(angle), -np.sin(angle), 0],
    [np.sin(angle), np.cos(angle), 0],
    [0, 0, 1]
])

points_layer = napari.layers.Points(
    data,
    features=features,
    scale=scale,
    rotate=rotate,
    translate=translate
)

# Convert to ITK PointSet
point_set = point_set_from_points_layer(points_layer)

# The points in the ITK PointSet will be in world coordinates:
# ((data * scale) @ rotate.T) + translate
# Point data will be stored from the 'intensity' feature

Transformation Handling

Images

  • ITK → napari: Physical space metadata (spacing, origin, direction) is converted to napari layer transformations
  • napari → ITK: Layer transformations are converted back to ITK physical space metadata

Points

  • ITK → napari: Points are copied as-is without transformations (identity transform assumed)
  • napari → ITK: Layer transformations (scale, rotate, translate) are applied to points to convert them to world coordinates
    • Transformations are applied in order: scale → rotate → translate

Notes

Images:

  • Supports 2D, 3D, and multi-dimensional images
  • RGB and RGBA images are automatically detected and handled
  • Axis order is automatically reversed between ITK (x, y, z) and NumPy/napari (z, y, x)
  • Metadata is preserved bidirectionally

Points:

  • Point data in ITK is stored as float32
  • Only the first feature column from napari is used for ITK point data
  • Empty point sets are handled gracefully
  • Dimension is automatically determined from the point data shape
  • Metadata conversion is not currently supported for point sets

Hacking


Contributions are welcome!

To test locally:

git clone https://github.com/InsightSoftwareConsortium/itk-napari-conversion.git
cd itk-napari-conversation
pip install flit pytest
flit install --symlink
pytest tests.py

Follow the itk contributing guidelines and the itk code of conduct.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

itk_napari_conversion-0.5.1.tar.gz (54.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

itk_napari_conversion-0.5.1-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file itk_napari_conversion-0.5.1.tar.gz.

File metadata

  • Download URL: itk_napari_conversion-0.5.1.tar.gz
  • Upload date:
  • Size: 54.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.16.2 cpython/3.14.2 HTTPX/0.28.1

File hashes

Hashes for itk_napari_conversion-0.5.1.tar.gz
Algorithm Hash digest
SHA256 b497b9f788352bdd9b755d9227c254936ce97849281476e89e0b76a1c85d6024
MD5 affc774abaa5ee1d3cb086ebc0359b32
BLAKE2b-256 a2681a70b807bfd5bf3fd2c7302337a1c47a36242188c6e1f9a1f35e32b7dc2c

See more details on using hashes here.

File details

Details for the file itk_napari_conversion-0.5.1-py3-none-any.whl.

File metadata

File hashes

Hashes for itk_napari_conversion-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ae1be7a1030fa2ebc333bd9458ae0bba49ef33071045d9b633a3add3436d7b09
MD5 9763343ae64d252e14ad16ab26e880e6
BLAKE2b-256 f5a3829da9221438f0db0c20d8eead92d0b9df4bf217e16ec35544ca1382a7e8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page