From 72b19ec3458196f6fcbb25441436eb01345be182 Mon Sep 17 00:00:00 2001 From: Saad Jbabdi <saad@fmrib.ox.ac.uk> Date: Mon, 23 Nov 2009 16:31:51 +0000 Subject: [PATCH] added postmat --- vecreg.cc | 196 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 102 insertions(+), 94 deletions(-) diff --git a/vecreg.cc b/vecreg.cc index 5748965..0ea16f7 100755 --- a/vecreg.cc +++ b/vecreg.cc @@ -13,8 +13,8 @@ using namespace Utilities; -string title="vecreg (Version 1.0)\nVector Affine/non linear Tranformation with Orientation Preservation"; -string examples="vecreg -i <input4Dvector> -o <output4D> -t <transformation>"; +string title="vecreg (Version 1.0)\nVector Affine/NonLinear Tranformation with Orientation Preservation"; +string examples="vecreg -i <input4D> -o <output4D> -r <refvol> -t <transform>"; Option<bool> verbose(string("-v,--verbose"),false, string("switch on diagnostic messages"), @@ -22,26 +22,26 @@ Option<bool> verbose(string("-v,--verbose"),false, Option<bool> help(string("-h,--help"),false, string("display this message"), false,no_argument); -Option<string> ivector(string("-i,--input"),string(""), - string("filename of input vector"), - false,requires_argument); -Option<string> itensor(string("--tensor"),string(""), - string("full tensor"), - false,requires_argument); -Option<string> ovector(string("-o,--output"),string(""), - string("filename of output registered vector"), +Option<string> infilename(string("-i,--input"),string(""), + string("filename for input vector or tensor field"), + true,requires_argument); +Option<string> outfilename(string("-o,--output"),string(""), + string("filename for output registered vector or tensor field"), true,requires_argument); Option<string> ref(string("-r,--ref"),string(""), - string("filename of reference (target) volume"), + string("filename for reference (target) volume"), true,requires_argument); Option<string> matrix(string("-t,--affine"),string(""), - string("filename of affine transformation matrix"), + string("filename for affine transformation matrix"), false,requires_argument); Option<string> warp(string("-w,--warpfield"),string(""), - string("filename of 4D warp field for nonlinear registration"), + string("filename for 4D warp field for nonlinear registration"), + false,requires_argument); +Option<string> matrix2(string("--postmat"),string(""), + string("filename for post-transform affine matrix \n\t\t\tif set, this matrix will be used for the rotation of the vector/tensor field "), false,requires_argument); Option<string> interpmethod(string("--interp"),"", - string("interpolation method : nearestneighbour, trilinear (default) or sinc"), + string("interpolation method : nearestneighbour, trilinear (default), sinc or spline"), false,requires_argument); Option<string> maskfile(string("-m,--mask"),string(""), string("brain mask in input space"), @@ -144,12 +144,24 @@ void vecreg_aff(const volume4D<float>& tens, const Matrix& M, const volume<float>& mask){ - Matrix iM(4,4),R(3,3); + Matrix iM(4,4); iM=M.i(); + + ////////////////////////////////////////////////// + // Do we only need a FLIRT matrix for reorienting? + Matrix M2; + if(matrix2.value()!="") + M2 = read_ascii_matrix(matrix2.value()); + ////////////////////////////////////////////////// + + // extract rotation matrix from M - Matrix F(3,3),u(3,3),v(3,3); + Matrix F(3,3),R(3,3),u(3,3),v(3,3); DiagonalMatrix d(3); - F=M.SubMatrix(1,3,1,3); + if(matrix2.value()=="") + F=M.SubMatrix(1,3,1,3); + else + F=M2.SubMatrix(1,3,1,3); SVD(F*F.t(),d,u,v); R=(u*sqrt(d)*v.t()).i()*F; @@ -180,33 +192,33 @@ void vecreg_aff(const volume4D<float>& tens, << tens[5].interpolate(X_seed(1),X_seed(2),X_seed(3)); - if(ivector.set()){ - // compute first eigenvector - EigenValues(Tens,d,v); - V_seed = v.Column(3); + if(oV1.tsize()==3){ // case where input is a vector + // compute first eigenvector + EigenValues(Tens,d,v); + V_seed = v.Column(3); - // rotate vector - V_target=F*V_seed; - if(V_target.MaximumAbsoluteValue()>0) - V_target/=sqrt(V_target.SumSquare()); - - oV1(x,y,z,0)=V_target(1); - oV1(x,y,z,1)=V_target(2); - oV1(x,y,z,2)=V_target(3); - } + // rotate vector + V_target=F*V_seed; + if(V_target.MaximumAbsoluteValue()>0) + V_target/=sqrt(V_target.SumSquare()); + + oV1(x,y,z,0)=V_target(1); + oV1(x,y,z,1)=V_target(2); + oV1(x,y,z,2)=V_target(3); + } - // create tensor - if(ivector.unset()){ - Tens << R*Tens*R.t(); - - oV1(x,y,z,0)=Tens(1,1); - oV1(x,y,z,1)=Tens(2,1); - oV1(x,y,z,2)=Tens(3,1); - oV1(x,y,z,3)=Tens(2,2); - oV1(x,y,z,4)=Tens(3,2); - oV1(x,y,z,5)=Tens(3,3); - - } + // create tensor + if(oV1.tsize()==6){ + Tens << R*Tens*R.t(); + + oV1(x,y,z,0)=Tens(1,1); + oV1(x,y,z,1)=Tens(2,1); + oV1(x,y,z,2)=Tens(3,1); + oV1(x,y,z,3)=Tens(2,2); + oV1(x,y,z,4)=Tens(3,2); + oV1(x,y,z,5)=Tens(3,3); + + } } @@ -256,6 +268,20 @@ void vecreg_nonlin(const volume4D<float>& tens,volume4D<float>& oV1, FnirtFileReader ffr(warp.value()); warpvol=ffr.FieldAsNewimageVolume4D(true); + Matrix F(3,3),u(3,3),v(3,3); + DiagonalMatrix d(3); + + ////////////////////////////////////////////////// + // Do we only need a FLIRT matrix for reorienting? + Matrix M2; + if(matrix2.value()!=""){ + M2 = read_ascii_matrix(matrix2.value()); + // extract rotation matrix from M + F=M2.SubMatrix(1,3,1,3); + SVD(F*F.t(),d,u,v); + F=(u*sqrt(d)*v.t()).i()*F; + } + ////////////////////////////////////////////////// // compute transformation jacobian volume4D<float> jx(mask.xsize(),mask.ysize(),mask.zsize(),3); @@ -270,8 +296,7 @@ void vecreg_nonlin(const volume4D<float>& tens,volume4D<float>& oV1, ColumnVector V1_seed(3),V2_seed(3); ColumnVector V1_target(3),V2_target(3),V3_target(3); Matrix R(3,3),I(3,3);I<<1<<0<<0<<0<<1<<0<<0<<0<<1; - Matrix F(3,3),Jw(3,3),u(3,3),v(3,3); - DiagonalMatrix d(3); + Matrix Jw(3,3); SymmetricMatrix Tens(3); for(int z=0;z<oV1.zsize();z++) for(int y=0;y<oV1.ysize();y++) @@ -295,25 +320,23 @@ void vecreg_nonlin(const volume4D<float>& tens,volume4D<float>& oV1, << tens[4].interpolate(X_seed(1),X_seed(2),X_seed(3)) << tens[5].interpolate(X_seed(1),X_seed(2),X_seed(3)); - // Local Jacobian of the backward warpfield - Jw << jx(x,y,z,0) << jx(x,y,z,1) << jx(x,y,z,2) - << jy(x,y,z,0) << jy(x,y,z,1) << jy(x,y,z,2) - << jz(x,y,z,0) << jz(x,y,z,1) << jz(x,y,z,2); - - // compute local forward affine transformation - F = (I + Jw).i(); - - - if(ivector.set()){ - // reorient according to affine reorientation scheme - //SVD(F*F.t(),d,u,v); - //R=(u*sqrt(d)*v.t()).i()*F; + // F will not change if matrix2 is set + if(matrix2.value()==""){ + // Local Jacobian of the backward warpfield + Jw << jx(x,y,z,0) << jx(x,y,z,1) << jx(x,y,z,2) + << jy(x,y,z,0) << jy(x,y,z,1) << jy(x,y,z,2) + << jz(x,y,z,0) << jz(x,y,z,1) << jz(x,y,z,2); + // compute local forward affine transformation + F = (I + Jw).i(); + } + if(oV1.tsize()==3){// case where input is a vector // compute first eigenvector EigenValues(Tens,d,v); V_seed = v.Column(3); V_target=F*V_seed; + if(V_target.MaximumAbsoluteValue()>0) V_target/=sqrt(V_target.SumSquare()); @@ -322,13 +345,16 @@ void vecreg_nonlin(const volume4D<float>& tens,volume4D<float>& oV1, oV1(x,y,z,2)=V_target(3); } // create tensor - if(ivector.unset()){ - //SVD(F*F.t(),d,u,v); - //R=(u*sqrt(d)*v.t()).i()*F; + if(oV1.tsize()==6){ - EigenValues(Tens,d,v); - R=ppd(F,v.Column(3),v.Column(2)); - Tens << R*Tens*R.t(); + if(matrix2.value()==""){ + EigenValues(Tens,d,v); + R=ppd(F,v.Column(3),v.Column(2)); + Tens << R*Tens*R.t(); + } + else{ + Tens << F*Tens*F.t(); + } oV1(x,y,z,0)=Tens(1,1); oV1(x,y,z,1)=Tens(2,1); @@ -360,17 +386,11 @@ int do_vecreg(){ //read_volume4D(warpvol,warp.value()); //} if(verbose.value()) cerr << "Loading volumes" << endl; - if(ivector.set()) - read_volume4D(ivol,ivector.value()); - else - read_volume4D(ivol,itensor.value()); + read_volume4D(ivol,infilename.value()); read_volume(refvol,ref.value()); volume4D<float> ovol; - if(ivector.set()) - ovol.reinitialize(refvol.xsize(),refvol.ysize(),refvol.zsize(),3); - else - ovol.reinitialize(refvol.xsize(),refvol.ysize(),refvol.zsize(),6); + ovol.reinitialize(refvol.xsize(),refvol.ysize(),refvol.zsize(),ivol.tsize()); copybasicproperties(refvol,ovol); // set interpolation method @@ -378,6 +398,8 @@ int do_vecreg(){ ivol.setinterpolationmethod(nearestneighbour); else if(interpmethod.value()=="sinc") ivol.setinterpolationmethod(sinc); + else if(interpmethod.value()=="spline") + ivol.setinterpolationmethod(spline); else ivol.setinterpolationmethod(trilinear); @@ -389,12 +411,10 @@ int do_vecreg(){ for(int z=0;z<mask.zsize();z++) for(int y=0;y<mask.ysize();y++) for(int x=0;x<mask.xsize();x++){ - if(ivol(x,y,z,0)*ivol(x,y,z,0) - +ivol(x,y,z,1)*ivol(x,y,z,1) - +ivol(x,y,z,2)*ivol(x,y,z,2) != 0) - mask(x,y,z) = 1; - else + if(abs(ivol(x,y,z,0))==0 && abs(ivol(x,y,z,1))==0 && abs(ivol(x,y,z,2))==0) mask(x,y,z) = 0; + else + mask(x,y,z) = 1; } } @@ -402,7 +422,7 @@ int do_vecreg(){ // tensor for interpolation volume4D<float> tens(ivol.xsize(),ivol.ysize(),ivol.zsize(),6); copybasicproperties(ivol,tens); - if(ivector.set()) + if(ivol.tsize()==3) for(int z=0;z<ivol.zsize();z++) for(int y=0;y<ivol.ysize();y++) for(int x=0;x<ivol.xsize();x++){ @@ -428,7 +448,7 @@ int do_vecreg(){ } //cout<<"elapsed time:"<<time(NULL)-_time<<" sec"<<endl; - save_volume4D(ovol,ovector.value()); + save_volume4D(ovol,outfilename.value()); return 0; @@ -443,11 +463,11 @@ int main(int argc,char *argv[]){ try{ options.add(verbose); options.add(help); - options.add(ivector); - options.add(itensor); - options.add(ovector); + options.add(infilename); + options.add(outfilename); options.add(ref); options.add(matrix); + options.add(matrix2); options.add(warp); options.add(interpmethod); options.add(maskfile); @@ -473,19 +493,7 @@ int main(int argc,char *argv[]){ << endl << endl; exit(EXIT_FAILURE); } - if(ivector.unset()){ - if(itensor.unset()){ - cerr << endl; - cerr << "Please entre either an input vector or a tensor" << endl << endl; - exit(EXIT_FAILURE); - } - } - if(ivector.set()){ - if(itensor.set()){ - cerr << endl; - cerr << "Warning: warping the input vector, and ignoring the tensor" << endl << endl; - } - } + } catch(X_OptionError& e) { options.usage(); -- GitLab