Ejemplo n.º 1
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.º 2
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()  */