Hi,
This is all complicated by the number of different coordinate conventions in play, which if you are delving into the internals of what FSL stores then also includes some internal coordinate conventions that we don't normally need to explain to users. Very briefly the coordinates that are used include:
- voxel coordinates (same for FSL and NIFTI)
- NIFTI world (mm) coordinates
- FSL (internal) mm coordinates
The latter case (internal FSL coordinates) are scaled versions of the voxel coordinates, independent of the sform and qform matrices stored in the NIFTI file, with the exception that for positive determinant matrices (qform and/or sform) then the voxel coordinates on the x-axis are swapped prior to calculating the FSL (internal) mm coordinates. Hence the internal FSL coordinates always have a fixed handedness, which is opposite to the NIFTI mm coordinates (and also oriented differently when the qform/sform matrix is non-diagonal) due to historical reasons and backwards compatibility constraints.
The utilities need to know about the source and destination images when working in "mm" space because the relationship between the NIFTI mm space and FSL mm space requires knowledge of the relevant qform/sform matrices in the NIFTI files. This isn't how we'd build things from the ground up now, but is again a consequence of backwards compatibility of FSL from the pre-NIFTI era. Again, for users not needing to get under the hood, they can get away without worrying about these details as long as they stick to using our provided tools.
Also, all the transformations are stored in such a way that they are used, in the tools, to take coordinates from the source space to the destination space. However, non-linear warp fields are stored in the destination space and directly point towards the source space (making it easier to find the source space coordinate for all the grid points in the destination space).
You are right that FNIRT stores mm offset vectors in the --fout images, but these are in FSL internal mm conventions, not NIFTI mm conventions.
You can find some more information about coordinate conventions on the FSL wiki and in other emails on the list.
However, I will also send you, offline, some code that should also help you figure things out.
All the best,
Mark
> On 21 Jul 2017, at 11:31, Dr. Thomas Möbius <[log in to unmask]> wrote:
>
> Hi,
>
> so, i am trying to reverse engineer the functions img2imgcoord and
> img2stdcoord, as I am a bit at a loss of what they are doing.
>
> I have two images t (a template) and r (a subject) with affine
> transformations T and R that map from their respected voxel spaces into
> the world.
>
> template=MNI152_T1_2mm_brain.nii.gz
> subject=subject.nii.gz
>
> So, if I apply T or R to an index, say v=(0,0,0), I would expect to get
> T⋅v and R⋅v, when applying
>
> # apply references to index, ok :)
> echo 0 0 0 | img2stdcoord -img $fixed -std $fixed -vox -
> echo 0 0 0 | img2stdcoord -img $subject -std $subject -vox -
>
> and this is exactly what happens, so good.
>
> Now, I have given an affine transformation A: t -> r that maps from
> points in t to points in r. Now, given a point in t, say x=(0,0,0), I
> would like to have its coordinates in r, namely: A⋅x.
>
> # apply affine to coordinates, not ok :(
> flirt -in $subject -ref $fixed -omat A.mat
> echo 0 0 0 | img2imgcoord -dest $subject -src $fixed -xfm A.mat -mm
>
> This does not seem to be the case. In fact, I expected this function to
> not care what the -src and -dest images are when specifiying -mm, as I
> already provide the function with coordinates and not with indicies of
> some voxels. This does not seem to be the case, too. So, this function
> seems to be doing something different.
>
> Q1: So, given the affine transformations T, R, and A. What does img2imgcoord calculate? I experted (for coordinates x or indicies v)
> img2imgcoord -mm = A⋅x
> img2imgcoord -vox = R^{-1)⋅A⋅T⋅v
> But this does not seem to be the case.
>
>
> Now, I have given a diffeomorphism ψ: t -> r, and this diffeomorphism is
> defined via an affine transformation A and a displacement (or warp)
> field δ, i.e.,
>
> ψ (x) = A⋅x + δ(x).
>
> Given an index v=(0,0,0) in the template image t, I would like to have
> the coordinates of Tv in the image r, in other words, I would like to
> calculate
>
> ψ(Tv) = ATv + δ(Tv).
>
> I have given A, T, and δ is given to me via a warp image w.
>
> fnirt --in=$subject --ref=$fixed --aff=A.mat --fout w.nii.gz
>
> The affine transformation in the image w that maps from indicies to
> coordinates is the same as in t. (What I would have expected.) But what
> are theses entries in w? For a given index, say v=(0,0,0), I expected
> that the equality
>
> ψ(Tv) = ATv + w[v].
>
> would hold, i.e., that each voxel in w contains the displacement that we
> still need to apply, when applying the affine A to the coordinates of
> the voxel v:
>
> w[v] = ψ(Tv) - ATv.
>
> But this does not seem to be the case.
>
> Q2: What does the --fout image of FNIRT contain (if not the above)?
>
>
> I other words, given the affine transformation A and the fout-warp-field
> w, I expected to simply calculate at least for the voxels v in t
> their coordinates in r by simply doing the calculatation ATv+w[v] and,
> thus, replicate the output of
>
> echo 0 0 0 | img2stdcoord -img $subject -std $fixed -warp $cout -vox
>
> Thank you very much for your help.
> Thomas
>
> --
> Dr. Thomas W. D. Möbius
> Institut für Medizinische Informatik und Statistik
> Christian Albrechts-Universität zu Kiel
> Brunswiker Str. 10
> 24105 Kiel
> Telefon: +49 431 500 - 30719
> Fax: +49 431 500 - 30704
> E-Mail: [log in to unmask]
|