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

David Gobbi david.gobbi at gmail.com
Fri May 18 16:15:25 EDT 2018


I'll briefly follow-up with a link that describes how vtkNIFTIImageReader
handles coordinates.  The (x,y,z) it mentions are RAS.
https://gitlab.kitware.com/vtk/vtk/blob/master/IO/Image/vtkNIFTIImageReader.cxx#L738

 - David

On Fri, May 18, 2018 at 1:55 PM, David Gobbi <david.gobbi at gmail.com> wrote:

> 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/3adb71f7/attachment.html>


More information about the vtkusers mailing list