Example #1
0
//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;
}
Example #2
0
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;
}
Example #3
0
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);
}
Example #4
0
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); 
}
Example #5
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;
}