[vtkusers] Correct anatomical orientation of volumes from Niftii and DICOM

David Gobbi david.gobbi at gmail.com
Fri May 18 15:55:06 EDT 2018


Hi Panos,

Regarding the RASMatrix (or equivalently the QFormMatrix), there are
two ways that it can be used.  The first way is to apply it directly to the
actor, e.g. actor->SetUserMatrix(reader->GetQFormMatrix()) where the
'actor' is a vtkImageSlice object or a vtkImageActor object.  This will
correctly place the data within VTK's world coordinate system, without
the need for any image filters to flip or permute the IJK coordinates.

A different way to use the matrix is to use it to reslice the data, i.e. use
it to perform an image reformat.  The easiest way to do this is by passing
the vtkImageData through vtkImageReslice, with reslice->SetResliceAxes()
set to the inverse of the matrix.  The output will be a reoriented volume,
where IJK are mapped to new directions.

There are special considerations needed for oblique acquisitions, and I
won't go into those here.


Regarding what the reader does, let's start with vtkNIFTIImageReader.
The IJ coordinates are the same as stored in the file.  The K coordinate
is flipped of necessary to make the IJK axes follow the right-hand-rule.
This is done because it is required by the NIFTI qform, and also because
coordinate systems that don't follow the right-hand-rule are troublesome.
For more info, search for "qfac" in the NIFTI documentation or in the
docs for vtkNIFTIImageReader.

For vtkDICOMReader (from vtk-dicom), with SetRowOrderingToFileNative(),
it also keeps the IJ coordinates as stored in the file.  As for K, it also
flips
it as necessary so that the coordinates follow the right-hand-rule.
The vtkDICOMImageReader and vtkGDCMImageReader will keep IJ the
same if you use FileLowerLeftOn(), I won't go into how they manage K.


All of the readers store the spacing (in mm) in the vtkImageData.  So you
call VTK's data coordinates (x',y',z') if you want to, but these are not RAS
coords.  To get RAS coords, you need to multiply (x',y',z') by the
QFormMatrix, which will rotate them and shift them to give (x,y,z).
Moving along the 'J' data axis will only move you along the 'y' RAS axis
if the QFormMatrix encodes an identity rotation.

Unfortunately I don't have time to give a longer answer today, so I've left
some of your questions unanswered.  But feel free to follow up if there
are things you still aren't sure about after reading this.

 - David



On Fri, May 18, 2018 at 5:20 AM, ochampao <ochampao at hotmail.com> wrote:

> Hi David,
>
> Thanks for all the information you’ve been sending. It has been very
> helpful.
>
> Indeed, I have confused the RAS coordinate system with the neurological
> convention. I also assumed that because Slicer uses RAS it automatically
> meant that it also used the neurological viewing convention, which is not
> the case.
>
> My intention with the camera configuration posted in my previous comment
> was
> to use the neurological convention because I will be displaying images of
> the brain (this explains why I thought that all my images appeared flipped
> compared to Slicer). With the RAS coordinate system and the neurological
> viewing convention in mind, I think the camera configuration as posted
> above
> is correct now. To be more specific, this is what I am aiming for with that
> camera configuration:
>
> Axial (Looking towards patient’s inferior):
>   * Patient's Right    <= maps to => View Right
>   * Patient's Anterior <= maps to => View Up
>   * (Patient's Superior points "outside" the screen)
>
> Coronal (Looking towards Patient's Anterior):
>   * Patient's Right    <= maps to => View Right
>   * Patient's Superior <= maps to => View Up
>   * (Patient's Anterior points "inside" the screen)
>
> Sagittal (Looking towards Patient's Right):
>   * Patient's Posterior <= maps to => View Right
>   * Patient's Superior  <= maps to => View Up
>   * (Patient's Right points "inside" the screen)
>
> <http://vtk.1045678.n5.nabble.com/file/t341857/2018-05-17_14
> _52_58-kPlan_TPM.png>
>
> I found the following resources very helpful:
> Slicer Coordinate systems <https://www.slicer.org/wiki/Coordinate_systems>
>
> and all the links therein. Especially the table ""Radiological" vs
> "Neurological" Orientation in Viewers" from:  Orientation Terms
> <http://www.grahamwideman.com/gw/brain/orientation/orientterms.htm>
>
> Regarding the computed vtkMatrix4x4 (RASMatrix, QFormMatrix), if it is not
> the identity, then this means that we need to either transform the data
> (e.g. flip the respective axis) or apply the vtkMatrix4x4 to the respective
> actor?
>
> Another source of confusion was (and probably still is), what is done by
> the
> readers for us and what remains to be done by the programmer to properly
> display the volume. Also, if nothing is done to the reconstructed output
> volume of the reader, how is it positioned/oriented in VTK's world? Here is
> my current understanding:
>   * The reader loads the raw voxels which are stored in indexed/structured
> coordinates (scanner's i,j,k).
>   * The reader reconstructs the volume and transforms the uniteless (i,j,k)
> coordinates to (x',y',z') data coordinates with dimensions (e.g. mm):
>     - If, for example, the file format is using an RAS convention, then
> increasing i/j/k corresponds to increasing x'/y'/z' which in turn
> corresponds to moving towards R/A/S respectively.
>     - This volume is not oriented or positioned in the Patient's coordinate
> system yet i.e. its origin (i.e. voxel 0,0,0) is still at (0,0,0)mm and its
> RAS axes have not been mapped to VTK's world (X,Y,Z) coordinates.
>           -> This was probably my biggest point of confusion. I was
> assuming that
> even if the volume was not translated to the Patient's origin, it at least
> had its RAS axes mapped to VTK's positive X,Y,Z axes.
>     - This is actually the output of the reader i.e. the volume is still
> not
> positioned and oriented in Patient's corrdinate system but has the correct
> dimensions.
>     - The above coordinates refer to coordinates within the volume (user
> coordinates in VTK's terminology?).
>     - How is this volume positioned in VTK's world, without applying the
> transofmration matrix? <check this by plotting axes, and bounding box>
>   * the reader also computes the transformation matrix for orienting and
> positioning the reconstructed volume. The matrix should be applied by the
> programmer.
>   * this is where the job of the reader stops
>
>   * Let's assume that the file uses RAS and that the camera is setup using
> the neurological viewing convnetion. Then, if the volume is displayed using
> a vtkImageSlice prop without applying the UserMatrix, I was expecting VTK's
> world (X+,Y+,Z+) to map to the volumes (R,A,S) and the origin of VTK's
> world
> to coincide with the volume' s 0,0,0. When I apply this in prctice with a
> volume form a Nifti file, it clearly does not work.
>   * This is where the computed vtkMatrix4x4 (RASMatrix, QFormMatrix) that
> you mentioned comes into play.
>     - If the top left 3x3 of the matrix is identity, it means that the RAS
> axes are aligned with VTK's world positive XYZ coordinates, but the origin
> is at (0,0,0)mm, rather at the Patient's Origin.
>         - If the top left 3x3 is not identiy, then we need to apply the
> computed
> vtkMatrix4x4 to the actor, or transform the data accordingly (e.g. flipping
> the respective dimension or maybe passing it through a vtkTransformFilter?)
>
> I apologise for the long post. I hope that the above are not completely
> wrong and may be helpful.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://vtk.org/pipermail/vtkusers/attachments/20180518/31306a47/attachment.html>


More information about the vtkusers mailing list