1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
#include "filter_reslice.h"
bool swapdim(Data<float,4>& data, Geometry& geo,const direction newread,const direction newphase,const direction newslice,const int newread_mult,const int newphase_mult,const int newslice_mult) {
Log<Filter> odinlog("","swapdim");
ODINLOG(odinlog,normalDebug) << "newread/newphase/newslice=" << newread << "/" << newphase << "/" << newslice << STD_endl;
// Checking input
if(newread==newphase || newread==newslice || newphase==newslice) {
ODINLOG(odinlog,errorLog) << "Direction used more than once: newread/newphase/newslice=" << newread << "/" << newphase << "/" << newslice << STD_endl;
return false;
}
const dvector vects[n_directions]={geo.get_readVector(),geo.get_phaseVector(),geo.get_sliceVector()};
double fov[n_directions];
//store i,j and k of the image coordinate system in scanner coordinate system
ODINLOG(odinlog,normalDebug) << "get_readVector:" << vects[readDirection] << " => " << (vects[newread]*newread_mult).printbody() << STD_endl;
ODINLOG(odinlog,normalDebug) << "get_phaseVector:" << vects[phaseDirection] << " => " << (vects[newphase]*newphase_mult).printbody() << STD_endl;
ODINLOG(odinlog,normalDebug) << "get_sliceVector:" << vects[sliceDirection] << " => " << (vects[newslice]*newslice_mult).printbody() << STD_endl;
//switch to 3d mode (we cannot deal with slice gaps)
geo.set_Mode(voxel_3d);
//get the size of the image
for(direction i=readDirection;i<n_directions;i=direction(i+1))
fov[i]=geo.get_FOV(i);
//transpose the data (data.transposeSelf(0,n_directions-sliceDirection,n_directions-phaseDirection,n_directions-readDirection) would do nothing
data.transposeSelf(
0,
n_directions-newslice,
n_directions-newphase,
n_directions-newread
);
geo.set_orientation_and_offset(
vects[newread]*newread_mult,
vects[newphase]*newphase_mult,
vects[newslice]*newslice_mult,
geo.get_center()
);
geo.set_FOV(readDirection,fov[newread]);
geo.set_FOV(phaseDirection,fov[newphase]);
geo.set_FOV(sliceDirection,fov[newslice]);
if(newread_mult<0)data.reverseSelf(3);
if(newphase_mult<0)data.reverseSelf(2);
if(newslice_mult<0)data.reverseSelf(1);
return true;
}
/////////////////////////////////////////////////////////////////////////////
void FilterSwapdim::init(){
newread.set_description("[rps][-]");
newphase.set_description("[rps][-]");
newslice.set_description("[rps][-]");
append_arg(newslice,"slice");
append_arg(newphase,"phase");
append_arg(newread,"read");
}
bool FilterSwapdim::process(Data<float,4>& data, Protocol& prot)const{
direction read,phase,slice;
int swap[3];
if(! (selChannel( newslice,slice,swap[0]) && selChannel( newphase,phase,swap[1]) && selChannel(newread,read,swap[2])) ) return false;
return swapdim(data,prot.geometry,read,phase,slice,swap[2],swap[1],swap[0]);
}
bool FilterSwapdim::selChannel(STD_string name, direction &dir, int& sign){
Log<Filter> odinlog("FilterSwapdim","selChannel");
sign=1;
dir=readDirection;
bool result=true;
if(name.length()>0) {
size_t minus=name.find('-'),plus=name.find('+');
if(plus!=STD_string::npos)name.erase(plus,1);
else if(minus!=STD_string::npos){
name.erase(minus,1);
sign=-1;
}
if(name[0]=='r')dir=readDirection;
else if(name[0] == 'p')dir=phaseDirection;
else if(name[0] == 's')dir=sliceDirection;
else result=false;
} else {
result=false;
}
if(!result) {
ODINLOG(odinlog,errorLog) << "Error parsing direction string >" << name << "<" << STD_endl;
}
return result;
}
/////////////////////////////////////////////////////////////////////////////
void FilterReSlice::init(){
orient.add_item("axial",axial);
orient.add_item("sagittal",sagittal);
orient.add_item("coronal",coronal);
orient.set_description("requested orientation");
append_arg(orient,"orientation");
}
bool FilterReSlice::process(Data<float,4>& data, Protocol& prot)const{
sliceOrientation sorient=prot.geometry.get_orientation();
if(sorient==int(orient)) return true;
Geometry &geo=prot.geometry;
switch(int(orient))
{
case axial:
if(sorient == sagittal)
return swapdim(data,geo,sliceDirection,readDirection,phaseDirection,1,1,1);
else if(sorient == coronal)
return swapdim(data,geo,readDirection,sliceDirection,phaseDirection,1,1,-1);
break;
case sagittal:
if(sorient==axial)
return swapdim(data,geo,phaseDirection,sliceDirection,readDirection,-1,-1,1);
else if(sorient==coronal)
return swapdim(data,geo,sliceDirection,phaseDirection,readDirection,-1,1,1);
break;
case coronal:
if(sorient==axial)
return swapdim(data,geo,readDirection,sliceDirection,phaseDirection,1,-1,1);
else if(sorient==sagittal)
return swapdim(data,geo,sliceDirection,phaseDirection,readDirection,-1,1,1);
break;
}
return true;
}
|