Skip to content

Conversation

@thewtex
Copy link
Member

@thewtex thewtex commented Oct 16, 2025

  • ENH: Bump version to 0.4.0
  • ENH: Initial points_layer_from_point_set, point_set_from_points_layer
  • DOC: Describe point set conversion, expand on image conversion
  • DOC: Add support for applying points layer rotate

@thewtex
Copy link
Member Author

thewtex commented Oct 16, 2025

Closes #2

@thewtex thewtex force-pushed the point-set-conversion branch from 4ed930d to 8654b2b Compare October 17, 2025 18:43
# 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)

Choose a reason for hiding this comment

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

image_layer.rotate is the transpose of ITK's image direction matrix, right? (Rather than "in reverse order"). At least, that's what I understand from your 7e48ef0

Copy link
Member Author

Choose a reason for hiding this comment

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

There is the issue of the order elements of the columns / rows (which I am trying to indicate with "in reverse order", and which I assume is correct), and there is the issue of how the matrix is applied, including whether a transpose is needed. The latter is a separate issue, and I think it is harder to make an assumption, so I would not like to make assertions here ;-).

README.md Outdated
Comment on lines 87 to 100
layer = viewer.add_image(
data,
scale=[2.0, 1.5, 1.5], # anisotropic spacing
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]
# - direction: from napari `rotate`. In this case unspecified, so just the identity matrix.

Choose a reason for hiding this comment

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

Can you possibly extend the example here with a non-identity rotation matrix:

viewer.add_image(
    data,
    scale=[2.0, 1.5, 1.5],  # anisotropic spacing
    translate=[10.0, 20.0, 30.0],
    rotate=[ ... ],

And then possibly mention in the comment (line 100 here) what the ITK direction then would be?

Copy link
Member Author

Choose a reason for hiding this comment

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

@N-Dekker 👍 added in
cbdfcd2

Documentation and test covering napari Image Layer rotate and the
itk.Image direction as a NumPy array an itk.Matrix.
Comment on lines +158 to +159
# napari rotate is transposed compared to ITK direction
assert np.allclose(rotate, np.transpose(np.array(image["direction"])))

Choose a reason for hiding this comment

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

Cool, thanks Matt!!! So the napari rotate is just the transpose of the ITK "direction", right?

Choose a reason for hiding this comment

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

Locally I got:

Non-orthogonal slicing is being requested, but is not fully supported. Data is displayed without applying an out-of-slice rotation or shear component.
Traceback (most recent call last):
  File "D:\X\Src\M\MyPythonApp\MyPythonApp.py", line 41, in <module>
    test_image_from_image_layer_rotate_3d()
  File "D:\X\Src\M\MyPythonApp\MyPythonApp.py", line 27, in test_image_from_image_layer_rotate_3d
    assert np.allclose(rotate, np.transpose(np.array(image["direction"])))
AssertionError

Could be my fault, still having another look 🤷

Choose a reason for hiding this comment

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

By the way, the assert np.allclose(rotate, np.transpose(np.array(image["direction"]))) looks somewhat redundant, because the next lines of code check image["direction"] as well. Especially:

expected_direction = np.transpose(rotate)
assert np.allclose(direction_array, expected_direction)

Choose a reason for hiding this comment

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

Sorry for the noise, I was running your new unit test on the old itk_napari_conversion version!!! That causes test assert failures, of course 😄

Copy link

@N-Dekker N-Dekker left a comment

Choose a reason for hiding this comment

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

Thanks Matt! Looks like this will be very useful for our elastix-napari plugin as well 🥇

@thewtex thewtex merged commit 9dec812 into InsightSoftwareConsortium:main Oct 23, 2025
13 checks passed
@thewtex thewtex deleted the point-set-conversion branch October 23, 2025 19:47
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.

2 participants