[ITK] Nifti Image to World Orientation

Matt McCormick matt.mccormick at kitware.com
Fri Apr 15 11:30:10 EDT 2016


Hi Nicolas,

Slicer modifies the coordinate system from ITK as described here:

  https://www.slicer.org/slicerWiki/index.php/Coordinate_systems

HTH,
Matt

On Fri, Apr 15, 2016 at 7:10 AM, Nicolas Rannou <nicolas at eunate.ch> wrote:
> Hi all,
>
> Apologizes if it is another duplicate but I couldn’t find any
> relevant/recent information about my issue.
>
> Is it possible to display image to world transform for an image in ITK?
>
> I am trying to figure out how ITK handles the orientation for this Nifti
> file:
> https://drive.google.com/open?id=0B2-PspfnvPNgY1R2SFFTd3YtaGM
>
> The image to world transform I get if I compute it “manually" from the
> header or run it in Nibabel does not match Slicer's (which is based on ITK)
> [1]. Also, if I convert this Nifiti file to NRRD in ITK, the orientation
> returned by the NRRD header matches Slicer but not Nibabel.
>
> SLICER:
> -0.859375 0 0 49.8438
> 0 -0.859375 0 -67.8906
> 0 0 0.859375 -53.7109
> 0 0 0 1
>
> NIBABEL:
> array([[ -0.859375 ,   0.       ,   0.       ,  49.84375  ],
>        [  0.       ,   0.859375 ,   0.       , -67.890625 ],
>        [  0.       ,   0.       ,   0.859375 , -53.7109375],
>        [  0.       ,   0.       ,   0.       ,   1.       ]])
>
>
> NRRD HEADER:
> NRRD0004
>    2 # Complete NRRD file format specification at:
>    3 # http://teem.sourceforge.net/nrrd/format.html
>    4 type: float
>    5 dimension: 3
>    6 space: left-posterior-superior
>    7 sizes: 117 159 126
>    8 space directions: (0.859375,0,0) (0,0.859375,0) (0,0,0.859375)
>    9 kinds: domain domain domain
>   10 endian: little
>   11 encoding: raw
>   12 space origin: (-49.84375,67.890625,-53.7109375)
>
>
> I understand the RAS/LPS differences but what doesn’t makes sense to me are
> the space directions in the NRRD header: -0.85 on the second vector would
> make sense to me:
> (0.859375,0,0) (0,-0.859375,0) (0,0,0.859375)
> I would also expect slicer [0][0] and [1][1] indices to have opposite signs.
> (like Nibabel)
> -0.859375 0 0 49.8438
> 0  0.859375 0 -67.8906
> 0 0 0.859375 -53.7109
> 0 0 0 1
>
>
> I couldn’t track down where this modification happens in ITK.
> Does ITK do any kind of correction to adjust the orientation somehow?
>
>
> As a test, I convert my Nifti to NRRD [2] and run the program step by step.
>
> In the Nifti parser, one of the last steps is to set the “Direction” to:
> (NiftiImageIO::SetImageIOOrientationFromNIfTI - Around line 1700)
> Direction 0: [1,-0,0]
> Direction 1: [-0,-1,0]
> Direction 2: [0,0,1]
>
> Then, when the NRRD parser tries fo fetch the direction it becomes:
> (NrrdImageIO::Write - Around line 945)
> Direction 0 [1,0,0]
> Direction 1 [0,1,0]
> Direction 2 [0,0,1]
>
> I couldn’t track down where this is happening or if that even makes sense.
>
> Best,
> Nicolas
>
> [1]
> -------------------------------------------------------
>  nifti_1_header :
>     sizeof_hdr     = 348
>     data_type[10]  = 0x 0 0 0 0 0 0 0 0 0 0
>     db_name[18]    = 0x 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>     extents        = 0
>     session_error  = 0
>     regular        = 0x72
>     dim_info       = 0x0
>     dim[8]         = 4 117 159 126 15 1 1 1
>     intent_p1      = 0.000000
>     intent_p2      = 0.000000
>     intent_p3      = 0.000000
>     intent_code    = NIFTI_INTENT_NONE
>     datatype       = 16
>     bitpix         = 32
>     slice_start    = 0
>     pixdim[8]      = -1.000000 0.859375 0.859375 0.859375
>                      1.000000 0.000000 0.000000 0.000000
>     vox_offset     = 352.000000
>     scl_slope      = 1.000000
>     scl_inter      = 0.000000
>     slice_end      = 0
>     slice_code     = 0
>     xyzt_units     = 0x12
>     cal_max        = 0.000000
>     cal_min        = 0.000000
>     slice_duration = 0.000000
>     toffset        = 0.000000
>     glmax          = 0
>     glmin          = 0
>     descrip        = ''
>     aux_file       = ''
>     qform_code     = 1
>     sform_code     = 0
>     quatern_b      = 0.000000
>     quatern_c      = 1.000000
>     quatern_d      = 0.000000
>     qoffset_x      = 49.843750
>     qoffset_y      = -67.890625
>     qoffset_z      = -53.710938
>     srow_x[4]      = 0.000000, 0.000000, 0.000000, 0.000000
>     srow_y[4]      = 0.000000, 0.000000, 0.000000, 0.000000
>     srow_z[4]      = 0.000000, 0.000000, 0.000000, 0.000000
>     intent_name    = ''
>     magic          = 'n+1'
> ———————————————————————————
>
>
> SLICER
>
>>>> import slicer
>>>> vol = slicer.util.getNode('template_T2.nii')
>>>> IJKToRASMat = vtk.vtkMatrix4x4()
>>>> vol.GetIJKToRASMatrix(IJKToRASMat);
>>>> print(IJKToRASMat)
> vtkMatrix4x4 (0x140294910)
> Debug: Off
> Modified Time: 980729
> Reference Count: 1
> Registered Events: (none)
> Elements:
> -0.859375 0 0 49.8438
> 0 -0.859375 0 -67.8906
> 0 0 0.859375 -53.7109
> 0 0 0 1
>
> NIBABEL
>
> In [2]: example_filename =
> '/Users/nico/work/gitroot/ami/data/nifti/FetalAtlas/template_T2.nii.gz'
>
> In [3]: import nibabel as nib
>
> In [4]: img = nib.load(example_filename)
>
> In [5]: img.shape
> Out[5]: (117, 159, 126, 15)
>
> In [6]: img.affine
> Out[6]:
> array([[ -0.859375 ,   0.       ,   0.       ,  49.84375  ],
>        [  0.       ,   0.859375 ,   0.       , -67.890625 ],
>        [  0.       ,   0.       ,   0.859375 , -53.7109375],
>        [  0.       ,   0.       ,   0.       ,   1.       ]])
>
> [2]
>   typedef itk::Image<float, 3> InputImageType;
>   typedef itk::Image<float, 3> OutputImageType;
>
>   typedef itk::ImageFileReader<InputImageType>  ReaderType;
>   typedef itk::ImageFileWriter<OutputImageType> WriterType;
>
>   ReaderType::Pointer reader = ReaderType::New();
>   WriterType::Pointer writer = WriterType::New();
>
>   reader->SetFileName(
> "/Users/nico/work/gitroot/data/nifti/fetalatlas_brain/t2/template_T2.nii.gz"
> );
>
>   writer->SetFileName( "test.nrrd" );
>   writer->SetInput( reader->GetOutput() );
>   writer->Update();
>
>
>
>
> [3]
>
>
> _______________________________________________
> Community mailing list
> Community at itk.org
> http://public.kitware.com/mailman/listinfo/community
>


More information about the Community mailing list