예제 #1
0
/*---------------------------------------------------------------*/
int main(int argc, char *argv[]) {
  int nargs, n, Ntp, nsearch, nsearch2=0;
  double fwhm = 0, nresels, voxelvolume, nvoxperresel, reselvolume;
  double car1mn, rar1mn,sar1mn,cfwhm,rfwhm,sfwhm, ftmp;
  double car2mn, rar2mn,sar2mn;
  double gmean, gstd, gmax;
  FILE *fp;

  sprintf(tmpstr, "S%sER%sRONT%sOR", "URF", "_F", "DO") ;
  setenv(tmpstr,"1",0);

  nargs = handle_version_option (argc, argv, vcid, "$Name:  $");
  if (nargs && argc - nargs == 1) exit (0);
  argc -= nargs;
  cmdline = argv2cmdline(argc,argv);
  uname(&uts);
  getcwd(cwd,2000);

  Progname = argv[0] ;
  argc --;
  argv++;
  ErrorInit(NULL, NULL, NULL) ;
  DiagInit(NULL, NULL, NULL) ;
  if (argc == 0) usage_exit();
  parse_commandline(argc, argv);
  check_options();
  if (checkoptsonly) return(0);

  if (SynthSeed < 0) SynthSeed = PDFtodSeed();
  if (debug) dump_options(stdout);

  // ------------- load or synthesize input ---------------------
  InVals = MRIreadType(inpath,InValsType);
  if(InVals == NULL) exit(1);
  if(SetTR){
    printf("Setting TR to %g ms\n",TR);
    InVals->tr = TR;
  }
  if((nframes < 0 && synth) || !synth) nframes = InVals->nframes;
  if(nframes < nframesmin && !SmoothOnly && !sum2file) {
    printf("ERROR: nframes = %d, need at least %d\n",
	   nframes,nframesmin);
    exit(1);
  }
  if (InVals->type != MRI_FLOAT) {
    mritmp = MRISeqchangeType(InVals, MRI_FLOAT, 0, 0, 0);
    MRIfree(&InVals);
    InVals = mritmp;
  }
  if(synth) {
    printf("Synthesizing %d frames, Seed = %d\n",nframes,SynthSeed);
    mritmp = MRIcloneBySpace(InVals,MRI_FLOAT,nframes);
    MRIfree(&InVals);
    MRIrandn(mritmp->width, mritmp->height, mritmp->depth, 
	     nframes, 0, 1, mritmp);
    InVals = mritmp;
  }
  voxelvolume = InVals->xsize * InVals->ysize * InVals->zsize ;
  printf("voxelvolume %g mm3\n",voxelvolume);

  if(DoSqr){
    printf("Computing square of input\n");
    MRIsquare(InVals,NULL,InVals);
  }

  // -------------------- handle masking ------------------------
  if (maskpath) {
    printf("Loading mask %s\n",maskpath);
    mask = MRIread(maskpath);
    if(mask==NULL) exit(1);
    if(MRIdimMismatch(mask,InVals,0)){
      printf("ERROR: dimension mismatch between mask and input\n");
      exit(1);
    }
    MRIbinarize2(mask, mask, maskthresh, 0, 1);
  }
  if (automask) {
    RFglobalStats(InVals, NULL, &gmean, &gstd, &gmax);
    maskthresh = gmean * automaskthresh;
    printf("Computing mask, relative threshold = %g, gmean = %g, absthresh = %g\n",
           automaskthresh,gmean,maskthresh);
    mritmp = MRIframeMean(InVals,NULL);
    //MRIwrite(mritmp,"fmean.mgh");
    mask = MRIbinarize2(mritmp, NULL, maskthresh, 0, 1);
    MRIfree(&mritmp);
  }
  if (mask) {
    if (maskinv) {
      printf("Inverting mask\n");
      MRImaskInvert(mask,mask);
    }
    nsearch = MRInMask(mask);
    if (nsearch == 0) {
      printf("ERROR: no voxels found in mask\n");
      exit(1);
    }
    // Erode the mask -----------------------------------------------
    if (nerode > 0) {
      printf("Eroding mask %d times\n",nerode);
      for (n=0; n<nerode; n++) MRIerode(mask,mask);
      nsearch2 = MRInMask(mask);
      if (nsearch2 == 0) {
        printf("ERROR: no voxels found in mask after eroding\n");
        exit(1);
      }
      printf("%d voxels in mask after eroding\n",nsearch2);
    }
    //---- Save mask -----
    if (outmaskpath) MRIwrite(mask,outmaskpath);
  } else nsearch = InVals->width * InVals->height * InVals->depth;
  printf("Search region is %d voxels = %lf mm3\n",nsearch,nsearch*voxelvolume);

  if( (infwhm > 0 || infwhmc > 0 || infwhmr > 0 || infwhms > 0) && SmoothOnly) {
    if(SaveUnmasked) mritmp = NULL;
    else             mritmp = mask;
    if(infwhm > 0) {
      printf("Smoothing input by fwhm=%lf, gstd=%lf\n",infwhm,ingstd);
      MRImaskedGaussianSmooth(InVals, mritmp, ingstd, InVals);
    }
    if(infwhmc > 0 || infwhmr > 0 || infwhms > 0) {
      printf("Smoothing input by fwhm=(%lf,%lf,%lf) gstd=(%lf,%lf,%lf)\n",
	     infwhmc,infwhmr,infwhms,ingstdc,ingstdr,ingstds);
      MRIgaussianSmoothNI(InVals, ingstdc, ingstdr, ingstds, InVals);
    }
    printf("Saving to %s\n",outpath);
    MRIwrite(InVals,outpath);
    printf("SmoothOnly requested, so exiting now\n");
    exit(0);
  }

  // Make a copy, if needed, prior to doing anything to data
  if(outpath) InValsCopy = MRIcopy(InVals,NULL);

  // Compute variance reduction factor -------------------
  if(sum2file){
    ftmp = MRIsum2All(InVals);
    fp = fopen(sum2file,"w");
    if(fp == NULL){
      printf("ERROR: opening %s\n",sum2file);
      exit(1);
    }
    printf("sum2all: %20.10lf\n",ftmp);
    printf("vrf: %20.10lf\n",1/ftmp);
    fprintf(fp,"%20.10lf\n",ftmp);
    exit(0);
  }

  //------------------------ Detrend ------------------
  if(DetrendOrder >= 0) {
    Ntp = InVals->nframes;
    printf("Polynomial detrending, order = %d\n",DetrendOrder);
    X = MatrixAlloc(Ntp,DetrendOrder+1,MATRIX_REAL);
    for (n=0;n<Ntp;n++) X->rptr[n+1][1] = 1.0;
    ftmp = Ntp/2.0;
    if (DetrendOrder >= 1)
      for (n=0;n<Ntp;n++) X->rptr[n+1][2] = (n-ftmp)/ftmp;
    if (DetrendOrder >= 2)
      for (n=0;n<Ntp;n++) X->rptr[n+1][3] = pow((n-ftmp),2.0)/(ftmp*ftmp);
  }
  if(X){
    printf("Detrending\n");
    if (X->rows != InVals->nframes) {
      printf("ERROR: dimension mismatch between X and input\n");
      exit(1);
    }
    mritmp = fMRIdetrend(InVals,X);
    if (mritmp == NULL) exit(1);
    MRIfree(&InVals);
    InVals = mritmp;
  }

  // ------------ Smooth Input BY infwhm -------------------------
  if(infwhm > 0) {
    printf("Smoothing input by fwhm=%lf, gstd=%lf\n",infwhm,ingstd);
    MRImaskedGaussianSmooth(InVals, mask, ingstd, InVals);
  }
  // ------------ Smooth Input BY infwhm -------------------------
  if(infwhmc > 0 || infwhmr > 0 || infwhms > 0) {
    printf("Smoothing input by fwhm=(%lf,%lf,%lf) gstd=(%lf,%lf,%lf)\n",
	   infwhmc,infwhmr,infwhms,ingstdc,ingstdr,ingstds);
    MRIgaussianSmoothNI(InVals, ingstdc, ingstdr, ingstds, InVals);
  }

  // ------------ Smooth Input TO fwhm -------------------------
  if (tofwhm > 0) {
    printf("Attempting to smooth to %g +/- %g mm fwhm (nitersmax=%d)\n",
           tofwhm,tofwhmtol,tofwhmnitersmax);
    mritmp = MRImaskedGaussianSmoothTo(InVals, mask, tofwhm,
                                       tofwhmtol, tofwhmnitersmax,
                                       &byfwhm, &tofwhmact, &tofwhmniters,
                                       InVals);
    if (mritmp == NULL) exit(1);
    printf("Smoothed by %g to %g in %d iterations\n",
           byfwhm,tofwhmact,tofwhmniters);
    if (tofwhmfile) {
      fp = fopen(tofwhmfile,"w");
      if (!fp) {
        printf("ERROR: opening %s\n",tofwhmfile);
        exit(1);
      }
      fprintf(fp,"tofwhm    %lf\n",tofwhm);
      fprintf(fp,"tofwhmtol %lf\n",tofwhmtol);
      fprintf(fp,"tofwhmact %lf\n",tofwhmact);
      fprintf(fp,"byfwhm    %lf\n",byfwhm);
      fprintf(fp,"niters    %d\n",tofwhmniters);
      fprintf(fp,"nitersmax %d\n",tofwhmnitersmax);
      fclose(fp);
    }
  }

  // ------ Save smoothed/detrended ------------------------------
  if(outpath) {
    // This is a bit of a hack in order to be able to save undetrended
    // Operates on InValsCopy, which has not been modified (requires
    // smoothing twice, which is silly:).
    printf("Saving to %s\n",outpath);
    // Smoothed output will not be masked
    if (SaveDetrended && X) {
      mritmp = fMRIdetrend(InValsCopy,X);
      if (mritmp == NULL) exit(1);
      MRIfree(&InValsCopy);
      InValsCopy = mritmp;
    }
    if (SaveUnmasked) mritmp = NULL;
    else             mritmp = mask;
    if(infwhm > 0)
      MRImaskedGaussianSmooth(InValsCopy, mritmp, ingstd, InValsCopy);
    if(infwhmc > 0 || infwhmr > 0 || infwhms > 0) 
      MRIgaussianSmoothNI(InValsCopy, ingstdc, ingstdr, ingstds, InValsCopy);
    if(tofwhm > 0) {
      bygstd = byfwhm/sqrt(log(256.0));
      MRImaskedGaussianSmooth(InValsCopy, mritmp, bygstd, InValsCopy);
    }
    MRIwrite(InValsCopy,outpath);
    MRIfree(&InValsCopy);
  }


  // ----------- Compute smoothness -----------------------------
  printf("Computing spatial AR1 in volume.\n");
  ar1 = fMRIspatialAR1(InVals, mask, NULL);
  if (ar1 == NULL) exit(1);
  fMRIspatialAR1Mean(ar1, mask, &car1mn, &rar1mn, &sar1mn);

  cfwhm = RFar1ToFWHM(car1mn, InVals->xsize);
  rfwhm = RFar1ToFWHM(rar1mn, InVals->ysize);
  sfwhm = RFar1ToFWHM(sar1mn, InVals->zsize);
  fwhm = sqrt((cfwhm*cfwhm + rfwhm*rfwhm + sfwhm*sfwhm)/3.0);
  printf("ar1mn = (%lf,%lf,%lf)\n",car1mn,rar1mn,sar1mn);
  printf("colfwhm   = %lf\n",cfwhm);
  printf("rowfwhm   = %lf\n",rfwhm);
  printf("slicefwhm = %lf\n",sfwhm);
  printf("outfwhm = %lf\n",fwhm);

  reselvolume = cfwhm*rfwhm*sfwhm;
  nvoxperresel = reselvolume/voxelvolume;
  nresels = voxelvolume*nsearch/reselvolume;
  printf("reselvolume %lf\n",reselvolume);
  printf("nresels %lf\n",nresels);
  printf("nvoxperresel %lf\n",nvoxperresel);

  if(DoAR2){
    printf("Computing spatial AR2 in volume.\n");
    fMRIspatialAR2Mean(InVals, mask, &car2mn, &rar2mn, &sar2mn);
    printf("ar2mn = (%lf,%lf,%lf)\n",car2mn,rar2mn,sar2mn);
  }

  if(ar1path) MRIwrite(ar1,ar1path);

  fflush(stdout);

  // ---------- Save summary file ---------------------
  if(sumfile) {
    fp = fopen(sumfile,"w");
    if (fp == NULL) {
      printf("ERROR: opening %s\n",sumfile);
      exit(1);
    }
    dump_options(fp);
    fprintf(fp,"nsearch2        %d\n",nsearch2);
    fprintf(fp,"searchspace_vox %d\n",nsearch);
    fprintf(fp,"searchspace_mm3 %lf\n",nsearch*voxelvolume);
    fprintf(fp,"voxelvolume_mm3 %g\n",voxelvolume);
    fprintf(fp,"voxelsize_mm %g %g %g\n",InVals->xsize,InVals->ysize,InVals->zsize);
    fprintf(fp,"ar1mn  %lf %lf %lf\n",car1mn,rar1mn,sar1mn);
    fprintf(fp,"colfwhm_mm      %lf\n",cfwhm);
    fprintf(fp,"rowfwhm_mm      %lf\n",rfwhm);
    fprintf(fp,"slicefwhm_mm    %lf\n",sfwhm);
    fprintf(fp,"outfwhm_mm      %lf\n",fwhm);
    fprintf(fp,"reselvolume_mm3 %lf\n",reselvolume);
    fprintf(fp,"nresels         %lf\n",nresels);
    fprintf(fp,"nvox_per_resel  %lf\n",nvoxperresel);
    fclose(fp);
  }

  if(datfile) {
    fp = fopen(datfile,"w");
    if(fp == NULL) {
      printf("ERROR: opening %s\n",datfile);
      exit(1);
    }
    fprintf(fp,"%lf\n",fwhm);
    fclose(fp);
  }


  printf("mri_fwhm done\n");

  return 0;
}
예제 #2
0
/*-------------------------------------------------------------*/
int main(int argc, char *argv[])
{
  /* check for and handle version tag */
  int nargs = handle_version_option
              (argc, argv,
               "$Id: mri_gcut.cpp,v 1.14 2011/03/02 00:04:16 nicks Exp $",
               "$Name: stable5 $");
  if (nargs && argc - nargs == 1)
  {
    exit (0);
  }
  argc -= nargs;

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

  parse_commandline(argc, argv);

  MRI *mri, *mri2, *mri3, *mri_mask=NULL;
  mri3  = MRIread(in_filename);
  if ( mri3 == NULL )
  {
    printf("can't read file %s\nexit!\n", in_filename);
    exit(0);
  }
  mri   = MRISeqchangeType(mri3, MRI_UCHAR, 0.0, 0.999, FALSE);
  mri2  = MRISeqchangeType(mri3, MRI_UCHAR, 0.0, 0.999, FALSE);
  //MRI* mri4 = MRIread("gcutted.mgz");

  if (bNeedMasking == 1)
  {
    printf("reading mask...\n");
    mri_mask = MRIread(mask_filename);
    if ( mri_mask == NULL )
    {
      printf("can't read %s, omit -mult option!\n", mask_filename);
      print_help();
      exit(1);
    }
    else
    {
      if ( mri_mask->width != mri->width ||
           mri_mask->height != mri->height ||
           mri_mask->depth != mri->depth )
      {
        printf("Two masks are of different size, omit -mult option!\n");
        print_help();
        exit(1);
      }
    }
  }

  int w = mri->width;
  int h = mri->height;
  int d = mri->depth;

  // -- copy of mri matrix
  unsigned char ***label;
  label = new unsigned char**[d];
  for (int i = 0; i < d; i++)
  {
    label[i] = new unsigned char*[h];
    for (int j = 0; j < h; j++)
    {
      label[i][j] = new unsigned char[w];
      for (int k = 0; k < w; k++)
      {
        label[i][j][k] = 0;
      }
    }
  }
  // -- gcut image
  int ***im_gcut;
  im_gcut = new int**[d];
  for (int i = 0; i < d; i++)
  {
    im_gcut[i] = new int*[h];
    for (int j = 0; j < h; j++)
    {
      im_gcut[i][j] = new int[w];
      for (int k = 0; k < w; k++)
      {
        im_gcut[i][j][k] = 0;
      }
    }
  }
  // -- diluted
  int ***im_diluteerode;
  im_diluteerode = new int**[d];
  for (int i = 0; i < d; i++)
  {
    im_diluteerode[i] = new int*[h];
    for (int j = 0; j < h; j++)
    {
      im_diluteerode[i][j] = new int[w];
      for (int k = 0; k < w; k++)
      {
        im_diluteerode[i][j][k] = 0;
      }
    }
  }
  //int w, h, d;
  //int x, y, z;
  double whitemean;
  if (bNeedPreprocessing == 0)
  {
    // pre-processed: 110 intensity voxels are the WM
    if (LCC_function(mri ->slices,
                     label,
                     mri->width,
                     mri->height,
                     mri->depth,
                     whitemean) == 1)
    {
      if ( whitemean < 0 )
      {
        printf("whitemean < 0 error!\n");
        exit(0);
      }
    }
    else
    {
      whitemean = 110;
      printf("use voxels with intensity 110 as WM mask\n");
    }
  }
  else
  {
    printf("estimating WM mask\n");
    whitemean = pre_processing(mri ->slices,
                               label,
                               mri->width,
                               mri->height,
                               mri->depth);
    if ( whitemean < 0 )
    {
      printf("whitemean < 0 error!\n");
      exit(0);
    }
  }
  double threshold = whitemean * _t;
  printf("threshold set to: %f*%f=%f\n", whitemean, _t, threshold);

  for (int z = 0 ; z < mri->depth ; z++)
  {
    for (int y = 0 ; y < mri->height ; y++)
    {
      for (int x = 0 ; x < mri->width ; x++)
      {
        if ( mri->slices[z][y][x] < threshold + 1 )
        {
          mri->slices[z][y][x] = 0;
        }
      }
    }//end of for
  }

  //new code
  int ***foregroundseedwt;
  int ***backgroundseedwt;
  matrix_alloc(&foregroundseedwt, d, h, w);
  matrix_alloc(&backgroundseedwt, d, h, w);

  double kval = 2.3;
  graphcut(mri->slices, label, im_gcut,
           foregroundseedwt, backgroundseedwt,
           w, h, d, kval, threshold, whitemean);
  printf("g-cut done!\npost-processing...\n");
  //printf("_test: %f\n", _test);

  post_processing(mri2->slices,
                  mri->slices,
                  threshold,
                  im_gcut,
                  im_diluteerode,
                  w, h, d);
  printf("post-processing done!\n");

  if (bNeedMasking == 1)//masking
  {
    printf("masking...\n");
    for (int z = 0 ; z < mri_mask->depth ; z++)
    {
      for (int y = 0 ; y < mri_mask->height ; y++)
      {
        for (int x = 0 ; x < mri_mask->width ; x++)
        {
          if ( mri_mask->slices[z][y][x] == 0 )
          {
            im_diluteerode[z][y][x] = 0;
          }
        }
      }
    }
  }

  //if the output might have some problem
  int numGcut = 0, numMask = 0;
  double _ratio = 0;
  int error_Hurestic = 0;
  if (bNeedMasking == 1)//-110 and masking are both set
  {
    for (int z = 0 ; z < mri_mask->depth ; z++)
    {
      for (int y = 0 ; y < mri_mask->height ; y++)
      {
        for (int x = 0 ; x < mri_mask->width ; x++)
        {
          if ( im_diluteerode[z][y][x] != 0 )
          {
            numGcut++;
          }
          if ( mri_mask->slices[z][y][x] != 0 )
          {
            numMask++;
          }
        }
      }
    }
    _ratio = (double)numGcut / numMask;
    if (_ratio <= 0.85)
    {
      error_Hurestic = 1;
    }
  }

  if (error_Hurestic == 1)
  {
    printf("** Gcutted brain is much smaller than the mask!\n");
    printf("** Using the mask as the output instead!\n");
    //printf("** Gcutted output is written as: 'error_gcutted_sample'\n");
  }

  for (int z = 0 ; z < mri->depth ; z++)
  {
    for (int y = 0 ; y < mri->height ; y++)
    {
      for (int x = 0 ; x < mri->width ; x++)
      {
        if (error_Hurestic == 0)
        {
          if ( im_diluteerode[z][y][x] == 0 )
          {
            mri2 ->slices[z][y][x] = 0;
          }
        }
        else
        {
          if ( mri_mask->slices[z][y][x] == 0 )
          {
            mri2 ->slices[z][y][x] = 0;
          }
          //if( im_diluteerode[z][y][x] == 0 )
          //mri ->slices[z][y][x] = 0;
        }
      }
    }//end of for 2
  }//end of for 1

  MRIwrite(mri2, out_filename);

  // if user supplied a filename to which to write diffs, then write-out
  // volume file containing where cuts were made (for debug)
  if (diff_filename[0] && (error_Hurestic != 1))
  {
    MRI *mri_diff = MRISeqchangeType(mri3, MRI_UCHAR, 0.0, 0.999, FALSE);
    for (int z = 0 ; z < mri3->depth ; z++)
    {
      for (int y = 0 ; y < mri3->height ; y++)
      {
        for (int x = 0 ; x < mri3->width ; x++)
        {
          if (mri_mask)
          {
            mri_diff->slices[z][y][x] =
              mri2->slices[z][y][x] - mri_mask->slices[z][y][x];
          }
          else
          {
            mri_diff->slices[z][y][x] =
              mri2->slices[z][y][x] - mri3->slices[z][y][x];
          }
        }
      }//end of for 2
    }//end of for 1
    MRIwrite(mri_diff, diff_filename);
    MRIfree(&mri_diff);
  }

  if (mri)
  {
    MRIfree(&mri);
  }
  if (mri2)
  {
    MRIfree(&mri2);
  }
  if (mri3)
  {
    MRIfree(&mri3);
  }
  if (mri_mask)
  {
    MRIfree(&mri_mask);
  }
  for (int i = 0; i < d; i++)
  {
    for (int j = 0; j < h; j++)
    {
      delete[] im_diluteerode[i][j];
      delete[] im_gcut[i][j];
      delete[] label[i][j];
    }
    delete[] im_diluteerode[i];
    delete[] im_gcut[i];
    delete[] label[i];
  }
  delete[] im_diluteerode;
  delete[] im_gcut;
  delete[] label;

  return 0;
}