[Insight-developers] Just checked in: Support for vector images in itk::NiftiImageIO.cxx

Gordon Kindlmann gk at bwh.harvard.edu
Wed Apr 5 18:17:30 EDT 2006


hello,

I'm happy to see increased NIfTI support in ITK.

I ran into the same issues when adding full NRRD support to ITK.   
NRRD, like NIfTI, can store vector quantities, and as in NIfTI, you  
can tag that axis with a "kind" that serves the same role as the  
"intent" in NIfTI.  I chose nrrdKindVector just like you chose  
NIFTI_INTENT_VECTOR (this stuff is in Insight/Code/IO/ 
itkNrrdImageIO.cxx).  As an aside, one drawback with NIfTI is that it  
can't represent the difference between a contravariant vector and a  
covariant vector; NRRD does allow you do set either nrrdKindVector or  
nrrdKindCovariantVector, according to ITK pixel type  
ImageIOBase::VECTOR or ImageIOBase::COVARIANTVECTOR, respectively.

The logic in Insight/Code/IO/itkNrrdImageIO.cxx represents the best I  
could come with as far as a clean mapping between ITK pixel types and  
Nrrd kinds, and probably like your ITK<-->NIfTI mapping, its not  
fully bijective: ImageIOBase::OFFSET, ImageIOBase::VECTOR, and  
ImageIOBase::FIXEDARRAY all map to nrrdKindVector; while  
nrrdKindVector, nrrdKindList, nrrdKindQuaternion all map to  
ImageIOBase::VECTOR.

You noted that its unfortunate that while ITK internally stores  
multiple per-voxel values along the fastest axis (as close as  
possible in memory, as it should be), NIfTI puts these values on the  
slowest axis (as far apart as possible on disk).  I believe this is  
for backwards compatibility reasons, related to how existing software  
uses the Analyze format (upon which NIfTI is entirely based).  I had  
the same issue with the axis permutation as you described, except  
that it was slightly worse in NRRD: the axis for the per-voxel values  
can be anywhere among the other spatial axes-- fastest, slowest, or  
in between (as indicated by whichever axis has a non-spatial  
"kind"=="intent").

So I snagged the nrrdAxesPermute function and put it into Insight/ 
Utilities/NrrdIO, which is likely doing the same thing as  
itk::PermuteAxesImageFilter.  nrrdAxesPermute is like the brute-force  
permutation you described, but with the optimization that the  
entities being permuted are not individual samples, but the scanlines  
(or image slices) along the set of fastest axes which are  
unpermuted.  So instead of many scalar value assignments, you can do  
memcpy()s of larger units.  But in the end, on average, the  
performance may not be radically different.

Gordon

On Apr 5, 2006, at 4:43 PM, Kent Williams wrote:

> This was development driven by local requirements @ U of Iowa, but  
> should be of general interest.
>
> I've added support for vector images in itk::NiftiImageIO. I added  
> a test to Insight/Testing/Code/IO as well.  I would appreciate any  
> feedback from those of you who regularly use vector images.
>
> If you write out a vector image, it sets the intent to  
> NIFTI_INTENT_VECTOR.   NIfTI, as it happens, supports a load of  
> different intent codes that all boil down to vector types, but  
> coming from ITK, you don't know if another intent code would be  
> more appropriate.  Unfortunately, given the way ImageIO works  
> internally, getting a handle for the itk::NiftiImageIO object from  
> your file writer, and setting the intent code won't work, since it  
> will be overwritten in WriteImageInformation.
>
> NIfTI also defines a couple of matrix types, which I haven't added  
> support for.  That wouldn't be a huge amount of work because the  
> data ordering in the file works the same as with vectors.
>
> NIfTI  stores things a little strangely (to my mind) with respect  
> to vectors -- for a volume of vectors, it's stored as a series of  
> volumes, one per vector component. In other words I have to premute  
> axes when I read and write nifti files, basically
>
> ITKVectorArray[t][z][y][x][vec] <=> NIfTIVectorArray[vec][t][z][y][x]
>
> I did the permutation in-line in itkNiftiImageIO.cxx.  I couldn't  
> find anything to re-use in ITK to do the permutation, short of  
> creating an itk::Image from the image data and using  
> itk::PermuteAxesImageFilter.  So I use brute force nested loops.   
> Anyone has a better idea let me know.
>
> _______________________________________________
> Insight-developers mailing list
> Insight-developers at itk.org
> http://www.itk.org/mailman/listinfo/insight-developers



More information about the Insight-developers mailing list