Skip to main content

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:
    • spacing → scale
    • origin → translate
    • direction → rotate

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:
    • scale → spacing
    • translate → origin
    • rotate → direction
  • 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.

Release files for itk_napari_conversion 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for itk_napari_conversion 0.5.1
File Size Uploaded
itk_napari_conversion-0.5.1.tar.gz 54.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for itk_napari_conversion 0.5.1
File Interpreter ABI Platform
itk_napari_conversion-0.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 64.2 kB

Release files / itk_napari_conversion-0.5.1.tar.gz

Download URL itk_napari_conversion-0.5.1.tar.gz
Size 54.4 kB
Tags Source
SHA-256 checksum
How to use checksums
b497b9f788352bdd9b755d9227c254936ce97849281476e89e0b76a1c85d6024
BLAKE2b-256 checksum
How to use checksums
a2681a70b807bfd5bf3fd2c7302337a1c47a36242188c6e1f9a1f35e32b7dc2c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.2 cpython/3.14.2 HTTPX/0.28.1

Release files / itk_napari_conversion-0.5.1-py3-none-any.whl

Download URL itk_napari_conversion-0.5.1-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ae1be7a1030fa2ebc333bd9458ae0bba49ef33071045d9b633a3add3436d7b09
BLAKE2b-256 checksum
How to use checksums
f5a3829da9221438f0db0c20d8eead92d0b9df4bf217e16ec35544ca1382a7e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via Hatch/1.16.2 cpython/3.14.2 HTTPX/0.28.1

Release history Release notifications | RSS feed

This release

0.5.1 This release

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page