GNU General Public License
convert saved flirt matrix to NIfTI world coords matrix

[worldmat spmvoxmat fslvoxmat] = flirtmat2worldmat(flirtmat, src, trg);

Versions Of This Snippet::

Ged Ridgway
Snippet ID Download Version Date Posted Author Delete
50.92009-07-27 00:29Ged RidgwayDelete

Download a raw-text version of this code by clicking on "Download Version"


Latest Snippet Version: :0.9

function [worldmat spmvoxmat fslvoxmat] = flirtmat2worldmat(flirtmat, src, trg)
%flirtmat2worldmat: convert saved flirt matrix to NIfTI world coords matrix
% flirt matrix is from text file specified in "flirt -omat mat.txt" command
% world matrix maps from NIfTI world coordinates in target to source. Note:
% mat.txt contains a mapping from source to target in FSL's *scaled* coords
% which are not NIfTI world coordinates, and note src-trg directionality!
% worldmat from this script reproduces "img2imgcoord -mm ...".
% The script can also return a matrix to map from target to source voxels 
% in MATLAB/SPM's one-based convention, or in FSL's zero-based convention
% Example:
%  [worldmat spmvoxmat fslvoxmat] = flirtmat2worldmat(flirtmat, src, trg);
% See also: worldmat2flirtmat, flirtmat_read, flirtmat_write

% Copyright 2009 Ged Ridgway <ged.ridgway>

if ischar(src)
    src = nifti(src);
if ischar(trg)
    trg = nifti(trg);

if ischar(flirtmat)
    flirtmat = flirtmat_read(flirtmat);

% src = inv(flirtmat) * trg
% srcvox = src.mat \ inv(flirtmat) * trg.mat * trgvox
% BUT, flirt doesn't use src.mat, only absolute values of the 
% scaling elements from it,
% AND, if images are not radiological, the x-axis is flipped, see:
trgscl = nifti2scl(trg);
srcscl = nifti2scl(src);
fslvoxmat = inv(srcscl) * inv(flirtmat) * trgscl;

% AND, Flirt's voxels are zero-based, while SPM's are one-based...
addone = eye(4); addone(:, 4) = 1;
spmvoxmat = addone * fslvoxmat * inv(addone);

worldmat = src.mat * spmvoxmat * inv(trg.mat);

function scl = nifti2scl(N)
% not sure if this is always correct with rotations in mat, but seems okay!
scl = diag([sqrt(sum(N.mat(1:3,1:3).^2)) 1]);
if det(N.mat) > 0
    % neurological, x-axis is flipped, such that [3 2 1 0] and [0 1 2 3]
    % have the same *scaled* coordinates:
    xflip = diag([-1 1 1 1]);
    xflip(1, 4) = N.dat.dim(1)-1; % reflect about centre
    scl = scl * xflip;


Submit a new version

You can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..