> My specific question is do the 3dAllineate parameters refer to going from input to base coordinates, base to input, or a combination of the two?
I'm pretty sure the parameters go from "base to input".
In registration what 3dAllineate calls the "input" is often called the "moving image" and the "base" image is called the "fixed" image. At each step the moving image is transformed and interopolated onto the same space as the fixed image. From that P.O.V. the needed function is the one that goes from the "fixed" image to the "moving" image.
Here are some octave functions I use to convert between aff12 and parameter versions. Extraction uses QR decomposition. I've not tested it in matlab but it should be fine.
function param = aff12_to_param(aff12)
A = aff12(1:3,1:3) ;
[Q,R] = qr(A') ;
s = diag(sign(diag(R))) ;
SD = R' * s ;
D = diag(diag(SD)) ;
S = SD * inv(D) ;
U = s * Q' ;
[a,b,c] = afni_get_angles(U) ;
param(1:3) = aff12(:,4) ;
param(4:6) = [a,b,c] ;
param(7:9) = diag(D) ;
param(10:12) = [S(2,1) S(3,1) S(3,2)] ;
end
function aff12 = param_to_aff12(param)
aff12 = zeros(3,4) ;
aff12(:,4) = param(1:3)' ;
S = eye(3) ;
S(2,1) = param(10) ;
S(3,1) = param(11) ;
S(3,2) = param(12) ;
D = diag(param(7:9)) ;
U = afni_rotation( param(4), param(5), param(6) ) ;
aff12(1:3,1:3) = S*D*U ;
end
function [a,b,c] = afni_get_angles(U)
b = asin(U(2,3)) ;
a = asin(-U(2,1)/cos(b)) ;
c = asin(-U(1,3)/cos(b)) ;
a = a/pi*180 ;
b = b/pi*180 ;
c = c/pi*180 ;
end
function U = afni_rotation(p4,p5,p6)
a = p4*pi/180.0 ;
b = p5*pi/180.0 ;
c = p6*pi/180.0 ;
rz = [ cos(a) sin(a) 0 ; -sin(a) cos(a) 0 ; 0 0 1 ] ;
rx = [ 1 0 0 ; 0 cos(b) sin(b) ; 0 -sin(b) cos(b) ] ;
ry = [ cos(c) 0 -sin(c) ; 0 1 0 ; sin(c) 0 cos(c) ] ;
U = ry * rx * rz ;
end