[Insight-developers] More orientation questions - dicom->nifti
Kent Williams
kent at psychiatry.uiowa.edu
Fri Sep 22 10:55:53 EDT 2006
DICOM was the starting point in ITK for definition of orientation. ITK's
internal idea of orientation and origin are the same as DICOMs.
If you look at the NIfTI header (in
Insight/Utilities/nifti/niftilib/nifti1.h) there's this description of
the relationship between DICOM and NIfTI origins.
"...DICOM's coordinate system is 180 degrees rotated about the z-axis
from the neuroscience/NIFTI coordinate system. To transform between
DICOM and NIFTI, you just have to negate the x- and y-coordinates.
The DICOM attribute (0020,0037) "Image Orientation (Patient)" gives the
orientation of the x- and y-axes of the image data in terms of 2
3-vectors. The first vector is a unit vector along the x-axis, and the
second is along the y-axis. If the (0020,0037) attribute is extracted
into the value (xa,xb,xc,ya,yb,yc), then the first two columns of the R
matrix would be
[ -xa -ya ]
[ -xb -yb ]
[ xc yc ]
The negations are because DICOM's x- and y-axes are reversed relative
to NIFTI's."
So when ITK reads a NIfTI file, it negates the X and Y components of the
origin, and when it writes it out, it negates it again. Similarly, the
ITK representation of the direction cosines is negated in the X & Y
terms. If you look at the NIfTI headers with nifti_tool, you'll see that
the origin reported is negated in two directions from what ITK reports
for the same image.
The ChangeImageInformation filter does this calculation to center the
origin, which I don't understand:
for (i = 0; i < ImageDimension; i++)
{
origin[i] = -output->GetSpacing()[i] *
static_cast<double>(outputSize[i] - 1) / 2.0;
}
output->SetOrigin(origin);
What I don't understand is why its components are negative. I also don't
know SPM5b, and I don't know what it's doing to report the numbers it
does. Every time I revisit the orientation issues in ITK I give myself
a headache trying to visualize how the orientation of the subject of a
scan in space boils down to the representation of that orientation
numerically. Every time I have to factor in another application's
notions on the subject, it turns into a migraine.
Richard Beare wrote:
> Hi everyone,
>
> I still haven't had any luck sorting out issues reagarding origin of
> nifti files for use in spm5.
>
> My current experiment uses ConvertBetweenFileFormats to create a nifti
> file from dicom. The resulting file seems to be correctly interpreted
> by spm5b, and has an origin that is close to the centre of the image
> which means that spm's segmentation process seems to work OK.
>
> However I'd like to get to the bottom of the issues regarding setting
> the origin. I've noticed in Kent Williams' article "A definition of
> spatial orientation for the Insight Toolkit" that origin definition is
> different between ITK and dicom. I'm not sure where this is dealt with
> or if I need to do anything special.
>
> I am using the following code to set origin, and it doesn't perform
> as expected. The various diagnostics are below. Can anyone suggest how
> I should address this issue?
>
> Many thanks
>
> -------------------------------------------------------------------
> typedef itk::Image<TPix, dim> ImType;
>
> typedef typename itk::ImageFileReader<ImType> ReaderType;
> typedef typename itk::ImageFileWriter<ImType> WriterType;
> typedef typename itk::ChangeInformationImageFilter<ImType>
> ChangeInfoType;
> typename ReaderType::Pointer reader = ReaderType::New();
> typename WriterType::Pointer writer = WriterType::New();
> typename OrienterType::Pointer orienter = OrienterType::New();
> reader->SetFileName(InputIm.c_str());
> reader->Update();
>
> changeInfo->SetInput(reader->GetOutput());
> changeInfo->CenterImageOn();
> writer->SetInput(changeInfo->GetOutput());
> writer->SetFileName(OutputIm.c_str());
> writer->Update();
> ------------------------------------------------------------------
>
> However it doesn't seem to perform as it should. In spm display the
> image details change :
> before setting origin:
> dimensions 256x256x248
> vox 0.898 x 0.898 x 0.6
> origin 156 134 120
> dir cos [0 0 1, -1 0 0, -0 -1 0]
>
> after setting origin
> vox 0.898 x 0.898 x 0.6
> origin 129 -81.5 -190
> dir cos [0 0 1, -1 0 0, -0 -1 0]
>
> and avwhd from fsl reports:
> before
> -----------------------------
> qform_code 1
> qto_xyz:1 0.000000 0.000000 0.599998 -71.458801
> qto_xyz:2 -0.898438 0.000000 0.000000 139.233994
> qto_xyz:3 0.000000 -0.898438 0.000000 119.819000
> qto_xyz:4 0.000000 0.000000 0.000000 1.000000
> qform_xorient Anterior-to-Posterior
> qform_yorient Superior-to-Inferior
> qform_zorient Left-to-Right
> sform_name Scanner Anat
> sform_code 1
> sto_xyz:1 0.000000 0.000000 0.599998 -71.458801
> sto_xyz:2 -0.898438 0.000000 0.000000 139.233994
> sto_xyz:3 0.000000 -0.898438 0.000000 119.819000
> sto_xyz:4 0.000000 0.000000 0.000000 1.000000
> sform_xorient Anterior-to-Posterior
> sform_yorient Superior-to-Inferior
> sform_zorient Left-to-Right
> --------------------------------------
> after
> qform_name Scanner Anat
> qform_code 1
> qto_xyz:1 0.000000 0.000000 0.599998 114.550842
> qto_xyz:2 -0.898438 0.000000 0.000000 114.550842
> qto_xyz:3 0.000000 -0.898438 0.000000 -74.099808
> qto_xyz:4 0.000000 0.000000 0.000000 1.000000
> qform_xorient Anterior-to-Posterior
> qform_yorient Superior-to-Inferior
> qform_zorient Left-to-Right
> sform_name Scanner Anat
> sform_code 1
> sto_xyz:1 -0.000000 0.000000 0.599998 114.550842
> sto_xyz:2 -0.898438 -0.000000 -0.000000 114.550842
> sto_xyz:3 0.000000 -0.898438 0.000000 -74.099808
> sto_xyz:4 0.000000 0.000000 0.000000 1.000000
> sform_xorient Anterior-to-Posterior
> sform_yorient Superior-to-Inferior
> sform_zorient Left-to-Right
> ----------------------------------------------------------
> _______________________________________________
> 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