[Insight-developers] more notes on images with affine transformations in the header

brian avants stnava at gmail.com
Wed Jul 6 12:08:11 EDT 2011


hi kent

everything i know about nifti is from:
http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/qsform_brief_usage

it says

"The qform and sform stored in a nifti file are intended to fulfil the
following functions:

specify the handedness of the coordinate system (important for getting
left and right correct)

specify the original scanner coordinates (qform only; figure)

specify standard space coordinates (sform only)

specify a relationship with another image's coordinates (sform only)

The qform and sform should never specify coordinates with different
handedness (i.e. have determinants of different signs). Otherwise it
is not possible to tell left from right.
"

my first guess is that this method:

NiftiImageIO::SetNIfTIOrientationFromImageIO(unsigned short int
origdims, unsigned short int dims)

needs to have two different paths of execution (one for qform, one for
sform) which should be determined at the start of the function.
unfortunately, we don't have a way (that i know of) to decide what the
purpose/origin of the input image's direction matrix is ...  but we
can decide if it's a rigid or affine mapping.  and if it's affine,
then we definitely should follow the sform path.

path 1 sets the qform which should occur when you have only a rigid
mapping from voxel to physical space.  this seems to be what you are
doing now.

path 2 sets the sform.  in this case, we set the qform intent code to
unknown and sform intent code to ALIGNED_ANAT .... also, in this case,
as a first pass i would just use the existing itk transform as it is.
my experiments with meta i/o seemed to work ok ... however, it's
possible that one might actually need to set the transform as the
inverse of the mapping between a pair of images.   this can be worked
out fairly easily once we have the operations working.

then the question is, will itk read in a nifti image with a sform (no
qform) affine transform correctly?   again, it seems to work with meta
images.

regarding:  "The problem is that the NIfTI orientation system isn't
the same as ITK. When I wrote that code, I was working from a set of
test images that had 'square' direction cosines, trying to accommodate
going to and from NIfTI world."

the linear algebra for the affine and rigid case should be the same,
shouldn't it?  i.e. now that you know the mapping (for rigid
transforms), affine transforms should just generalize the same style.

brian




On Wed, Jul 6, 2011 at 10:50 AM, Williams, Norman K
<norman-k-williams at uiowa.edu> wrote:
> The SpatialOrientationAdapter is actually a pretty regrettable thing we
> did back in the day.
>
>
> The problem it solved: Given images in different orientations, it permutes
> and swaps the voxels to get them into a common anatomical orientation
> (e.g. RAI) so that INDEX-SPACE operations worked.
>
> The problem it created: It reads the reported rotation matrix and
> over-writes it with the 'nearest' orthogonal (I.e. each dir cosine in 3D
> has a single 1.0 and two 0.0) direction cosines.
>
> As far as I know this information-destroying 'squaring up' of the
> direction cosines is only in the SpatialOrientationAdapter and
> OrientImageFilter.
>
> The relevant code in the NIFTI reader is in SetImageIOOrientationFromNIfTI
> and SetNIfTIOrientationFromImageIO.
>
> The problem is that the NIfTI orientation system isn't the same as ITK.
> When I wrote that code, I was working from a set of test images that had
> 'square' direction cosines, trying to accommodate going to and from NIfTI
> world.
>
> The truth of the matter is that I barely made it through Linear Algebra
> with a gentleman's 'C' so I can't begin to understand how to fix the NIfTI
> code to go between ITK-world and NIfTI-world, preserving its
> non-orthogonality.  If you can show me the formula to do so, I'd be glad
> to implement it.
>
> To put it more plainly, any dumb-headedness in the NIfTI ImageIO stems
> directly from my dumb-headedness.
>
> On 7/5/11 11:54 AM, "brian avants" <stnava at gmail.com> wrote:
>
>>hi everyone (hans and kent, especially),
>>
>>currently, the image classes do not appear to check that the direction
>>matrix is orthogonal.
>>
>>e.g. line 143   Modules/Core/Common/src/itkSpatialOrientationAdapter.cxx
>>//TODO:  Should check that directions are orthoganal.
>>  return direction;
>>
>>what does appear to check orthogonality is writer classes.
>>
>>i have only checked nifti for the moment.  test code is here:
>>
>>  typename ImageType::Pointer image = reader->GetOutput();
>>  typename ImageType::DirectionType testdir=image->GetDirection();
>>  testdir[0][0]=1;
>>  testdir[0][1]=0.2;
>>  testdir[1][0]=0.5;
>>  testdir[1][1]=1;
>>  image->SetDirection(testdir);
>>  typedef itk::ImageFileWriter<ImageType> writertype;
>>  typename writertype::Pointer writer = writertype::New();
>>  writer->SetFileName("test.nii");
>>  writer->SetInput( image );
>>  writer->Update();
>>
>>this will write out an image with an orthogonal direction matrix
>>presumably because nifti i/o forces this conversion (silently).
>>
>>if you switch the extension to "mhd", then the direction matrix in the
>>output image is the same
>>as that set in code.   you can run a registration etc using this
>>non-orthogonal transform to physical space.  that is, if i use an
>>image with the above direction matrix as the "fixed" image and an
>>image resampled by that affine matrix (testdir), i get an identity
>>transform as the solution for the mapping between them.  this is the
>>use case we want to support .... and we do, to some extent, though
>>the support is undocumented and inconsistent.
>>
>>in short, given current git itk, you can add a non-orthogonal transform
>>to the
>>header of an image in code.  you can then run image operations on this
>>image without, it appears, any checking that the header orientation is
>>orthogonal.  obviously, it requires significant code review to check
>>if all filters that use direction
>>matrices will be correct if the header transformation is affine.
>>
>>so, a minimal solution to this problem would be:
>>
>>-- allow nii to write non-orthogonal direction matrices via the sform
>>   and setting the sform code to NIFTI_XFORM_ALIGNED_ANAT and qform code
>>   to UNKOWN
>>
>>-- provide explicit warnings/exceptions in other i/o classes that
>>cannot write affine header txs.
>>
>>this page has other details:
>>
>>http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_
>>pages/qsform_brief_usage
>>
>>any thoughts?
>>
>>b.a.
>>_______________________________________________
>>Powered by www.kitware.com
>>
>>Visit other Kitware open-source projects at
>>http://www.kitware.com/opensource/opensource.html
>>
>>Kitware offers ITK Training Courses, for more information visit:
>>http://kitware.com/products/protraining.html
>>
>>Please keep messages on-topic and check the ITK FAQ at:
>>http://www.itk.org/Wiki/ITK_FAQ
>>
>>Follow this link to subscribe/unsubscribe:
>>http://www.itk.org/mailman/listinfo/insight-developers
>
>
>
> ________________________________
> Notice: This UI Health Care e-mail (including attachments) is covered by the Electronic Communications Privacy Act, 18 U.S.C. 2510-2521, is confidential and may be legally privileged.  If you are not the intended recipient, you are hereby notified that any retention, dissemination, distribution, or copying of this communication is strictly prohibited.  Please reply to the sender that you have received the message in error, then delete it.  Thank you.
> ________________________________
>


More information about the Insight-developers mailing list