LR rotation transform reduces axial resolution

Hi,

I performed an LR rotation transform using an angle and this matrix:
self.transform = np.array([
[1, 0, 0, 0],
[0, cos_angle, sin_angle, 0],
[0, -sin_angle, cos_angle, 0],
[0, 0, 0, 1]
])
From what I understand, it should only effect the sagittal plane, but it changes the spacing of the axial plane - from ~0.2 to ~2mm slices!
Why does it do that?

Thanks for any help in advance

anyone? I could really use the help.
When I do it manually there is no problem…

If you did this in Slicer we’d appreciate if you told us

  • What Slicer version you use
  • What modules you used, what steps did you take exactly
  • What did you expect, what happened instead, how did you found out
  • Preferably include screenshots

Thank you for answering!

Yes it is a part of an extension I’m working on in pycharm (2024.1.4)
I am using Slicer 5.6.2, using a linear transform.
I wanted to simply align the scan to a marked line by rotating around the LR axis. Manually, on a single sagittal slice, I marked the angle between the chosen line and the horizontal line using markups module, and put that angle in the LR rotation in the transforms module. Programmatically, the user marks two control points creating a line, and I calculate the projection of the line on the XY plane (I checked that the angle is identical to the manual process). Then I calculate the transform as I wrote in the first post (again, I checked it is the same as the manual transform is shown), and then I apply the transform using this line of code:
targetNode.SetAndObserveTransformNodeID(transformNode.GetID())
where targetNode is the scan volume, and the transformNode is:
self.transform = np.array([
[1, 0, 0, 0],
[0, cos_angle, sin_angle, 0],
[0, -sin_angle, cos_angle, 0],
[0, 0, 0, 1]
])
transformNode = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLLinearTransformNode”,
“AlignTransform”)
slicer.util.updateTransformMatrixFromArray(transformNode, self.transform)

The transform is done as I expected (only the sagittal changes), but for some reason, the axial slices which were 0.2 mm thin, become 2 mm thin. I found out when I was trying to move on with marking a target point in the axial plane and I scrolled a bit to find I already passed it because each slice was ten-fold larger…
What screenshots could help the debugging?

Are you talking about a CT that you loaded from DICOM?

What screenshots could help the debugging?

I think what could help is one actual matrix that you calculate (Transforms module), and the slice views before and after applying the transform.

Thanks!

Are you talking about a CT that you loaded from DICOM?

MRI from nii

The transform matrix:

slice view before:

slice view after:

also, it seems to only happen some of the time… and I couldn’t figure out what I’m doing different in each case…

Here is the transform that doesn’t recreate the problem (keeps the same axial resolution):

What makes you think that the slice spacing is changed?

Are you trying to compute the ACPC transform? You can do the using the ACPC transform module in SlicerNeuro extension.

I think the slice spacing is changed because when I scroll through the slices I see that they are ~2 mm apart in the I-S axis, whereas when I do this manually the spacing remains 0.2 mm

I am computing the AC-PC transform, but in the meantime I chose to do it with my own code since I need things that are not accessible through the the ACPC transform module (such as setting the MCP as origin)

The step size of the slice offset is computed as the diameter of the ellipsoid inscribed in a voxel in the direction of the slice normal. If you have an image with anisotropic spacing then changing the orientation of the volume will result in a different step size. This should not matter much, as you are browsing reformatted slices anyway. If you want to step through exact slices then use “rotate slice to volume plane”.

Is using a the MCP as origin a common need? If yes, and this is the only reason you don’t use the ACPC module then we could add one more point input to the ACPC module (it would take maybe half an hour to implement).

ok, thanks, I think I got it. I can also manually set the slice spacing, but how exactly does that work? I couldn’t find the documentation of that option

In my understanding, MCP is commonly used in surgery planning as the origin.
First of all, thanks for the offer for MCP implementation!
However, it is not the only reason I don’t use it… for example from UI point of view, I want the button of creating the markup (line or control point list) to be in the GUI (not on the toolbar); I want the point size to be much smaller for accurate pinpoint; I want to see the coordinates of each point on the GUI so I can move a point in very fine steps; etc…