Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
  char        **av, *in_vol, *out_vol;
  int         ac, nargs;

  MRI         *mri_in, *mri_out, *mri_tmp ;
  LTA         *lta = 0;
  MATRIX *i_to_r_src = 0; /* src geometry of the input LTA */
  MATRIX *V_to_V = 0; /* Final voxel-to-voxel transform */
  MATRIX *r_to_i_dst = 0; /* dst geometry of the input LTA */
  MATRIX *m_tmp = 0;
  MATRIX *i_to_r_reg = 0; /* i_to_r of the volume after registration */
  MATRIX *r_to_i_out = 0; /* r_to_i of the final output volume */
  VOL_GEOM vgm_in;
  int x, y, z;
  double maxV, minV, value;
  //  MATRIX *i_to_r, *r_to_i;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option (argc, argv, "$Id: mri_transform_to_COR.c,v 1.8 2011/03/02 00:04:55 nicks Exp $", "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
    usage_exit (0);
  argc -= nargs;

  Progname = argv[0] ;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++)
  {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc < 3)
    usage_exit(0) ;

  in_vol = argv[1] ;
  out_vol = argv[2] ;

  printf("reading volume from %s...\n", in_vol) ;
  mri_in = MRIread(in_vol) ;
  if (!mri_in)
    ErrorExit(ERROR_NOFILE, "%s: could not read MRI volume %s", Progname,
              in_vol) ;

  /* Convert mri_in to float type */
  /* double would be more accurate */
  if (mri_in->type != MRI_FLOAT)
  {
    printf("Input volume type is %d\n", mri_in->type);
    printf("Change input volume to float type for convenience and accuracy");
    mri_tmp = MRIchangeType(mri_in, MRI_FLOAT, 0, 1.0, 1);
    MRIfree(&mri_in);
    mri_in = mri_tmp; //swap
  }

  /* Get input volume geometry, which is needed to compute i_to_r
   * and r_to_i of input volume. Note that i_to_r and r_to_i assumed
   * a certain prespecified c_r, c_a, c_s
   */
  getVolGeom(mri_in, &vgm_in);

  maxV = -10000.0;
  minV = 10000.0;
  for (z=0; z < mri_in->depth; z++)
    for (y=0; y< mri_in->height; y++)
      for (x=0; x < mri_in->width; x++)
      {
        if (MRIFvox(mri_in, x, y, z) > maxV )
          maxV = MRIFvox(mri_in, x, y,z) ;
        if (MRIFvox(mri_in, x, y, z) < minV )
          minV = MRIFvox(mri_in, x, y,z) ;
      }

  printf("Input volume has max = %g, min =%g\n", maxV, minV);

  printf("Scale input volume by %g \n", scale);

  maxV = -10000.0;
  minV = 10000.0;
  for (z=0; z < mri_in->depth; z++)
    for (y=0; y< mri_in->height; y++)
      for (x=0; x < mri_in->width; x++)
      {
        MRIFvox(mri_in, x, y, z) *= scale;
        if (MRIFvox(mri_in, x, y, z) > maxV )
          maxV = MRIFvox(mri_in, x, y,z) ;
        if (MRIFvox(mri_in, x, y, z) < minV )
          minV = MRIFvox(mri_in, x, y,z) ;
      }

  printf("Input volume after scaling has max = %g, min =%g\n", maxV, minV);

  /* Try to compute the Voxel_to_Voxel transform from the input volume
   * and the registration target/reference volume!
   * If no registration is involved, vox_to_vox is simply identity
   */
  /* Things become more complicated when allowing inverse transform */
  if (transform_flag)
  {
    int transform_type;

    printf("INFO: Applying transformation from file %s...\n",
           transform_fname);
    transform_type =  TransformFileNameType(transform_fname);

    /* Read in LTA transform file name */
    if (transform_type == MNI_TRANSFORM_TYPE ||
        transform_type == TRANSFORM_ARRAY_TYPE ||
        transform_type == REGISTER_DAT ||
        transform_type == FSLREG_TYPE
       )
    {

      printf("Reading transform ...\n");
      lta = LTAreadEx(transform_fname) ;

      if (!lta)
        ErrorExit(ERROR_NOFILE, "%s: could not read transform file %s",
                  Progname, transform_fname) ;

      if (transform_type == FSLREG_TYPE)
      {
        if (lta_src == 0 || lta_dst == 0)
        {
          fprintf(stderr, "ERROR: fslmat does not have information on the src and dst volumes\n");
          fprintf(stderr, "ERROR: you must give options '-src' and '-dst' to specify the src and dst volume infos for the registration\n");
        }


        LTAmodifySrcDstGeom(lta, lta_src, lta_dst); // add src and dst information
        //The following is necessary to interpret FSLMAT correctly!!!
        LTAchangeType(lta, LINEAR_VOX_TO_VOX);
      }
      if (lta->xforms[0].src.valid == 0)
      {
        if (lta_src == 0)
        {
          fprintf(stderr, "The transform does not have the valid src volume info.\n");
          fprintf(stderr, "Either you give src volume info by option -src or\n");
          fprintf(stderr, "make the transform to have the valid src info.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        }
        else
        {
          LTAmodifySrcDstGeom(lta, lta_src, NULL); // add src information
        }
      }
      if (lta->xforms[0].dst.valid == 0)
      {
        if (lta_dst == 0)
        {
          fprintf(stderr, "The transform does not have the valid dst volume info.\n");
          fprintf(stderr, "Either you give src volume info by option -dst or\n");
          fprintf(stderr, "make the transform to have the valid dst info.\n");
          fprintf(stderr, "If the dst was average_305, then you can set\n");
          fprintf(stderr, "environmental variable USE_AVERAGE305 true\n");
          fprintf(stderr, "instead.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        }
        else
        {
          LTAmodifySrcDstGeom(lta, NULL, lta_dst); // add  dst information
        }
      }


      // The following procedure aims to apply an LTA computed from COR format to a volume in non-COR format, or vice versa, as long as they share the same RAS
      // first change to LINEAR RAS_TO_RAS using old info
      if (lta->type != LINEAR_RAS_TO_RAS)
      {
        LTAchangeType(lta, LINEAR_RAS_TO_RAS);
      }

      // now possiblly reset the src and dst
      if (lta_src != NULL)
      {
        //always trust the user
        LTAmodifySrcDstGeom(lta, lta_src, NULL);
      }
      if (lta_dst != NULL)
      {
        //always trust the user
        LTAmodifySrcDstGeom(lta, NULL, lta_dst);
      }

      if (lta->type == LINEAR_RAS_TO_RAS)
      {
        /* Convert it to VOX_TO_VOX */
        /* VOXELsrc_to_VOXELdst = R2Vdst*R2Rlta*V2Rsrc */
        /* Note whether the input should be identical to src or dst here depends
         * on whether the LTA here is the direct or inverse transform
         */
        i_to_r_src = vg_i_to_r(&lta->xforms[0].src);
        r_to_i_dst = vg_r_to_i(&lta->xforms[0].dst);

        if (!r_to_i_dst || !i_to_r_src)
          ErrorExit(ERROR_BADFILE, "%s: failed to extract volume geometries from input LTA file",Progname);
        m_tmp = MatrixMultiply(lta->xforms[0].m_L, i_to_r_src, NULL);
        V_to_V = MatrixMultiply(r_to_i_dst, m_tmp, NULL);
        MatrixFree(&m_tmp);

        MatrixFree(&i_to_r_src);
        MatrixFree(&r_to_i_dst);
      }
    }
    else
    {
      fprintf(stderr, "unknown transform type in file %s\n",
              transform_fname);
      exit(1);
    }

    if (invert_flag)
    {
      /* Geometry of input volume should match that of the dst of the LTA */
      if (MYvg_isEqual(&lta->xforms[0].dst, &vgm_in) == 0)
      {
        ErrorExit(ERROR_BADFILE, "%s: dst volume of lta doesn't match that of input volume",Progname);
      }

      i_to_r_reg = vg_i_to_r(&lta->xforms[0].src);

      if (!i_to_r_reg)
        ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r of registered volume from LTA",Progname);

      m_tmp =  MatrixInverse(V_to_V, NULL);
      if (!m_tmp)
        ErrorExit(ERROR_BADPARM, "%s: transform is singular!", Progname);

      MatrixFree(&V_to_V);
      V_to_V = m_tmp;
    }
    else
    {
      /* Geometry of input volume should match that of the src of the LTA */
      if (MYvg_isEqual(&lta->xforms[0].src, &vgm_in) == 0)
      {
        ErrorExit(ERROR_BADFILE, "%s: src volume of lta doesn't match that of input volume",Progname);
      }

      i_to_r_reg = vg_i_to_r(&lta->xforms[0].dst);

      if (!i_to_r_reg)
        ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r of registered volume from LTA",Progname);
    }

  }
  else
  {
    /* No registration transform need be applied */
    V_to_V = MatrixIdentity(4, NULL);
    i_to_r_reg = extract_i_to_r(mri_in);
    if (!i_to_r_reg)
      ErrorExit(ERROR_BADFILE, "%s: failed to extract i_to_r from input volume",Progname);
  }

  /* Now need to find the vox-to-vox transformation between registered volume
   * (or input volume itself if no registration involved) and the output
   * volume, either in COR format or as the out-like volume
   */
  /* Given a volume with a certain i_to_r, we need to compute the necessary
   * vox-to-voxel transform to change its i_to_r to like another volume.
   * The vox-to-vox is equal to R2V(r_to_i)_likevol*i_to_r_current_vol.
   */
  if (out_like_fname)
  {
    mri_tmp = MRIread(out_like_fname) ;
    if (!mri_tmp)
      ErrorExit(ERROR_NOFILE, "%s: could not read template volume from %s",out_like_fname) ;

    /* out_type = mri_tmp->type; */

    /* specify the out-type to float initially so as not to lose accuracy
     * during reslicing, will change type to correct type later.
     */
    mri_out = MRIalloc(mri_tmp->width, mri_tmp->height, mri_tmp->depth, MRI_FLOAT) ;

    MRIcopyHeader(mri_tmp, mri_out) ;
    MRIfree(&mri_tmp);
  }
  else  /* assume output is in COR format */
  {
    mri_out = MRIalloc(256, 256, 256, MRI_FLOAT) ;
    /* out_type = MRI_UCHAR; */

    /* Who says MRIlinearTransformInterp will change the header??
     * I don't think so!
     */
    //E/ set xyzc_ras to coronal ones.. - these'll get zorched
    //by MRIlinearTransformInterp() - copy again later - is there
    //any use in having them here now?  yes, so we can pass mri_out
    //to the ras2vox fns.


    mri_out->imnr0 = 1; /* what's this? */
    mri_out->imnr1 = 256; /* what's this? */
    mri_out->thick = 1.0;
    mri_out->ps = 1.0; /* what's this? */
    mri_out->xsize = mri_out->ysize = mri_out->zsize = 1.0;
    mri_out->xstart = mri_out->ystart = mri_out->zstart = -128.0;
    mri_out->xend = mri_out->yend = mri_out->zend = 128.0;
    mri_out->x_r =-1;
    mri_out->y_r = 0;
    mri_out->z_r = 0;
    mri_out->x_a = 0;
    mri_out->y_a = 0;
    mri_out->z_a = 1;
    mri_out->x_s = 0;
    mri_out->y_s =-1;
    mri_out->z_s = 0;

    /* In this case, the RAS itself is not fully determined, i.e., c_ras.
     * It's quite arbitrary, different values just change the final
     * sitting of the volume inside the RAS system.
     */
    /* NO! The C_RAS has to be set correctly, depending which target
     * volume the previous Vox_to_Vox transformation assumes!
     * When a registration is involved, the target volume is either
     * the src of LTA (direct) or the dst (inverse transform). When
     * just change format, the target volume is the input itself!!
     */
    if (transform_flag)
    {
      if (invert_flag)
      {
        mri_out->c_r = lta->xforms[0].src.c_r;
        mri_out->c_a = lta->xforms[0].src.c_a;
        mri_out->c_s = lta->xforms[0].src.c_s;

      }
      else
      {
        mri_out->c_r = lta->xforms[0].dst.c_r;
        mri_out->c_a = lta->xforms[0].dst.c_a;
        mri_out->c_s = lta->xforms[0].dst.c_s;
      }
    }
    else
    {
      mri_out->c_r = mri_in->c_r;
      mri_out->c_a = mri_in->c_a;
      mri_out->c_s = mri_in->c_s;
    }

    mri_out->ras_good_flag=1; /* What does this flag mean ? */

    /* since output is just transformed input */
    MRIcopyPulseParameters(mri_in, mri_out) ;

  }

  /* Compute the final input-to-output VOX_to_VOX transformation matrix */
  r_to_i_out = extract_r_to_i(mri_out);

  m_tmp = MatrixMultiply(r_to_i_out, i_to_r_reg, NULL);
  V_to_V = MatrixMultiply(m_tmp, V_to_V, V_to_V);
  MatrixFree(&m_tmp);

  printf("InterpMethod = %d\n", InterpMethod);

  /* Modify the MyMRIlinearTr... if I want to implement my cubic-B-spline
   * interpolation method. Otherwise, unnecessary
   */
  /* mri_out = MyMRIlinearTransformInterp(mri_in, mri_out, V_to_V, InterpMethod); */
  if (InterpMethod == SAMPLE_BSPLINE)
    mri_out = MRIlinearTransformInterpBSpline(mri_in, mri_out, V_to_V,
              SplineDegree);
  else
    mri_out = MRIlinearTransformInterp(mri_in, mri_out, V_to_V, InterpMethod);

  maxV = -10000.0;
  minV = 10000.0;
  for (z=0; z < mri_out->depth; z++)
    for (y=0; y< mri_out->height; y++)
      for (x=0; x < mri_out->width; x++)
      {
        if (MRIFvox(mri_out, x, y, z) > maxV )
          maxV = MRIFvox(mri_out, x, y,z) ;
        if (MRIFvox(mri_out, x, y, z) < minV )
          minV = MRIFvox(mri_out, x, y,z) ;
      }

  if (autoscale)
  {
    noscale = 1;

    /* compute histogram of output volume */
    HISTOGRAM *h, *hsmooth ;
    float fmin, fmax, val, peak, smooth_peak;
    int i, nbins, bin;

    fmin = minV;
    fmax = maxV;
    if (fmin < 0) fmin = 0;
    nbins = 256 ;
    h = HISTOalloc(nbins) ;
    hsmooth = HISTOcopy(h, NULL) ;
    HISTOclear(h, h) ;
    h->bin_size = (fmax-fmin)/255.0 ;

    for (i = 0 ; i < nbins ; i++)
      h->bins[i] = (i+1)*h->bin_size ;

    for (z=0; z < mri_out->depth; z++)
      for (y=0; y< mri_out->height; y++)
        for (x=0; x < mri_out->width; x++)
        {
          val = MRIFvox(mri_out, x, y, z);
          if (val <= 0) continue;

          bin = nint((val - fmin)/h->bin_size);
          if (bin >= h->nbins)
            bin = h->nbins-1;
          else if (bin < 0)
            bin = 0;

          h->counts[bin] += 1.0;
        }
    HISTOfillHoles(h) ;
    HISTOsmooth(h, hsmooth, 5)  ;
    peak =
      hsmooth->bins[HISTOfindHighestPeakInRegion(h, 1, h->nbins)] ;
    //   smooth_peak =
    //  hsmooth->bins[HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins)] ;

    smooth_peak =
      hsmooth->bins[HISTOfindLastPeak(hsmooth, 5, 0.8)] ;

    /*
      bin = nint((smooth_peak - fmin)/hsmooth->bin_size) ;

      printf("Highest peak has count = %d\n", (int)hsmooth->counts[bin]);

      bin = nint((420 - fmin)/hsmooth->bin_size) ;

      printf("bin at 420 has count = %d\n", (int)hsmooth->counts[bin]);
    */

    scale =  110.0/smooth_peak;
    printf("peak of output volume is %g, smooth-peak is %g, multiply by %g to scale it to 110\n", peak, smooth_peak, scale);
    for (z=0; z < mri_out->depth; z++)
      for (y=0; y< mri_out->height; y++)
        for (x=0; x < mri_out->width; x++)
        {
          val = MRIFvox(mri_out, x, y, z);
          MRIFvox(mri_out, x, y, z) = val*scale;
        }

  }


  printf("Output volume (before type-conversion) has max = %g, min =%g\n", maxV, minV);

  /* Finally change type to desired */
  if (mri_out->type != out_type)
  {
    printf("Change output volume to type %d\n", out_type);
    /* I need to modify the MIRchangeType function to make sure
     * it does roundoff instead of simple truncation!
     */
    /* Note if the last flag is set to 1, then it won't do scaling
       and small float numbers will become zero after convert to
       BYTE
    */
    if (out_type == 0 && noscale == 1)
    {
      //convert data to UCHAR
      mri_tmp = MRIalloc(mri_out->width, mri_out->height, mri_out->depth, out_type) ;
      MRIcopyHeader(mri_out, mri_tmp);
      for (z=0; z < mri_out->depth; z++)
        for (y=0; y< mri_out->height; y++)
          for (x=0; x < mri_out->width; x++)
          {
            value = floor(MRIgetVoxVal(mri_out, x, y, z, 0) + 0.5);
            if (value < 0 ) value = 0;
            if (value > 255) value = 255;
            MRIvox(mri_tmp,x,y,z) = (unsigned char)value;
          }
    }
    else
      mri_tmp = MRIchangeType(mri_out, out_type, thred_low, thred_high, noscale);

    MRIfree(&mri_out);
    mri_out = mri_tmp; //swap
  }

  MRIwrite(mri_out, out_vol) ;

  MRIfree(&mri_in);
  MRIfree(&mri_out);

  if (lta_src)
    MRIfree(&lta_src);
  if (lta_dst)
    MRIfree(&lta_dst);

  MatrixFree(&V_to_V);

  if (!r_to_i_out)
    MatrixFree(&r_to_i_out);

  if (!i_to_r_reg)
    MatrixFree(&i_to_r_reg);

  return(0) ;  /* for ansi */
}
Ejemplo n.º 2
0
// (mr) uses LTA to map point array:
MPoint *MRImapControlPoints(const MPoint *pointArray, int count, int useRealRAS,
                            MPoint *trgArray, LTA* lta)
{
	if (trgArray == NULL)
     trgArray=(MPoint*) malloc(count* sizeof(MPoint));

  if (! lta->xforms[0].src.valid )
    ErrorExit(ERROR_BADPARM,"MRImapControlPoints LTA src geometry not valid!\n");
  if (! lta->xforms[0].dst.valid )
    ErrorExit(ERROR_BADPARM,"MRImapControlPoints LTA dst geometry not valid!\n");

  // create face src and target mri from lta:
	MRI* mri_src = MRIallocHeader(1,1,1,MRI_UCHAR,1);
	useVolGeomToMRI(&lta->xforms[0].src,mri_src);
	MRI* mri_trg = MRIallocHeader(1,1,1,MRI_UCHAR,1);
	useVolGeomToMRI(&lta->xforms[0].dst,mri_trg);

  // set vox ras transforms depending on flag:
  MATRIX * src_ras2vox, *trg_vox2ras;
  switch (useRealRAS)
  {
    case 0:
		{
      MATRIX * src_vox2ras = MRIxfmCRS2XYZtkreg(mri_src);
      src_ras2vox = MatrixInverse(src_vox2ras,NULL);	
	  	MatrixFree(&src_vox2ras);
      trg_vox2ras = MRIxfmCRS2XYZtkreg(mri_trg);
      break;
		}
    case 1:
		{
      src_ras2vox = extract_r_to_i(mri_src);
      trg_vox2ras = extract_i_to_r(mri_trg);
      break;
		}
    default:
      ErrorExit(ERROR_BADPARM,
                "MRImapControlPoints has bad useRealRAS flag %d\n",
                useRealRAS) ;
  }
	
	// make vox2vox:
	lta = LTAchangeType(lta,LINEAR_VOX_TO_VOX);

  // concatenate transforms:
  MATRIX *M = NULL;
	M = MatrixMultiply(lta->xforms[0].m_L, src_ras2vox, M);
	M = MatrixMultiply(trg_vox2ras, M, M);
	
	// clenup some stuff:
	MRIfree(&mri_src);
	MRIfree(&mri_trg);
	MatrixFree(&src_ras2vox);
	MatrixFree(&trg_vox2ras);
	
	// map point array
  VECTOR * p  = VectorAlloc(4,MATRIX_REAL);
	VECTOR_ELT(p,4)=1.0;
  VECTOR * p2 = VectorAlloc(4,MATRIX_REAL);
	int i;
	for (i=0;i<count;i++)
	{
    VECTOR_ELT(p,1)=pointArray[i].x;
		VECTOR_ELT(p,2)=pointArray[i].y;
		VECTOR_ELT(p,3)=pointArray[i].z;
		MatrixMultiply(M, p, p2) ;
    trgArray[i].x=VECTOR_ELT(p2,1);
    trgArray[i].y=VECTOR_ELT(p2,2);
    trgArray[i].z=VECTOR_ELT(p2,3);
	}
	
	// cleanup rest
	MatrixFree(&M);
	MatrixFree(&p);
	MatrixFree(&p2);
	
  return trgArray;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[]) {
  char **av;
  MRI *mri_T1, *mri_tmp, *mri_ctrl, *mri_in, *mri_out;
  MRI *mri_snr, *mri_bias;
  MRI *mri_mask1 = NULL;
  MRI *mri_mask2 = NULL;

  int ac, nargs;
  int  width, height, depth, x, y, z;
  int mask1_set = 0;
  int mask2_set = 0;
  int i, j, k, cx, cy, cz, count;
  LTA          *lta = 0;
  int          transform_type;
  double mean, std, value, src, bias, norm;
//  HISTOGRAM *h;
//  float bin_size;
//  int nbins, bin_no;
  double mean1, std1, mean2, std2, count1, count2, slope, offset;
  VOL_GEOM vgtmp;
  LT *lt = NULL;
  MATRIX *m_tmp = NULL;

  Progname = argv[0];

  nargs = handle_version_option
          (argc, argv,
           "$Id: mri_normalize_tp2.c,v 1.8 2011/03/02 00:04:23 nicks Exp $",
           "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
    exit (0);
  argc -= nargs ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++) {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc  !=  3)
    usage(1);

  if (tp1_ctrl_fname == NULL  || tp1_T1_fname == NULL) {
    printf("Use options to specify ctrl volume and T1 volume for tp1\n");
    usage(1);
  }

  mri_in = MRIread(argv[1]) ;
  if (!mri_in)
    ErrorExit(ERROR_BADPARM, "%s: could not read input volume %s",
              Progname, argv[1]) ;

  mri_T1 = MRIread(tp1_T1_fname) ;
  if (!mri_T1)
    ErrorExit(ERROR_BADPARM, "%s: could not read T1 volume for tp1 %s",
              Progname, tp1_T1_fname) ;

  mri_ctrl = MRIread(tp1_ctrl_fname) ;
  if (!mri_ctrl)
    ErrorExit(ERROR_BADPARM,
              "%s: could not read control points volume for tp1 %s",
              Progname, tp1_ctrl_fname) ;

  if ((mri_in->width != mri_T1->width) ||
      (mri_in->height != mri_T1->height) ||
      (mri_in->depth != mri_T1->depth) ||
      (mri_in->width != mri_ctrl->width) ||
      (mri_in->height != mri_ctrl->height) ||
      (mri_in->depth != mri_ctrl->depth)
     ) ErrorExit
         (ERROR_BADPARM,
          "%s: three input volumes have different sizes \n", Progname);

  if (mask1_fname) {
    mri_mask1 = MRIread(mask1_fname) ;
    if (!mri_mask1)
      ErrorExit(ERROR_BADPARM,
                "%s, could not read mask volume for tp1 %s",
                Progname, mask1_fname);
    mask1_set = 1;
    if ((mri_mask1->width != mri_in->width) ||
        (mri_mask1->height != mri_in->height) ||
        (mri_mask1->depth != mri_in->depth))
      ErrorExit
      (ERROR_BADPARM,
       "%s:  mask volumes have different sizes than other volumes \n",
       Progname);
  }
  if (mask2_fname) {
    mri_mask2 = MRIread(mask2_fname) ;
    if (!mri_mask2)
      ErrorExit
      (ERROR_BADPARM,
       "%s, could not read mask volume for tp2 %s",
       Progname, mask2_fname);
    mask2_set = 1;
    if ((mri_mask2->width != mri_T1->width) ||
        (mri_mask2->height != mri_T1->height) ||
        (mri_mask2->depth != mri_T1->depth)
       )
      ErrorExit
      (ERROR_BADPARM,
       "%s:  mask volumes have different sizes than other volumes \n",
       Progname);
  }

  width = mri_in->width ;
  height = mri_in->height ;
  depth = mri_in->depth ;

  //nbins = 200;
  //h = HISTOalloc(nbins);

  mri_out = MRIclone(mri_in, NULL) ;

  /* Read LTA transform and apply it to mri_ctrl */
  if (xform_fname != NULL) {
    // read transform
    transform_type =  TransformFileNameType(xform_fname);

    if (transform_type == MNI_TRANSFORM_TYPE ||
        transform_type == TRANSFORM_ARRAY_TYPE ||
        transform_type == REGISTER_DAT ||
        transform_type == FSLREG_TYPE
       ) {
      printf("Reading transform ...\n");
      lta = LTAreadEx(xform_fname) ;
      if (!lta)
        ErrorExit(ERROR_NOFILE, "%s: could not read transform file %s",
                  Progname, xform_fname) ;

      if (transform_type == FSLREG_TYPE) {
        if (lta_src == 0 || lta_dst == 0) {
          fprintf
          (stderr,
           "ERROR: fslmat does not have information "
           "on the src and dst volumes\n");
          fprintf
          (stderr,
           "ERROR: you must give options '-lta_src' and "
           "'-lta_dst' to specify the src and dst volume infos\n");
        }

        LTAmodifySrcDstGeom
        (lta, lta_src, lta_dst); // add src and dst information
        LTAchangeType(lta, LINEAR_VOX_TO_VOX); //this is necessary
      }

      if (lta->xforms[0].src.valid == 0) {
        if (lta_src == 0) {
          fprintf
          (stderr,
           "The transform does not have the valid src volume info.\n");
          fprintf
          (stderr,
           "Either you give src volume info by option -lta_src or\n");
          fprintf(stderr, "make the transform to have the valid src info.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        } else {
          LTAmodifySrcDstGeom(lta, lta_src, NULL); // add src information
          //   getVolGeom(lta_src, &lt->src);
        }
      }
      if (lta->xforms[0].dst.valid == 0) {
        if (lta_dst == 0) {
          fprintf
          (stderr,
           "The transform does not have the valid dst volume info.\n");
          fprintf
          (stderr,
           "Either you give src volume info by option -lta_dst or\n");
          fprintf
          (stderr,
           "make the transform to have the valid dst info.\n");
          fprintf
          (stderr,
           "If the dst was average_305, then you can set\n");
          fprintf
          (stderr,
           "environmental variable USE_AVERAGE305 true\n");
          fprintf
          (stderr,
           "without giving the dst volume for RAS-to-RAS transform.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        } else {
          LTAmodifySrcDstGeom(lta, NULL, lta_dst); // add  dst information
        }
      }
    } else {
      ErrorExit
      (ERROR_BADPARM,
       "transform is not of MNI, nor Register.dat, nor FSLMAT type");
    }

    if (invert) {
      m_tmp = lta->xforms[0].m_L ;
      lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ;
      MatrixFree(&m_tmp) ;
      lt = &lta->xforms[0];
      if (lt->dst.valid == 0 || lt->src.valid == 0) {
        fprintf
        (stderr,
         "WARNING:***********************************************\n");
        fprintf
        (stderr,
         "WARNING: dst volume infor is invalid.  "
         "Most likely produce wrong inverse.\n");
        fprintf
        (stderr,
         "WARNING:***********************************************\n");
      }
      copyVolGeom(&lt->dst, &vgtmp);
      copyVolGeom(&lt->src, &lt->dst);
      copyVolGeom(&vgtmp, &lt->src);
    }

    //    LTAchangeType(lta, LINEAR_VOX_TO_VOX);

    /* apply lta to the ctrl volume */
    mri_tmp = MRIalloc(mri_ctrl->width,
                       mri_ctrl->height,
                       mri_ctrl->depth,
                       mri_ctrl->type) ;
    MRIcopyHeader(mri_in, mri_tmp) ;
    // this function doesn't do NEAREST at all!!
    // I found the bug, in LTAtransformInterp()
    mri_tmp = LTAtransformInterp(mri_ctrl, mri_tmp, lta, SAMPLE_NEAREST);

    MRIfree(&mri_ctrl);
    mri_ctrl = mri_tmp;

    if (mask1_fname != NULL && mask2_fname == NULL) {
      printf("map mask for tp1 to get mask for tp2 ...\n");
      mri_mask2 = MRIalloc(mri_in->width,
                           mri_in->height,
                           mri_in->depth,
                           mri_mask1->type) ;
      MRIcopyHeader(mri_in, mri_mask2) ;

      mri_mask2 = LTAtransformInterp(mri_mask1,
                                     mri_mask2,
                                     lta,
                                     SAMPLE_NEAREST);
      mask2_set = 1;
      if (debug_flag)
        MRIwrite(mri_mask2, "mri_mask2.mgz");
    } else if (mask2_fname != NULL && mask1_fname == NULL) {
      printf("map mask for tp2 to get mask for tp1 ...\n");
      //need to invert lta first
      m_tmp = lta->xforms[0].m_L ;
      lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ;
      MatrixFree(&m_tmp) ;
      lt = &lta->xforms[0];

      copyVolGeom(&lt->dst, &vgtmp);
      copyVolGeom(&lt->src, &lt->dst);
      copyVolGeom(&vgtmp, &lt->src);

      mri_mask1 = MRIalloc(mri_T1->width,
                           mri_T1->height,
                           mri_T1->depth,
                           mri_mask2->type) ;
      MRIcopyHeader(mri_T1, mri_mask1) ;

      mri_mask1 = LTAtransformInterp(mri_mask2,
                                     mri_mask1,
                                     lta,
                                     SAMPLE_NEAREST);
      mask1_set = 1;
      if (debug_flag)
        MRIwrite(mri_mask1, "mri_mask1.mgz");
    }

    if (lta_src)
      MRIfree(&lta_src);
    if (lta_dst)
      MRIfree(&lta_dst);

    if (lta)
      LTAfree(&lta);
  }   /* if (xform_fname != NULL) */

  if (debug_flag) {
    //    MRIwrite(mri_snr, "snr.mgz");
    MRIwrite(mri_ctrl, "ctrl.mgz");
  }

  if (mask1_set == 0) {
    //create mask1
    mri_mask1 = MRIalloc(mri_T1->width,
                         mri_T1->height,
                         mri_T1->depth,
                         MRI_UCHAR) ;
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++) {
          if (MRIgetVoxVal(mri_T1, x, y, z, 0) < noise_threshold) {
            MRIvox(mri_mask1,x,y,z) = 0;
          } else
            MRIvox(mri_mask1,x,y,z) = 1;
        }
  }

  if (mask2_set == 0) {
    //create mask2
    mri_mask2 = MRIalloc(mri_in->width,
                         mri_in->height,
                         mri_in->depth,
                         MRI_UCHAR) ;
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++) {
          if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) {
            MRIvox(mri_mask2,x,y,z) = 0;
          } else
            MRIvox(mri_mask2,x,y,z) = 1;
        }
  }


#if 0
  /* compute the mean and std of T1 volume */
  /* Using only high SNR points */
  mri_snr = MRIalloc(mri_T1->width, mri_T1->height, mri_T1->depth, MRI_FLOAT) ;
  MRIcopyHeader(mri_T1, mri_snr) ;

  h->bin_size = bin_size = 0.5;
  for (bin_no = 0; bin_no < nbins; bin_no++)
    h->bins[bin_no] = (bin_no)*bin_size;

  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        if (MRIgetVoxVal(mri_T1, x, y, z, 0) < noise_threshold) {
          MRIFvox(mri_snr,x,y,z) = 0;
          continue;
        }
        mean = 0;
        std = 0;
        count = 0;
        for (i=-1; i<=1; i++)
          for (j=-1; j<=1; j++)
            for (k=-1;k<=1;k++) {
              cx = x+i;
              cy = y+j, cz = z+k;

              if (cx < 0 ||
                  cx >= width ||
                  cy < 0 ||
                  cy >= height ||
                  cz < 0 ||
                  cz >= depth) continue;
              count++;
              value = MRIgetVoxVal(mri_T1, cx, cy, cz, 0);
              mean += value;
              std += value*value;
            }

        mean /= (count + 1e-30);
        std /=  (count + 1e-30);

        std = std - mean *mean;

        if (std <= 0)
          std = 0;
        value = mean/sqrt(std);

        MRIFvox(mri_snr,x,y,z) = value;
        bin_no = nint((float)value/(float)bin_size);
        if (bin_no >= nbins) bin_no = nbins - 1;
        h->counts[bin_no]++;
      }

  for (num = 0.0f, b = h->nbins - 1; b >= 1; b --) {
    num += h->counts[b];
    if (num > 20000) /* this may make me only use WM points,
                        is it good to use only WM to compute
                        scale of intensity?? */
      break;
  }

  printf("using SNR threshold %2.3f at bin %d\n", h->bins[b], b);

  mean1 = 0;
  std1 = 0;
  count1 = 0;
  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        if (MRIgetVoxVal(mri_T1, x, y, z, 0) < noise_threshold) {
          continue;
        }

        value = MRIFvox(mri_snr,x,y,z);

        if (value < h->bins[b]) continue;

        value = MRIgetVoxVal(mri_T1, x, y, z, 0);
        count1++;
        mean1 += value;
        std1 += value*value;

      }

  MRIfree(&mri_snr);
#else
  printf("compute mean and std of tp1 volume within masked area...\n");
  mean1 = 0;
  std1 = 0;
  count1 = 0;
  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        if (MRIgetVoxVal(mri_mask1, x, y, z, 0) <= 1e-30) {
          continue;
        }

        value = MRIgetVoxVal(mri_T1, x, y, z, 0);


        count1++;
        mean1 += value;
        std1 += value*value;

      }

#endif

  mean1 /= (count1 + 1e-30);
  std1 /= (count1 + 1e-30);
  std1 = std1 - mean1*mean1;
  if (std1 <= 0)
    printf("warning: negative std for T1 volume. \n");
  else
    printf("mean and variance for tp1 volume are %g and %g\n", mean1, std1);

  printf("now compute SNR and stats for input volume ... \n");
  mri_snr = MRIalloc(mri_in->width, mri_in->height, mri_in->depth, MRI_FLOAT) ;
  MRIcopyHeader(mri_in, mri_snr) ;
  //HISTOclear(h,h);
  //h->bin_size = bin_size = 0.5;
  //for (bin_no = 0; bin_no < nbins; bin_no++)
  //  h->bins[bin_no] = (bin_no)*bin_size;

  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) {
          MRIFvox(mri_snr,x,y,z) = 0;
          continue;
        }
        mean = 0;
        std = 0;
        count = 0;
        for (i=-1; i<=1; i++)
          for (j=-1; j<=1; j++)
            for (k=-1;k<=1;k++) {
              cx = x+i;
              cy = y+j, cz = z+k;

              if (cx < 0 ||
                  cx >= width ||
                  cy < 0 ||
                  cy >= height ||
                  cz < 0 ||
                  cz >= depth) continue;
              count++;
              value = MRIgetVoxVal(mri_in, cx, cy, cz, 0);
              mean += value;
              std += value*value;
            }

        mean /= (count + 1e-30);
        std /=  (count + 1e-30);

        std = std - mean *mean;

        if (std <= 0)
          std = 0;
        value = mean/sqrt(std);

        MRIFvox(mri_snr,x,y,z) = value;
        //bin_no = nint((float)value/(float)bin_size);
        //if (bin_no >= nbins) bin_no = nbins - 1;
        //h->counts[bin_no]++;
      }

#if 0
  for (num = 0.0f, b = h->nbins - 1; b >= 1; b --) {
    num += h->counts[b];
    if (num > 20000) /* this may make me only use WM points, is it good to
                        use only WM to compute scale of intensity?? */
      break;
  }

  printf("using SNR threshold %2.3f at bin %d\n", h->bins[b], b);

  mean2 = 0;
  std2 = 0;
  count2 = 0;
  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) {
          continue;
        }

        value = MRIFvox(mri_snr,x,y,z);

        if (value >= h->bins[b]) {
          count2++;
          mean2 += value;
          std2 += value*value;
        }
      }
#else
  printf("compute mean and std of tp2 volume within masked area\n");
  /* somehow mri_watershed seems to leave some unzero voxels around
  image border, so I will skip image boundaries
  no, that's not a problem of most recent mri_watershed;
  something wrong previously */
  mean2 = 0;
  std2 = 0;
  count2 = 0;
  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        if (MRIgetVoxVal(mri_mask2, x, y, z, 0) <= 1e-30) {
          continue;
        }

        value = MRIgetVoxVal(mri_in, x, y, z, 0);

        count2++;
        mean2 += value;
        std2 += value*value;
      }
#endif

  mean2 /= (count2 + 1e-30);
  std2 /= (count2 + 1e-30);
  std2 = std2 - mean2*mean2;
  if (std2 <= 0)
    printf("warning: negative std for input volume. \n");
  else
    printf("mean and variance for input tp2 volume are %g and %g\n",
           mean2, std2);

  //compute intensity scale
  slope = sqrt(std1/std2);
  offset = mean1 - slope*mean2;

  printf("scale input volume by %g x + %g\n", slope, offset);
  // first change mri_in to FLOAT type
  mri_tmp = MRIchangeType(mri_in, MRI_FLOAT, 0, 1.0, 1);
  MRIfree(&mri_in);
  mri_in = mri_tmp;
  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        value = MRIFvox(mri_in, x, y, z);
        MRIFvox(mri_in, x, y, z) = value*slope + offset;
      }


  //  printf("compute SNR map of tp2 volume\n"); //already done above
  //  mri_snr = MRIalloc(mri_ctrl->width,
  //     mri_ctrl->height, mri_ctrl->depth, MRI_FLOAT) ;

  for (z=0; z < depth; z++)
    for (y=0; y< height; y++)
      for (x=0; x < width; x++) {
        if (MRIgetVoxVal(mri_in, x, y, z, 0) < noise_threshold) {
          //    MRIFvox(mri_snr,x,y,z) = 0;
          continue;
        }

        value = MRIFvox(mri_snr,x,y,z);

        if (value < 20) MRIvox(mri_ctrl, x, y, z) = 0;
        else if (MRIvox(mri_ctrl, x, y, z) > 0) {
          MRIvox(mri_ctrl, x, y, z) = 1;
        }
      }
  if (debug_flag) {
    MRIwrite(mri_snr, "snr.mgz");
    //    MRIwrite(mri_ctrl, "ctrl.mgz");
  }

  // SNR >= 20 seems a good threshold

  // Now use ctrl points to normalize tp2
  printf("normalize tp2...\n");
  mri_bias = MRIbuildBiasImage(mri_in, mri_ctrl, NULL, bias_sigma) ;

  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {
        src = MRIgetVoxVal(mri_in, x, y, z, 0) ;
        bias = MRIgetVoxVal(mri_bias, x, y, z, 0) ;
        if (!bias)   /* should never happen */
          norm = (float)src ;
        else
          norm = (float)src * 110.0 / (float)bias ;
        if (norm > 255.0f && mri_out->type == MRI_UCHAR)
          norm = 255.0f ;
        else if (norm < 0.0f && mri_out->type == MRI_UCHAR)
          norm = 0.0f ;
        MRIsetVoxVal(mri_out, x, y, z, 0, norm) ;
      }
    }
  }

  printf("writing normalized volume to %s...\n", argv[2]) ;
  MRIwrite(mri_out, argv[2]);

  MRIfree(&mri_in);
  MRIfree(&mri_bias);
  MRIfree(&mri_out);
  MRIfree(&mri_T1);
  MRIfree(&mri_ctrl);
  MRIfree(&mri_snr);
  //HISTOfree(&h);

  exit(0);

}  /*  end main()  */
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{

  char **av, *ltafn1, *ltafn2, *ltafn_total;
  LTA *lta1, *lta2, *lta_total;
  FILE *fo;
  MATRIX *r_to_i_1, *i_to_r_1, *i_to_r_2, *r_to_i_2;
  MATRIX *RAS_1_to_1, *RAS_2_to_2, *m_tmp;
  int nargs, ac;
  int type = 0;

  Progname = argv[0];

  nargs = handle_version_option
          (argc, argv,
           "$Id: mri_concatenate_lta.c,v 1.10 2011/03/16 21:23:48 nicks Exp $",
           "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
  {
    exit (0);
  }
  argc -= nargs ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++)
  {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc != 4)
  {
    usage(1);
  }

  ltafn1 = argv[1];
  ltafn2 = argv[2];
  ltafn_total = argv[3];

  printf("Read individual LTAs\n");
  //lta1 = ltaReadFileEx(ltafn1);
  TRANSFORM * trans = TransformRead(ltafn1);
  lta1 =  (LTA *)trans->xform ;

  if (!lta1)
  {
    ErrorExit(ERROR_BADFILE, "%s: can't read file %s",Progname, ltafn1);
  }

  if (invert1)
  {
    VOL_GEOM vgtmp;
    LT *lt;
    MATRIX *m_tmp = lta1->xforms[0].m_L ;
    lta1->xforms[0].m_L = MatrixInverse(lta1->xforms[0].m_L, NULL) ;
    MatrixFree(&m_tmp) ;
    lt = &lta1->xforms[0];
    if (lt->dst.valid == 0 || lt->src.valid == 0)
    {
      fprintf
      (stderr,
       "WARNING:********************************************************\n");
      fprintf
      (stderr,
       "WARNING:dst or src volume is invalid.  Inverse likely wrong.\n");
      fprintf
      (stderr,
       "WARNING:********************************************************\n");
    }
    copyVolGeom(&lt->dst, &vgtmp);
    copyVolGeom(&lt->src, &lt->dst);
    copyVolGeom(&vgtmp, &lt->src);
  }

  if (strcmp(ltafn2,"identity.nofile") == 0)
  {
    type = TransformFileNameType(ltafn_total);
    if (type == MNI_TRANSFORM_TYPE)
    {
      ltaMNIwrite(lta1, ltafn_total);
    }
    else
    {
      //change type to VOXEL_VOXEL
      if (lta1->type != out_type)
      {
        LTAchangeType(lta1, out_type);
      }

      printf("Writing  LTA to file %s...\n", ltafn_total);
      fo = fopen(ltafn_total,"w");
      if (fo==NULL)
        ErrorExit(ERROR_BADFILE,
                  "%s: can't create file %s",Progname, ltafn_total);

      LTAprint(fo, lta1);

      fclose(fo);
    }
    LTAfree(&lta1);
    printf("%s successful.\n", Progname);
    return 0;
  }


  type = TransformFileNameType(ltafn2);
  if (type == MNI_TRANSFORM_TYPE)
  {
    if (invert2 != 0)
      ErrorExit
      (ERROR_BADFILE,
       "%s: LTA2 is talairach.xfm, and shouldn't be inverted ",
       Progname);

    lta2 = ltaMNIreadEx(ltafn2) ;
    //the talairach xform is supposed to be linear_RAS_TO_RAS, right? Yes
    lta2->type =  LINEAR_RAS_TO_RAS;

    if (tal_src_file == 0 && lta2->xforms[0].src.valid == 0)
      ErrorExit
      (ERROR_BADFILE,
       "%s: pls use -tal option to give talairach src and "
       "template filenames",Progname);
    if (tal_dst_file == 0 && lta2->xforms[0].dst.valid == 0)
      ErrorExit
      (ERROR_BADFILE,
       "%s: pls use -tal option to give talairach src and "
       "template filenames",Progname);

    if (tal_src_file != 0)
    {
      LTAmodifySrcDstGeom(lta2, tal_src, NULL);  // add src and dst information
    }
    if (tal_dst_file != 0)
    {
      LTAmodifySrcDstGeom(lta2, NULL, tal_dst);  // add src and dst information
    }
  }
  else
  {
    TRANSFORM * trans = TransformRead(ltafn2);
    lta2 =  (LTA *)trans->xform ;
    //lta2 = ltaReadFileEx(ltafn2);
  }

  if (!lta2)
  {
    ErrorExit(ERROR_BADFILE, "%s: can't read file %s",Progname, ltafn2);
  }

  if (invert2)
  {
    VOL_GEOM vgtmp;
    LT *lt;
    MATRIX *m_tmp = lta2->xforms[0].m_L ;
    lta2->xforms[0].m_L = MatrixInverse(lta2->xforms[0].m_L, NULL) ;
    MatrixFree(&m_tmp) ;
    lt = &lta2->xforms[0];
    if (lt->dst.valid == 0 || lt->src.valid == 0)
    {
      fprintf
      (stderr,
       "WARNING:********************************************************\n");
      fprintf
      (stderr,
       "WARNING:dst or src volume is invalid.  Inverse likely wrong.\n");
      fprintf
      (stderr,
       "WARNING:********************************************************\n");
    }
    copyVolGeom(&lt->dst, &vgtmp);
    copyVolGeom(&lt->src, &lt->dst);
    copyVolGeom(&vgtmp, &lt->src);
  }

  if (vg_isEqual(&lta1->xforms[0].dst, &lta2->xforms[0].src) == 0)
  {
    /*    ErrorExit(ERROR_BADFILE,
          "%s: dst volume of lta1 doesn't match src
          volume of lta2",Progname);*/
    printf("Warning: dst volume of lta1 doesn't match src volume of lta2\n");
    printf("Volume geometry for lta1-dst: \n");
    vg_print(&lta1->xforms[0].dst);
    printf("Volume geometry for lta2-src:\n");
    vg_print(&lta2->xforms[0].src);
  }

  printf("Combining the two LTAs to get a RAS-to-RAS from src "
         "of LTA1 to dst of LTA2...\n");

  if (lta1->type == LINEAR_RAS_TO_RAS)
  {
    RAS_1_to_1 =  MatrixCopy(lta1->xforms[0].m_L, NULL);
  }
  else if (lta1->type == LINEAR_VOX_TO_VOX)
  {
    r_to_i_1 = vg_r_to_i(&lta1->xforms[0].src);
    i_to_r_1 = vg_i_to_r(&lta1->xforms[0].dst);
    if (!r_to_i_1 || !i_to_r_1)
      ErrorExit(ERROR_BADFILE,
                "%s: failed to convert LTA1 to RAS_to_RAS",Progname);
    m_tmp = MatrixMultiply(lta1->xforms[0].m_L, r_to_i_1, NULL);
    RAS_1_to_1 = MatrixMultiply(i_to_r_1, m_tmp, NULL);
    MatrixFree(&m_tmp);
  }
  else
  {
    ErrorExit(ERROR_BADFILE,
              "%s: unknown transform type for LTA1",Progname);
  }

  if (lta2->type == LINEAR_RAS_TO_RAS)
  {
    RAS_2_to_2 =  MatrixCopy(lta2->xforms[0].m_L, NULL);
  }
  else if (lta2->type == LINEAR_VOX_TO_VOX)
  {
    r_to_i_2 = vg_r_to_i(&lta2->xforms[0].src);
    i_to_r_2 = vg_i_to_r(&lta2->xforms[0].dst);
    if (!r_to_i_2 || !i_to_r_2)
      ErrorExit(ERROR_BADFILE,
                "%s: failed to convert LTA1 to RAS_to_RAS",Progname);
    m_tmp = MatrixMultiply(lta2->xforms[0].m_L, r_to_i_2, NULL);
    RAS_2_to_2 = MatrixMultiply(i_to_r_2, m_tmp, NULL);
    MatrixFree(&m_tmp);
  }
  else
  {
    ErrorExit(ERROR_BADFILE, "%s: unknown transform type for LTA1",Progname);
  }

  lta_total = LTAalloc(1, NULL);
  lta_total->type = LINEAR_RAS_TO_RAS;
  MatrixMultiply(RAS_2_to_2, RAS_1_to_1, lta_total->xforms[0].m_L);
  lta_total->xforms[0].src = lta1->xforms[0].src;
  lta_total->xforms[0].dst = lta2->xforms[0].dst;
  lta_total->xforms[0].x0 = 0;
  lta_total->xforms[0].y0 = 0;
  lta_total->xforms[0].z0 = 0;
  lta_total->xforms[0].sigma = 1.0f;

  type = TransformFileNameType(ltafn_total);
  if (type == MNI_TRANSFORM_TYPE)
  {
    ltaMNIwrite(lta_total, ltafn_total);
  }
  else
  {
    //change type to VOXEL_VOXEL
    if (lta_total->type != out_type)
    {
      LTAchangeType(lta_total, out_type);
    }

    printf("Writing combined LTA to file %s...\n", ltafn_total);
    fo = fopen(ltafn_total,"w");
    if (fo==NULL)
      ErrorExit(ERROR_BADFILE,
                "%s: can't create file %s",Progname, ltafn_total);

    LTAprint(fo, lta_total);

    fclose(fo);
  }

  LTAfree(&lta1);
  LTAfree(&lta2);
  LTAfree(&lta_total);
  MatrixFree(&RAS_1_to_1);
  MatrixFree(&RAS_2_to_2);

  if (tal_src)
  {
    MRIfree(&tal_src);
  }
  if (tal_dst)
  {
    MRIfree(&tal_dst);
  }

  printf("%s successful.\n", Progname);

  return(0);

}  /*  end main()  */
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
  char **av;
  MRI *mri_src, *mri_mask, *mri_dst ;
  int nargs, ac, nmask;
  int x, y, z;
  float value;
  MRI_REGION *region;
  LTA          *lta = 0;
  int          transform_type;
  MRI *mri_tmp;

  nargs =
    handle_version_option
    (
      argc, argv,
      "$Id: mri_mask.c,v 1.18 2012/12/07 22:45:50 greve Exp $", "$Name:  $"
    );
  if (nargs && argc - nargs == 1)
  {
    exit (0);
  }
  argc -= nargs ;

  Progname = argv[0];
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;

  ac = argc ;
  av = argv ;
  for ( ; argc > 1 && ISOPTION(*argv[1]) ; argc--, argv++)
  {
    nargs = get_option(argc, argv) ;
    argc -= nargs ;
    argv += nargs ;
  }

  if (argc != 4)
  {
    printf("Incorrect number of arguments, argc = %d\n", argc);
    usage(1);
  }

  mri_src = MRIread(argv[1]) ;
  if (!mri_src)
    ErrorExit(ERROR_BADPARM, "%s: could not read source volume %s",
              Progname, argv[1]) ;
  mri_mask = MRIread(argv[2]) ;
  if (!mri_mask)
    ErrorExit(ERROR_BADPARM, "%s: could not read mask volume %s",
              Progname, argv[2]) ;

  if(mri_src->width != mri_mask->width)
  {
    printf("ERROR: dimension mismatch between source and mask\n");
    exit(1);
  }

  printf("DoAbs = %d\n",DoAbs);

  /* Read LTA transform and apply it to mri_mask */
  if (xform_fname != NULL)
  {

    printf("Apply the given LTA xfrom to the mask volume\n");
    // read transform
    transform_type =  TransformFileNameType(xform_fname);

    if (transform_type == MNI_TRANSFORM_TYPE ||
        transform_type == TRANSFORM_ARRAY_TYPE ||
        transform_type == REGISTER_DAT ||
        transform_type == FSLREG_TYPE
       )
    {
      printf("Reading transform ...\n");
      lta = LTAreadEx(xform_fname) ;
      if (!lta)
        ErrorExit(ERROR_NOFILE, "%s: could not read transform file %s",
                  Progname, xform_fname) ;

      if (transform_type == FSLREG_TYPE)
      {
        if (lta_src == 0 || lta_dst == 0)
        {
          fprintf(stderr,
                  "ERROR: fslmat does not have information on "
                  "the src and dst volumes\n");
          fprintf(stderr,
                  "ERROR: you must give options '-lta_src' "
                  "and '-lta_dst' to specify the src and dst volume infos\n");
        }

        LTAmodifySrcDstGeom(lta, lta_src, lta_dst);
        // add src and dst information
        LTAchangeType(lta, LINEAR_VOX_TO_VOX);
      }

      if (lta->xforms[0].src.valid == 0)
      {
        if (lta_src == 0)
        {
          fprintf(stderr,
                  "The transform does not have the valid src volume info.\n");
          fprintf(stderr,
                  "Either you give src volume info by option -lta_src or\n");
          fprintf(stderr,
                  "make the transform to have the valid src info.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        }
        else
        {
          LTAmodifySrcDstGeom(lta, lta_src, NULL); // add src information
          //      getVolGeom(lta_src, &lt->src);
        }
      }
      if (lta->xforms[0].dst.valid == 0)
      {
        if (lta_dst == 0)
        {
          fprintf(stderr,
                  "The transform does not have the valid dst volume info.\n");
          fprintf(stderr,
                  "Either you give src volume info by option -lta_dst or\n");
          fprintf(stderr,
                  "make the transform to have the valid dst info.\n");
          fprintf(stderr,
                  "If the dst was average_305, then you can set\n");
          fprintf(stderr,
                  "environmental variable USE_AVERAGE305 true\n");
          fprintf(stderr,
                  "without giving the dst volume for RAS-to-RAS transform.\n");
          ErrorExit(ERROR_BAD_PARM, "Bailing out...\n");
        }
        else
        {
          LTAmodifySrcDstGeom(lta, NULL, lta_dst); // add  dst information
        }
      }
    }
    else
    {
      ErrorExit(ERROR_BADPARM,
                "transform is not of MNI, nor Register.dat, nor FSLMAT type");
    }

    if (invert)
    {
      VOL_GEOM vgtmp;
      LT *lt;
      MATRIX *m_tmp = lta->xforms[0].m_L ;
      lta->xforms[0].m_L = MatrixInverse(lta->xforms[0].m_L, NULL) ;
      MatrixFree(&m_tmp) ;
      lt = &lta->xforms[0];
      if (lt->dst.valid == 0 || lt->src.valid == 0)
      {
        fprintf(stderr,
                "WARNING:**************************************"
                "*************************\n");
        fprintf(stderr,
                "WARNING:dst volume information is invalid.  "
                "Most likely produced wrong inverse.\n");
        fprintf(stderr,
                "WARNING:**************************************"
                "*************************\n");
      }
      copyVolGeom(&lt->dst, &vgtmp);
      copyVolGeom(&lt->src, &lt->dst);
      copyVolGeom(&vgtmp, &lt->src);
    }

    //    LTAchangeType(lta, LINEAR_VOX_TO_VOX);
    mri_tmp =
      MRIalloc(mri_src->width,
               mri_src->height,
               mri_src->depth,
               mri_mask->type) ;
    MRIcopyHeader(mri_src, mri_tmp) ;

    mri_tmp = LTAtransformInterp(mri_mask, mri_tmp, lta, InterpMethod);

    // mri_tmp =
    //MRIlinearTransformInterp
    //  (
    //   mri_mask, mri_tmp, lta->xforms[0].m_L, InterpMethod
    //  );

    MRIfree(&mri_mask);

    mri_mask = mri_tmp;

    if (lta_src)
    {
      MRIfree(&lta_src);
    }
    if (lta_dst)
    {
      MRIfree(&lta_dst);
    }
    if (lta)
    {
      LTAfree(&lta);
    }
  }   /* if (xform_fname != NULL) */

  // Threshold mask
  nmask = 0;
  for (z = 0 ; z <mri_mask->depth ; z++)
  {
    for (y = 0 ; y < mri_mask->height ; y++)
    {
      for (x = 0 ; x < mri_mask->width ; x++)
      {
        value = MRIgetVoxVal(mri_mask, x, y, z, 0);
        if(DoAbs)
        {
          value = fabs(value);
        }
        if(value <= threshold)
        {
          MRIsetVoxVal(mri_mask,x,y,z,0,0);
        }
        else
        {
          nmask ++;
        }
      }
    }
  }
  printf("Found %d voxels in mask (pct=%6.2f)\n",nmask,
	 100.0*nmask/(mri_mask->width*mri_mask->height*mri_mask->depth));

  if(DoBB){
    printf("Computing bounding box, npad = %d\n",nPadBB);
    region = REGIONgetBoundingBox(mri_mask,nPadBB);
    REGIONprint(stdout, region);
    mri_tmp = MRIextractRegion(mri_mask, NULL, region);
    if(mri_tmp == NULL) exit(1);
    MRIfree(&mri_mask);
    mri_mask = mri_tmp;
    mri_tmp = MRIextractRegion(mri_src, NULL, region);
    if(mri_tmp == NULL) exit(1);
    MRIfree(&mri_src);
    mri_src = mri_tmp;
  }

  int mask=0;
  float out_val=0;
  if (do_transfer)
  {
    mask = (int)transfer_val;
    out_val = transfer_val;
  }
  mri_dst = MRImask(mri_src, mri_mask, NULL, mask, out_val) ;
  if (!mri_dst)
  {
    ErrorExit(Gerror, "%s: stripping failed", Progname) ;
  }

  if (keep_mask_deletion_edits)
  {
    mri_dst = MRImask(mri_dst, mri_mask, NULL, 1, 1) ; // keep voxels = 1
    if (!mri_dst)
      ErrorExit(Gerror, "%s: stripping failed on keep_mask_deletion_edits",
                Progname) ;
  }

  printf("Writing masked volume to %s...", argv[3]) ;
  MRIwrite(mri_dst, argv[3]);
  printf("done.\n") ;

  MRIfree(&mri_src);
  MRIfree(&mri_mask);
  MRIfree(&mri_dst);

  exit(0);

}  /*  end main()  */