Hi,
You are right that FSL currently ignores the qform, but it
should preserve this information in all unitary operations
(those involving one image only). The trick is what
happens when two or more images are involved in some processing.
Also, it depends on what you intend the information to mean.
The situation with nifti is that the qform is intended to
store the orientation information that you would get from
the scanner (i.e. the stuff in DICOM). The qform doesn't
allow you to change the voxel size or scaling, but does
allow for a rigid body transformation (rotations + translations).
In contrast, the sform allows you to store a general affine
transformation (including scalings and skews/shears).
It is intended that the sform will store standard space
transformations (where scaling is normally essential).
Note that there is also an intention field (the sform_code or
qform_code), which describes what space the sform or qform
is mapping to. This can be some arbitrary scanner-aligned
space (like you get from DICOM) or can be a standard space
like mni or talairach. So it is possible to set the sform
to mean the scanner-space transform rather than a standard
space transform as it can represent 6 dof transformations,
although the converse isn't normally true.
At present, FSL uses the sform to calculate standard space
coordinates when it is set. However, we ignore the qform
at the moment (just because we couldn't implement all the
necessary options in time for the last release) and we
also ignore the difference between scanner and standard
space sform codes. We do check to see if the sform_code
is set to NIFTI_XFORM_UNKNOWN or not, but if it is set to
something that is not unknown, then we just use it for
standard space coordinates. This is what is used in all
programs that use standard space coordinates (e.g. feat,
fdt, fslview, etc...)
So I would say that putting qform information in the sform
isn't perfect, but neither is our implementation of nifti,
since it is still incomplete. A key question is what do
you want to use the information for? Currently no fsl
program needs to know the scanner-space coordinate system
(although future versions will probably use it to help out
with initialisation in registration, for instance).
Therefore, is it just something that you want to see kept
with your images when they are processed?
The other key thing to know is that in registration (and
some other cases), the sform is used to determine the
radio/neuro-logical orientation of the image storage.
This is because the sign of the determinant of the sform
matrix encodes the handedness of the coordinate system.
It should be negative determinant for radiological orientation
and positive determinant for neurological orientation.
We definitely recommend using radiological convention at the
moment because again we only have a partial implementation of
all the required features for a fully integrated radiological
and neurological system. The problems arise when trying to
calculate new images from images with different orientations.
At the moment, many of our programs ignore the orientation
and just do the operations directly on the data, preserving
the sform/qform from one of the input images only. In future
versions we hope to have a more consistent solution, but for
now everything is consistent if you stick to radiological,
because this is the convention used in the standard space
image.
As for storing sagittal images, that is no problem as long
as the coordinate system is appropriately radiological. Note
that this does not mean the the x-axis has to be left-right
or anything like that. It is just about the handedness of
the coordinate system, and a sagittal image can be either
radiological or neurological, depending on the sign of the
determinant of the sform or qform matrix.
If in doubt, you can store the sform appropriate to your
image and use "avworient -getorient" to see if this is
radiological or neurological. If it is neurological, then
you should select the left-right axis (that is, the through-slice
axis for sagittal, which is normally z) and do both a
avwswapdim on this axis (which reorders the data) and also
change the sform/qform matrix by swapping the signs on z
appropriately. Note that doing avwswapdim alone will only
change the data order, but leave the sform/qform unchanged
which would then be wrong. You must make sure you also change
the sform/qform matrices, although we don't have any tool
besides avworient (which is limited to changing the x-axis sign)
and avwedithd for changing the sform or qform (and changing
qform with avwedithd is difficult as you need to modify the
quaternion values directly).
Anyway, I hope this clears things up a bit more.
All the best,
Mark
On 6 Dec 2004, at 16:49, Arvind Caprihan wrote:
> Mark,
> Thanks for a very clear explanation. I have a couple
> of question on the correct method to convert DICOM data to
> NIFTI.
> a) I am currently converting the dicom orientation and
> patient position to the s-matrix and leaving qform code to
> zero. I was thinking that currently FSL does not use
> q-form information so I should store it in S-matrix. IS
> this correct or accceptable according to NIFTI concept.
>
> b) In order to minimize confusion with FSL what is the
> best way to convert a Sagital image to NIFTI format. I
> was thinking of converting it to radiological coordinates
> and storing the appropriate s_matrix - so that fslview
> would show (x,y,z) in nIFTI notation but the data would be
> stored in radiological coordinates. Maybe I should not
> worry about this at all and store the data in the order
> the scanner presents it and simply store the correct
> s-matrix or the q-quaterns.
>
> I am glad that you all have created the NIFTI standard.
>
> Thanks,
>
> Arvind
>
>
> On Sat, 4 Dec 2004 10:23:37 +0000
> Mark Jenkinson <[log in to unmask]> wrote:
>> Dear Arvind,
>>
>> This is a slightly tricky situation but things are
>> working
>> as expected.
>>
>> Firstly, I want to emphasize that the sform matrix is
>> about
>> how to map voxel coordinates to *standard space
>> coordinates*
>> and therefore does not have to use the same spacing as
>> the
>> voxel sizes at all. The reason for this is if you have
>> a
>> scan of an individual with, for example, a small head,
>> then
>> their image will need to be scaled up to fit the
>> standard
>> brain. Hence they will have a voxel dimension which
>> tells
>> you about how big their brain was, and a value in the
>> sform
>> which tells you about how big the voxel spacing needs to
>> be
>> *after* scaling up to the standard brain. It is
>> necessary
>> to have both sets of information and to keep them
>> separate.
>> So in your case it is fine that the sform in the flirt
>> output
>> does not have a 1.5mm spacing in z.
>>
>> Secondly, flirt uses the reference volume to assign the
>> number of voxels and the voxel size in the output image.
>> It also copies the sform from the reference volume if it
>> is set. However, if it is not set, but the sform of the
>> input image is set, then it will *transform* the sform
>> of
>> the input image so that it is appropriate for the output
>> image. This is a more unusual situation, as normally
>> the
>> input image doesn't have an sform set, but the reference
>> one does (e.g. if it is the standard image). But we try
>> to preserve the sform information when we can, and so
>> you
>> are in the situation where the input sform is used, but
>> requires transformation.
>>
>> This transformation can be explained as follows:
>> Let the sform matrix of the input volume be Si.
>> Let the sform matrix of the output volume be So.
>> Let the transformation between the input and output be
>> M.
>> It is necessary that the following equation hold for
>> consistency:
>> Si = So * M
>> This is because Si maps input coord to standard coord
>> while
>> M maps input coord to output coord and So maps output
>> coord
>> to standard coord.
>>
>> Therefore if you specify Si in the input image, and M
>> with an
>> applyxfm, you must solve for So, which gives:
>> So = Si * M^(-1)
>> As a consequence, in your case, you end up multiplying
>> the
>> z component of the sform matrix by 2, as this is the 3,3
>> entry
>> in M^(-1).
>>
>> Again, just to reiterate, this only occurs if the sform
>> matrix
>> of the reference volume is not set. If the reference
>> sform is
>> set, then the output image just gets a copy of the
>> reference
>> sform matrix, since this is what you want if you are
>> transforming
>> to a standard space image with a well defined standard
>> coord system.
>>
>> I hope this makes this clear.
>>
>> All the best,
>> Mark
>>
>>
>>
>> On 4 Dec 2004, at 01:32, Arvind caprihan wrote:
>>
>>> Hi,
>>> I am trying to understand the role of reference volume
>>> and the
>>> transformation matrix in 'flirt', and I am confused.
>>>
>>> The input file is head_t1 (256x256x150) from the test
>>> data suite. It
>>> has a
>>> sto_xyx matrix of
>>>
>>> sto_xyz:1 -0.976562 0.000000 0.000000 122.070251
>>> sto_xyz:2 0.000000 0.976562 0.000000 -116.210884
>>> sto_xyz:3 0.000000 0.000000 1.000000 -71.000000
>>> sto_xyz:4 0.000000 0.000000 0.000000 1.000000
>>>
>>> I have made a zero2.nii file with avwcreatehd with
>>> dimension
>>> 128x128x75
>>> and the corresponding pixel size 1.95x1.95x1.5.
>>>
>>> The transformation matrix rs2.mat is
>>> 1.0 0.0 0.0 0.0
>>> 0.0 1.0 0.0 0.0
>>> 0.0 0.0 0.5 0.0
>>> 0 0 0 1
>>>
>>> The R(3,3) = 0.5
>>>
>>> I then apply:
>>> flirt -in head_t1 -ref zero2 -out utest2 -applyxfm -init
>>> rs2.mat
>>>
>>> The output has the dimensions of the ref-volume zero2.
>>> This is
>>> correct.
>>> The pixdim(z) is 1.5 - which corresponds to ref-volume.
>>> The sto_xyz
>>> matrix
>>> is:
>>>
>>> sto_xyz:1 -1.950000 0.000000 0.000000 122.070251
>>> sto_xyz:2 0.000000 1.950000 0.000000 -116.210884
>>> sto_xyz:3 0.000000 0.000000 3.000000 -71.000000
>>> sto_xyz:4 0.000000 0.000000 0.000000 1.000000
>>>
>>> Now although the pixeldim(z) is 1.5, the sto_xyz
>>> indicates it is 3.0.
>>> If
>>> you look at the image in fslview, the z-values changes
>>> by 3 mm for a
>>> unit
>>> change in k-index.
>>> I am thinking that the pixdim(z) should be 3 mm - then
>>> everything
>>> would be
>>> consistent.
>>>
>>> Thanks,
>>>
>>> Arvind
>>> New Mexico Resonance
|