Hello, I wanted to set a new origin point (to the last slice loaded), without modifying anything else (the volume must remain at the same spot in the world coordinates). In simple terms I just want that:
node.GetOrigin() == (0, 0, 0)
for the configuration in the picture bellow, instead of currently:
node.GetOrigin() == (0, 0, -100)
Is it possible to do that?
Do you mean you want to also flip the directions? Did you try just calling
SetOrigin? You can also use
volumeNode.SetKToRASDirection and related methods.
Yes, I played around with some functions, but no success. I just really want to change the Origin point, but not translating the volume in the world as a consequence.
The way we use the term, changing the origin would move the actual data in physical space unless you shuffle the data and change the directions. Can you give more info on what you need to achieve?
I managed to get the result I wanted by doind these two steps:
Revert the order of the files loaded into Slicer (I am using ‘DICOMScalarVolumePlugin’). By doing this, my volume is loaded upside down, and the origin is anchored where I want in the volume, i.e. at the top:
loadables.files = loadables.files[::-1]
Apply a transform to rotate 180 degrees around the Sagittal or Coronal axis.
This way I have the volume origin at (0, 0, 0), at the top of volume.
I wanted to know if there is a more elegant way to achieve this result.
It’s not clear to me why you need the origin to be at a specific spot. For example in dicom only the relative values of origin matter, and then only if they are in the same frame of reference.
@giovform has multiple volumes with an outside-of-Slicer-coordinate of the volumes defined by the top (patient head). When he loads the volume into slicer and sets the volume origin, this coordinate is defined at the bottom (patient feet), hence he needs to shift the outside-coordinate by the height of the patient. When the user wants to inspect the volume and retrieve the outside-of-Slicer-coordinate, the slicer volume origin coordinate is shifted.
We would like to set the imagedata (ijk) origin to start at the last slice (patient head), and increases as slices moves to the feet (I world direction).
You cannot expect to have a particular voxel (IJK) to physical (LPS) coordinate system mapping in an image file that you load. If your application only works with one particular slice order then you need to normalize the images after you load them in your own software.
If you really want to do this normalization in Slicer, then you can still do it (as in general, Slicer does not reorder slices when it loads or saves an image volume), it is really not the right place to do it.
Great Andras, I agree with you. But if you allow me, I am still curious about this issue.
Why does ImageData.setOrigin(0,0,-100) does not work for this case?
Is it because slicer assumes ijk always starts at zero and goes up to the dimensions of the imagedata?
Vtk seems to deal with this just fine, as the volume is rendered at the right position when I set the ImageData origin.
Thank you for the insights and ideas.
SetOrigin() method of vtkImageData must not be used. Origin, spacing, and axis directions of volumes are stored in the volume node, not in the vtkImageData (origin in vtkImageData must be kept (0,0,0)). The reason is that until recently, vtkImageData could not store image orientation and therefore the complete image geometry had to be stored outside the image data object. You can modify the origin by calling
SetOrigin() method of the volume node.
Once we upgrade to VTK9, we can switch to using vtkImageData for storing image geometry, but probably this will take about a year.