//extracts profiles in the area around the eyes vector<double> t1only_special_extract(const volume<float> & t1, const Pt & point, const Vec & n) { vector<double> resul; resul.clear(); bool output = true; const double INNER_DEPTH = 3; const double OUTER_DEPTH = 100; Profile pt1; for (double d = -INNER_DEPTH; d < OUTER_DEPTH; d+=.5) { Pt c = point + d * n; double tmp1 = t1.interpolate(c.X, c.Y, c.Z); pt1.add (d, tmp1); } pt1.init_roi(); //outer skin double outskin = pt1.last_point_over(pt1.end(), .2); double check = pt1.last_point_over(outskin - 1.5, .2); if (outskin - check > 2) output = false; pt1.set_rroi(outskin); double inskull = pt1.next_point_under(-INNER_DEPTH, .25); if (inskull > 5) inskull = 0; double outskull = pt1.next_point_over(inskull, .35); resul.push_back(inskull); resul.push_back(outskull); resul.push_back(outskin); return resul; }
vector<double> t1only_co_ext(const volume<float> & t1, const Pt & point, const Vec & n) { vector<double> resul; resul.clear(); bool output = true; bool alloutput = true; const double INNER_DEPTH = 3; const double OUTER_DEPTH = 60; Profile pt1; for (double d = -INNER_DEPTH; d < OUTER_DEPTH; d+=.5) { Pt c = point + d * n; double tmp1 = t1.interpolate(c.X, c.Y, c.Z); pt1.add (d, tmp1); } pt1.init_roi(); //outer skin double outskin = pt1.last_point_over(pt1.end(), .2); double check = pt1.last_point_over(outskin - 1.5, .2); if (outskin - check > 2) outskin = check; const double OUTER_SKIN = outskin; pt1.set_rroi(OUTER_SKIN); double inskull = pt1.next_point_under(pt1.begin(), .25); pt1.set_lroi(inskull); if (alloutput) { //outer skull //starting from the skin double outskull2 = 0; outskull2 = pt1.last_point_over(outskin, .75); outskull2 = pt1.last_point_under(outskull2, .20); //starting from the brain double minabs = pt1.next_point_under(pt1.begin(), .30); if (minabs == -500) output = false; minabs = Max(minabs, -INNER_DEPTH); double localminabs = minabs;//0 if (output) { bool stop = false; const double lowthreshold = pt1.threshold(.15); const double upthreshold = pt1.threshold(.60); int test = 0; for (vector<pro_pair>::const_iterator i = pt1.v.begin(); i != pt1.v.end(); i++) { if (!stop && (*i).abs>=minabs && i!=pt1.v.end() && i!=pt1.v.begin()) { if ((*i).val>upthreshold) stop = true; //avoid climbing skin if ((*i).val>lowthreshold) test++; if ((*i).val<lowthreshold) test--; if (test < 0) test=0; if (test == 12) {stop = true;} if ((*i).val<lowthreshold) { localminabs = (*i).abs; } } } } double outskull = pt1.next_point_over(localminabs, .15);//.20 if (outskull2 - outskull < -2 || outskull2 - outskull >= 2) {output = false;} if (outskin - outskull2 < 2) output = false; if (output) { resul.push_back(inskull); resul.push_back(outskull2); resul.push_back(outskin); } else resul.push_back(outskin); } return resul; }
void FnirtFileWriter::common_field_construction(const string& fname, const volume<float>& ref, const volume<float>& fieldx, const volume<float>& fieldy, const volume<float>& fieldz, const Matrix& aff) { volume4D<float> fields(ref.xsize(),ref.ysize(),ref.zsize(),3); fields.copyproperties(ref); Matrix M; bool add_affine = false; if (add_affine = ((aff-IdentityMatrix(4)).MaximumAbsoluteValue() > 1e-6)) { // Add affine part to fields M = (aff.i() - IdentityMatrix(4))*ref.sampling_mat(); } if (samesize(ref,fieldx,true)) { // If ref is same size as the original field fields[0] = fieldx; fields[1] = fieldy; fields[2] = fieldz; fields.copyproperties(ref); // Put qform/sform and stuff back. if (add_affine) { ColumnVector xv(4), xo(4); int zs = ref.zsize(), ys = ref.ysize(), xs = ref.xsize(); xv(4) = 1.0; for (int z=0; z<zs; z++) { xv(3) = double(z); for (int y=0; y<ys; y++) { xv(2) = double(y); for (int x=0; x<xs; x++) { xv(1) = double(x); xo = M*xv; fields(x,y,z,0) += xo(1); fields(x,y,z,1) += xo(2); fields(x,y,z,2) += xo(3); } } } } } else { fieldx.setextrapolationmethod(extraslice); fieldy.setextrapolationmethod(extraslice); fieldz.setextrapolationmethod(extraslice); Matrix R2F = fieldx.sampling_mat().i() * ref.sampling_mat(); ColumnVector xv(4), xo(4), xr(4); int zs = ref.zsize(), ys = ref.ysize(), xs = ref.xsize(); xv(4) = 1.0; for (int z=0; z<zs; z++) { xv(3) = double(z); for (int y=0; y<ys; y++) { xv(2) = double(y); for (int x=0; x<xs; x++) { xv(1) = double(x); xr = R2F*xv; fields(x,y,z,0) = fieldx.interpolate(xr(1),xr(2),xr(3)); fields(x,y,z,1) = fieldy.interpolate(xr(1),xr(2),xr(3)); fields(x,y,z,2) = fieldz.interpolate(xr(1),xr(2),xr(3)); if (add_affine) { xo = M*xv; fields(x,y,z,0) += xo(1); fields(x,y,z,1) += xo(2); fields(x,y,z,2) += xo(3); } } } } } fields.set_intent(FSL_FNIRT_DISPLACEMENT_FIELD,fields.intent_param(0),fields.intent_param(1),fields.intent_param(2)); fields.setDisplayMaximum(0.0); fields.setDisplayMinimum(0.0); // Save resulting field save_volume4D(fields,fname); }
double standard_step_of_computation(const volume<float> & image, Mesh & m, const int iteration_number, const double E,const double F, const float addsmooth, const float speed, const int nb_iter, const int id, const int od, const bool vol, const volume<short> & mask){ double xdim = image.xdim(); double ydim = image.ydim(); double zdim = image.zdim(); if (nb_iter % 50 == 0) { double l2 = 0; int counter = 0; for (vector<Mpoint*>::iterator i = m._points.begin(); i!=m._points.end(); i++ ) { counter++; l2 += (*i)->medium_distance_of_neighbours(); } l = l2/counter; } if (nb_iter % 100 == 0) { for (vector<Mpoint*>::iterator i = m._points.begin(); i!=m._points.end(); i++) { Vec n = (*i)->local_normal(); Pt point = (*i)->get_coord(); Pt ipoint(point.X/xdim, point.Y/ydim, point.Z/zdim); Vec in(n.X/xdim, n.Y/ydim, n.Z/zdim); double max = 0; Pt c_m1 = ipoint + (-1) * in; double current = image.interpolate((c_m1.X),(c_m1.Y),(c_m1.Z)); for (double i2 = 1; i2 < 150; i2+=2) { if (max > .1) break; Pt c_p = ipoint + i2 * in; double tmpp = image.interpolate((c_p.X),(c_p.Y),(c_p.Z)); double tmp = (tmpp - current) * 100; max = Max(max, tmp); current = tmpp; if (tmpp > .1) {max = 1; break;} } if (max < .1) { //There is a problem here for precision mode, since with the copy, no guarantee that data is non-zero size //even if mesh.cpp operator = is modified to copy data, after retesselate "new" points will have zero size data member if ( (*i)->data.size() ) (*i)->data.pop_back(); (*i)->data.push_back(1); } else { if ( (*i)->data.size() ) (*i)->data.pop_back(); (*i)->data.push_back(0); } } } for (vector<Mpoint*>::iterator i = m._points.begin(); i!=m._points.end(); i++) { Vec sn, st, u1, u2, u3, u; double f2, f3=0; Vec n = (*i)->local_normal(); Vec dv = (*i)->difference_vector(); double tmp = dv|n; sn = n * tmp; st = dv - sn; u1 = st*.5; double rinv = (2 * fabs(sn|n))/(l*l); f2 = (1+tanh(F*(rinv - E)))*0.5; u2 = f2 * sn * addsmooth; if ((*i)->data.back() == 0) { //main term of skull_extraction { Pt point = (*i)->get_coord(); Pt ipoint(point.X/xdim, point.Y/ydim, point.Z/zdim); Vec in(n.X/xdim, n.Y/ydim, n.Z/zdim); Pt c_m = ipoint + (-1.) * in; Pt c_p = ipoint + 1. * in; double tmp = image.interpolate((c_p.X ),( c_p.Y),(c_p.Z)); double gradient = tmp - image.interpolate((c_m.X),(c_m.Y), (c_m.Z)); double tmp2 = gradient*100; f3 = max(-1., min(tmp2, 1.)); if (tmp2 >= 0 && tmp2 < .1 && tmp < .1 ) f3 = speed; if (vol) { double tmpvol = mask.interpolate((ipoint.X ),(ipoint.Y),(ipoint.Z)); if (tmpvol > .0) { f3 = Max(Max(tmpvol*.5, .1), f3); f2 = 0; } } } } else { f3 = 0; Pt point = (*i)->get_coord(); Pt ipoint(point.X/xdim, point.Y/ydim, point.Z/zdim); double tmpvol = mask.interpolate((ipoint.X ),(ipoint.Y),(ipoint.Z)); if (tmpvol > .0) { f3 = Max(tmpvol*.5, .1); f2 = 0; } } u3 = .05 * f3 * n; u = u1 + u2 + u3; (*i)->_update_coord = (*i)->get_coord() + u; } m.update(); return (0); }
volume<float> find_skull (volume<float> & image, const Mesh & m, const double t2, double t, double t98) { const double skull_search = 30; const double skull_start = -3; volume<float> result = image; result=0; volume<short> volmesh; copyconvert(image,volmesh); int xsize = volmesh.xsize(); int ysize = volmesh.ysize(); int zsize = volmesh.zsize(); double xdim = volmesh.xdim(); double ydim = volmesh.ydim(); double zdim = volmesh.zdim(); double scale = Min(xdim, Min(ydim, zdim)); volmesh = 1; volmesh = draw_mesh(volmesh, m); image.setinterpolationmethod(trilinear); for (vector<Mpoint*>::const_iterator i = m._points.begin(); i != m._points.end(); i++) { double max_neighbour = 0; const Vec normal = (*i)->local_normal(); const Vec n = Vec(normal.X/xdim, normal.Y/ydim, normal.Z/zdim); for (list<Mpoint*>::const_iterator nei = (*i)->_neighbours.begin(); nei != (*i)->_neighbours.end(); nei++) max_neighbour = Max(((**i) - (**nei)).norm(), max_neighbour); max_neighbour = ceil((max_neighbour)/2); const Pt mpoint((*i)->get_coord().X/xdim,(*i)->get_coord().Y/ydim,(*i)->get_coord().Z/zdim); for (int ck = (int)floor(mpoint.Z - max_neighbour/zdim); ck <= (int)floor(mpoint.Z + max_neighbour/zdim); ck++) for (int cj = (int)floor(mpoint.Y - max_neighbour/ydim); cj <= (int)floor(mpoint.Y + max_neighbour/ydim); cj++) for (int ci = (int)floor(mpoint.X - max_neighbour/xdim); ci <= (int)floor(mpoint.X + max_neighbour/xdim); ci++) { bool compute = false; const Pt point(ci, cj, ck); const Pt realpoint(ci*xdim, cj*ydim, ck*zdim); if (volmesh(ci, cj, ck) == 0) { double mindist = 10000; for (list<Mpoint*>::const_iterator nei = (*i)->_neighbours.begin(); nei != (*i)->_neighbours.end(); nei++) mindist = Min(((realpoint) - (**nei)).norm(), mindist); if (mindist >= ((realpoint) - (**i)).norm()) compute = true; } if (compute) { double maxval = t; double minval = image.interpolate(point.X, point.Y, point.Z); double d_max = 0; for (double d=0; d<skull_search; d+=scale*.5) { Pt current = point + d * n; double val = image.interpolate(current.X, current.Y, current.Z); if (val>maxval) { maxval=val; d_max=d; } if (val<minval) minval=val; } if (maxval > t) { double d_min=skull_start; double maxJ =-1000000; double lastJ=-2000000; for(double d=skull_start; d<d_max; d+=scale*0.5) { Pt current = point + d * n; if (current.X >= 0 && current.Y >= 0 && current.Z >= 0 && current.X<xsize && current.Y<ysize && current.Z<zsize) { double tmpf = d/30 - image.interpolate(current.X, current.Y, current.Z) / (t98 - t2); if (tmpf > maxJ) { maxJ=tmpf; d_min = d; } lastJ=tmpf; } } double maxgrad = 0; double d_skull; Pt current2 = point + d_min * n; if (current2.X >= 0 && current2.Y >= 0 && current2.Z >= 0 && current2.X<xsize && current2.Y<ysize && current2.Z<zsize) { double val2 = image.interpolate(current2.X, current2.Y, current2.Z); for(double d=d_min + scale; d<d_max; d+=0.5*scale) { Pt current = point + d * n; if (current.X >= 0 && current.Y >= 0 && current.Z >= 0 && current.X<xsize && current.Y<ysize && current.Z<zsize) { double val = image.interpolate(current.X, current.Y, current.Z); double grad = val - val2; val2 = val; if (grad > 0) { if (grad > maxgrad) { maxgrad=grad; d_skull=d; } else d = d_max; } } } } if (maxgrad > 0) { Pt current3 = point + d_skull * n; if (current3.X >= 0 && current3.Y >= 0 && current3.Z >= 0 && current3.X<xsize && current3.Y<ysize && current3.Z<zsize) result ((int)current3.X, (int)current3.Y, (int)current3.Z) = 100/*max*/; } } } } } return result; }