Ejemplo n.º 1
0
MRI *
MRIScomputeDistanceMap(MRI_SURFACE *mris, MRI *mri_distance, int ref_vertex_no)
{
  int    vno ;
  VERTEX *v ;
  double circumference, angle, distance ;
  VECTOR *v1, *v2 ;

  if (mri_distance == NULL)
    mri_distance = MRIalloc(mris->nvertices, 1, 1, MRI_FLOAT) ;

  v1 = VectorAlloc(3, MATRIX_REAL) ; v2 = VectorAlloc(3, MATRIX_REAL) ;
  v = &mris->vertices[ref_vertex_no] ;
  VECTOR_LOAD(v1, v->x, v->y, v->z) ;  /* radius vector */
  circumference = M_PI * 2.0 * V3_LEN(v1) ;
  for (vno = 0 ; vno < mris->nvertices ; vno++)
  {
    v = &mris->vertices[vno] ;
    if (vno == Gdiag_no)
      DiagBreak() ;
    VECTOR_LOAD(v2, v->x, v->y, v->z) ;  /* radius vector */
    angle = fabs(Vector3Angle(v1, v2)) ;
    distance = circumference * angle / (2.0 * M_PI) ;
    MRIsetVoxVal(mri_distance, vno, 0, 0, 0, distance) ;
  }

  VectorFree(&v1) ; VectorFree(&v2) ;
  return(mri_distance) ;
}
Ejemplo n.º 2
0
static MRI *
make_atrophy_map(MRI *mri_time1, MRI *mri_time2, MRI *mri_dst, TRANSFORM *transform1, TRANSFORM *transform2,
                 int *gray_labels, int ngray, int *csf_labels, int ncsf) {
  int            x, y, z, label1, label2, n, found, xp, yp, zp, spacing ;
  GCA_MORPH_NODE *gcamn1, *gcamn2 ;
  GCA_MORPH      *gcam1, *gcam2 ;
  float           volume ;

  if (mri_dst == NULL) {
    mri_dst = MRIalloc(mri_time1->width, mri_time1->height, mri_time1->depth, MRI_FLOAT) ;
    MRIcopyHeader(mri_time1, mri_dst) ;
  }

  gcam1 = (GCA_MORPH*)transform1->xform ;
  gcam2 = (GCA_MORPH*)transform2->xform ;
  spacing = gcam1->spacing ;

  for (x = 0 ; x < mri_time1->width ; x++) {
    xp = x / spacing;
    for (y = 0 ; y < mri_time1->height ; y++) {
      yp = y / spacing;
      for (z = 0 ; z < mri_time1->depth ; z++) {
        if (x == Gx && y == Gy && z == Gz)
          DiagBreak() ;
        label1 = MRIgetVoxVal(mri_time1, x, y, z, 0) ;
        label2 = MRIgetVoxVal(mri_time2, x, y, z, 0) ;
        if (label1 == label2)
          continue ;

        /* if label1 was one of the gray types and label2 one of the csf, call it atrophy */
        for (found = n = 0 ; n < ngray ; n++)
          if (label1 == gray_labels[n]) {
            found = 1 ;
            break ;
          }
        if (found == 0)
          continue ;
        for (found = n = 0 ; n < ncsf ; n++)
          if (label2 == csf_labels[n]) {
            found = 1 ;
            break ;
          }
        if (found == 0)
          continue ;
        zp = z / spacing;
        gcamn1 = &gcam1->nodes[xp][yp][zp] ;
        gcamn2 = &gcam2->nodes[xp][yp][zp] ;
        volume = 0 ;
        if (FZERO(gcamn1->area) == 0)
          volume += gcamn1->orig_area / gcamn1->area ;
        if (FZERO(gcamn2->area) == 0)
          volume += gcamn2->orig_area / gcamn2->area ;
        MRIsetVoxVal(mri_dst, x, y, z, 0, volume) ;
      }
    }
  }


  return(mri_dst) ;
}
Ejemplo n.º 3
0
static MRI *
compute_bias(MRI *mri_src, MRI *mri_dst, MRI *mri_bias)
{
  int x, y, z ;
  float bias, src, dst ;

  if (!mri_bias)
    mri_bias = MRIalloc
               (mri_src->width, mri_src->height, mri_src->depth, MRI_FLOAT) ;

  MRIcopyHeader(mri_src, mri_bias) ;
  for (x = 0 ; x < mri_src->width ; x++)
  {
    for (y = 0; y < mri_src->height ; y++)
    {
      for (z = 0 ; z < mri_src->depth ; z++)
      {
        src = MRIgetVoxVal(mri_src, x, y, z, 0) ;
        dst = MRIgetVoxVal(mri_dst, x, y, z, 0) ;
        if (FZERO(src))
        {
          bias = 1 ;
        }
        else
        {
          bias = dst/src ;
        }
        MRIsetVoxVal(mri_bias, x, y, z, 0, bias) ;
      }
    }
  }

  return(mri_bias) ;
}
Ejemplo n.º 4
0
static MRI *
MRIupdatePriors(MRI *mri_binary, MRI *mri_priors) {
  int     width, height, depth, x, y, z ;
  BUFTYPE *pbin ;
  float   prob ;

  width = mri_binary->width ;
  height = mri_binary->height ;
  depth = mri_binary->depth ;
  if (!mri_priors) {
    mri_priors = MRIalloc(width, height, depth, MRI_FLOAT) ;
  }

  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      pbin = &MRIvox(mri_binary, 0, y, z) ;
      for (x = 0 ; x < width ; x++) {
        if (x == DEBUG_X && y == DEBUG_Y && z == DEBUG_Z)
          DiagBreak() ;
        prob = *pbin++ / 100.0f ;
        MRIFvox(mri_priors, x, y, z) += prob ;
      }
    }
  }
  return(mri_priors) ;
}
Ejemplo n.º 5
0
static MRI *
MRIcomputePriors(MRI *mri_priors, int ndof, MRI *mri_char_priors) {
  int     width, height, depth, x, y, z ;
  BUFTYPE *pchar_prior, char_prior ;
  float   *pprior, prior ;

  width = mri_priors->width ;
  height = mri_priors->height ;
  depth = mri_priors->depth ;
  if (!mri_char_priors) {
    mri_char_priors = MRIalloc(width, height, depth, MRI_UCHAR) ;
  }

  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      pprior = &MRIFvox(mri_priors, 0, y, z) ;
      pchar_prior = &MRIvox(mri_char_priors, 0, y, z) ;
      for (x = 0 ; x < width ; x++) {
        if (x == DEBUG_X && y == DEBUG_Y && z == DEBUG_Z)
          DiagBreak() ;
        prior = *pprior++ ;
        if (prior > 0)
          DiagBreak() ;
        if (prior > 10)
          DiagBreak() ;
        char_prior = (BUFTYPE)nint(100.0f*prior/(float)ndof) ;
        if (char_prior > 101)
          DiagBreak() ;
        *pchar_prior++ = char_prior ;
      }
    }
  }
  return(mri_char_priors) ;
}
MRI *
MRIsadd(MRI *mri1, MRI *mri2, MRI *mri_dst) {
  int     width, height, depth, x, y, z ;
  short   *p1, *p2, *pdst ;

  width = mri1->width ;
  height = mri1->height ;
  depth = mri1->depth ;

  if (!mri_dst) {
    mri_dst = MRIalloc(width, height, depth, mri1->type) ;
    MRIcopyHeader(mri1, mri_dst) ;
  }

  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      p1 = &MRISvox(mri1, 0, y, z) ;
      p2 = &MRISvox(mri2, 0, y, z) ;
      pdst = &MRISvox(mri_dst, 0, y, z) ;
      for (x = 0 ; x < width ; x++)
        *pdst++ = *p1++ + *p2++ ;
    }
  }
  return(mri_dst) ;
}
Ejemplo n.º 7
0
static int
write_snapshot(MRI *mri_target, MRI *mri_source, MATRIX *m_vox_xform, 
	       GCA_MORPH_PARMS *parms, int fno, int conform, char *in_fname)
{
  MRI *mri_aligned ;
  char fname[STRLEN] ;

  if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
    {
      printf("source->target vox->vox transform:\n") ;
      MatrixPrint(stdout, m_vox_xform) ;
    }
  if (conform || 1)
    {
      mri_aligned = MRIalloc(mri_target->width, mri_target->height,
			     mri_target->depth,mri_source->type);
      MRIcopyHeader(mri_target, mri_aligned) ;
      MRIlinearTransformInterp(mri_source, mri_aligned, m_vox_xform, SAMPLE_NEAREST);
    }
  else
    {
      mri_aligned = MRITransformedCenteredMatrix(mri_source, mri_target, m_vox_xform) ;
    }
  if (in_fname)
    sprintf(fname, "%s_%s", parms->base_name, in_fname) ;
  else
    sprintf(fname, "%s_%03d", parms->base_name, fno) ;
  MRIwriteImageViews(mri_aligned, fname, IMAGE_SIZE) ;
  if (in_fname)
    sprintf(fname, "%s_%s.mgz", parms->base_name, in_fname) ;
  else
    sprintf(fname, "%s_%03d.mgz", parms->base_name, fno) ;
  printf("writing snapshot to %s...\n", fname) ;
  MRIwrite(mri_aligned, fname) ;
  MRIfree(&mri_aligned) ;

  {
#if 0
    mri_aligned = MRIsrcTransformedCentered(mri_source, mri_target, m_vox_xform,
					    SAMPLE_NEAREST) ;
#else
    mri_aligned = MRITransformedCenteredMatrix(mri_source, mri_target, m_vox_xform) ;
#endif
    if (in_fname)
      sprintf(fname, "orig_%s_%s.mgz", parms->base_name, in_fname) ;
    else
      sprintf(fname, "orig_%s_%03d.mgz", parms->base_name, fno) ;
    printf("writing snapshot to %s...\n", fname) ;
    MRIwrite(mri_aligned, fname) ;
    MRIfree(&mri_aligned) ;
  }

  return(NO_ERROR) ;
}
Ejemplo n.º 8
0
MRI *
MRIcomputeConditionalProbabilities(MRI *mri_T1, MRI *mri_mean,
                                   MRI *mri_std, MRI *mri_dst)
{
    int       x, y, z, width, height, depth ;
    BUFTYPE   *pT1, *pmean, *pstd ;
    float     p, mean, std, val, n, *pdst ;


    width = mri_T1->width ;
    height = mri_T1->height ;
    depth = mri_T1->depth ;

    if (!mri_dst)
        mri_dst = MRIalloc(width, height, depth, MRI_FLOAT) ;

    for (z = 0 ; z < depth ; z++)
    {
        for (y = 0 ; y < height ; y++)
        {
            pT1 = &MRIvox(mri_T1, 0, y, z) ;
            pmean = &MRIvox(mri_mean, 0, y, z) ;
            pstd = &MRIvox(mri_std, 0, y, z) ;
            pdst = &MRIFvox(mri_dst, 0, y, z) ;
            for (x = 0 ; x < width ; x++)
            {
                if (DEBUG_POINT(x,y,z))
                    DiagBreak() ;
                val = (float)*pT1++ ;
                mean = (float)*pmean++ ;
                std = (float)*pstd++ ;
                if (FZERO(std))
                    std = 1.0 ;
#if 0
                if (std < 10.0)  /* hack!!!!! - not enough observations */
                    std = 10.0 ;
#endif
                n = 1 / (std * sqrt(2.0*M_PI)) ;
                p = n * exp(-SQR(val - mean) / (2.0f*SQR(std))) ;
                *pdst++ = p*100.0f ;
            }
        }
    }
    return(mri_dst) ;
}
Ejemplo n.º 9
0
int main(int argc, char *argv[]) {
  MRI *mri;
  Progname=argv[0];
  printf("Generating test_volume.mgz...\n");

  mri=MRIalloc(20,20,20,MRI_UCHAR);

  MRIvox(mri,10,10,10)=255;
  MRIvox(mri,11,10,10)=255;
  MRIvox(mri,11,11,10)=255;
  MRIvox(mri,11,11,11)=255;
  MRIvox(mri,10,11,11)=255;
  MRIvox(mri,10,10,11)=255;

  MRIwrite(mri,"test_volume.mgz");

  return 0;
}
Ejemplo n.º 10
0
MRI *
MRIbinarizeEditting(MRI *mri_src, MRI *mri_dst) {
  int     width, height, depth, x, y, z, val ;
  BUFTYPE *

  width = mri_src->width ;
  height = mri_src->height ;
  depth = mri_src->depth ;
  mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ;
  if (!mri_dst)
    mri_dst = MRIclone(mri_src, NULL) ;

  MRIvalRange(mri_src, &fmin, &fmax) ;
  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {}
    }
  }

  return(mri_dst) ;
}
Ejemplo n.º 11
0
MRI *
MRIfloatToChar(MRI *mri_src, MRI *mri_dst) {
  int   width, height, depth/*, x, y, z, out_val*/ ;
  /*  float fmax, fmin ;*/

  width = mri_src->width ;
  height = mri_src->height ;
  depth = mri_src->depth ;
  if (!mri_dst)
    mri_dst = MRIalloc(width, height, depth, MRI_UCHAR) ;
#if 1
  MRIcopy(mri_src, mri_dst) ;
#else
  MRIvalRange(mri_src, &fmin, &fmax) ;
  for (z = 0 ; z < depth ; z++) {
    for (y = 0 ; y < height ; y++) {
      for (x = 0 ; x < width ; x++) {}
    }
  }
#endif
  return(mri_dst) ;
}
MRI *  
correct_gmwm_boundaries_2(MRI *segmri, MRI *outmri)
{
  int x, y, z, width, height, depth = 0;
  double val;
  MRI *allvol = NULL;
  MRI *allmaskdist, *label2, *label2distmap, *label41, *label41distmap = NULL;

  width  = segmri->width ;
  height = segmri->height ;
  depth  = segmri->depth ;

  // all lables
  allvol = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val > 0)
	    MRIsetVoxVal(allvol,x,y,z,0,1);
	}
  allmaskdist = MRIalloc(width, height, depth, MRI_FLOAT);
  allmaskdist = MRIextractDistanceMap(allvol, allmaskdist, 1, 3, 3, NULL);

  // label 2
  label2 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 2)
	    MRIsetVoxVal(label2,x,y,z,0,1);
	}
  label2distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label2distmap = MRIextractDistanceMap(label2, label2distmap, 1, 3, 3, NULL);

  // label 41
  label41 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 41)
	    MRIsetVoxVal(label41,x,y,z,0,1);
	}
  label41distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label41distmap = MRIextractDistanceMap(label41, label41distmap, 1, 3, 3, NULL);

  if (!outmri)
    outmri = MRIclone(segmri, NULL) ;

  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  if(MRIgetVoxVal(allvol,x,y,z,0) == 1)
	    {
	      if((fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= .5) && (MRIgetVoxVal(label41distmap,x,y,z,0) <=0 ))
		MRIsetVoxVal(outmri,x,y,z,0,42);
	      else
		if((fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= .5) && (MRIgetVoxVal(label2distmap,x,y,z,0) <=0 ))
		  MRIsetVoxVal(outmri,x,y,z,0,3);
	    }
	}
  
  return(outmri) ;
}
Ejemplo n.º 13
0
int main(int argc, char *argv[]) {
  tesselation_parms *parms;
  MRIS **mris_table, *mris,*mris_corrected;
  MRI *mri;

  char cmdline[CMD_LINE_LEN] ;

  make_cmd_version_string 
    (argc, argv, 
     "$Id: mri_mc.c,v 1.22 2011/03/02 00:04:23 nicks Exp $", "$Name: stable5 $", 
     cmdline);
  Progname=argv[0];

  if (argc > 1 && (stricmp(argv[1], "-d") == 0)) {
    downsample = atoi(argv[2]) ;
    argc -= 2;
    argv += 2 ;
    printf("downsampling input volume %d times\n", downsample) ;
  }

  if (argc < 4) {
    fprintf(stderr,"\n\nUSAGE: mri_mc input_volume "
            "label_value output_surface [connectivity]");
    fprintf(stderr,
            "\noption connectivity: 1=6+,2=18,3=6,4=26 (default=1)\n\n");
    exit(-1);
  }

  parms=(tesselation_parms*)calloc(1,sizeof(tesselation_parms));
  if (!parms)
    ErrorExit(ERROR_NOMEMORY, "tesselation parms\n") ;
  mri=MRIread(argv[1]);
  if (downsample > 0) {
    MRI *mri_tmp ;
    mri_tmp = MRIdownsample2(mri, NULL) ;
    MRIfree(&mri) ;
    mri = mri_tmp ;
  }
  {
    MRI *mri_tmp ;
    mri_tmp = MRIalloc(mri->width+2, mri->height+2, mri->depth+2, mri->type) ;
    MRIextractInto(mri, mri_tmp, 
                   0, 0, 0, 
                   mri->width, mri->height, mri->depth, 
                   1, 1, 1) ;
    MRIfree(&mri) ;
    mri = mri_tmp ;
  }
  MRIreInitCache(mri);
  if (mri->type != MRI_UCHAR) {
    MRI *mri_tmp ;
    float min_val, max_val ;

    MRIvalRange(mri, &min_val, &max_val) ;
    if (min_val < 0 || max_val > 255)
      ErrorExit
        (ERROR_UNSUPPORTED, 
         "%s: input volume (val range [%2.1f %2.1f]) must be "
         "convertible to UCHAR",
         Progname, min_val, max_val) ;
    printf("changing type of input volume to 8 bits/voxel...\n") ;
    mri_tmp = MRIchangeType(mri, MRI_UCHAR, 0.0, 0.999, TRUE) ;
    MRIfree(&mri) ;
    mri = mri_tmp ;
  }

  parms->mri=mri;

  parms->number_of_labels=1; //only one single label
  parms->label_values=(int*)malloc(sizeof(int));
  parms->label_values[0]=atoi(argv[2]);//label;
  parms->ind=0;
  mris_table=(MRIS**)malloc(sizeof(MRIS*)); //final surface information
  parms->mris_table=mris_table;
  if ((!parms->label_values) || (!mris_table))
    ErrorExit(ERROR_NOMEMORY, "labels/surfaces tables\n") ;

  if (argc==5) parms->connectivity=atoi(argv[4]);//connectivity;
  else parms->connectivity=1;

  initTesselationParms(parms);

  generateMCtesselation(parms);

  free(parms->label_values);
  mris=parms->mris_table[0];
  free(parms->mris_table);
  freeTesselationParms(&parms);

  {
    float dist,max_e=0.0;
    int n,p,vn0,vn2;
    VERTEX *v,*vp;
    fprintf(stderr,"computing the maximum edge length...");
    for (n = 0 ; n < mris->nvertices ; n++) {
      v=&mris->vertices[n];
      for (p = 0 ; p < v->vnum ; p++) {
        vp = &mris->vertices[v->v[p]];
        dist=SQR(vp->x-v->x)+SQR(vp->y-v->y)+SQR(vp->z-v->z);
        if (dist>max_e) max_e=dist;
      }
    }
    fprintf(stderr,"%f mm",sqrt(max_e));
    fprintf(stderr,"\nreversing orientation of faces...");
    for (n = 0 ; n < mris->nfaces ; n++) {
      vn0=mris->faces[n].v[0];
      vn2=mris->faces[n].v[2];
      /* vertex 0 becomes vertex 2 */
      v=&mris->vertices[vn0];
      for (p = 0 ; p < v->num ; p++)
        if (v->f[p]==n)
          v->n[p]=2;
      mris->faces[n].v[2]=vn0;
      /* vertex 2 becomes vertex 0 */
      v=&mris->vertices[vn2];
      for (p = 0 ; p < v->num ; p++)
        if (v->f[p]==n)
          v->n[p]=0;
      mris->faces[n].v[0]=vn2;
    }
  }

  fprintf(stderr,"\nchecking orientation of surface...");
  MRISmarkOrientationChanges(mris);
  mris_corrected=MRISextractMainComponent(mris,0,1,0);

  MRISfree(&mris);

  fprintf(stderr,"\nwriting out surface...");
  MRISaddCommandLine(mris_corrected, cmdline) ;
  if (mriConformed(mri) == 0) {
    printf("input volume is not conformed - using useRealRAS=1\n") ;
    mris_corrected->useRealRAS = 1 ;
  }
  //  getVolGeom(mri, &mris_corrected->vg);
  MRISwrite(mris_corrected,argv[3]);
  fprintf(stderr,"done\n");

  MRIfree(&mri);
  MRISfree(&mris_corrected);

  return 0;
}
Ejemplo n.º 14
0
int
main(int argc, char *argv[])
{
  char        **av, *in_fname, *out_fname ;
  int         ac, nargs, i, label ;
  MRI         *mri_in, *mri_out, *mri_kernel, *mri_smoothed ;

  /* rkt: check for and handle version tag */
  nargs = handle_version_option
          (argc, argv,
           "$Id: mri_extract_label.c,v 1.13 2011/03/02 00:04:15 nicks 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)
    usage_exit() ;

  in_fname = argv[1] ;
  out_fname = argv[argc-1] ;

  printf("reading volume from %s...\n", in_fname) ;
  mri_in = MRIread(in_fname) ;
  if (!mri_in)
    ErrorExit(ERROR_NOFILE, "%s: could not read MRI volume %s", Progname,
              in_fname) ;
  if (out_like_fname)
  {
    MRI *mri_tmp = MRIread(out_like_fname) ;
    if (!mri_tmp)
      ErrorExit
      (ERROR_NOFILE,
       "%s: could not read template volume from %s",
       out_like_fname) ;
    mri_out = MRIalloc(mri_tmp->width,
                       mri_tmp->height,
                       mri_tmp->depth,
                       mri_tmp->type) ;
    /*    MRIcopyHeader(mri_tmp, mri_out) ;*/
    MRIfree(&mri_tmp) ;
  }
  else
    mri_out = MRIclone(mri_in, NULL) ;

  for (i = 2 ; i < argc-1 ; i++)
  {
    label = atoi(argv[i]) ;
    printf("extracting label %d (%s)\n", label, cma_label_to_name(label)) ;
    extract_labeled_image(mri_in, transform, label, mri_out) ;
  }
  if (!FZERO(sigma))
  {
    printf("smoothing extracted volume...\n") ;
    mri_kernel = MRIgaussian1d(sigma, 10*sigma) ;
    mri_smoothed = MRIconvolveGaussian(mri_out, NULL, mri_kernel) ;
    MRIfree(&mri_out) ;
    mri_out = mri_smoothed ;
  }
  /* removed for gcc3.3
   * vsprintf(out_fname, out_fname, (va_list) &label) ;
   */
  if (dilate > 0)
  {
    int i ;
    printf("dilating output volume %d times...\n", dilate) ;
    for (i = 0 ; i < dilate ; i++)
      MRIdilate(mri_out, mri_out) ;
  }
  if (erode > 0)
  {
    int i ;
    printf("eroding output volume %d times...\n", erode) ;
    for (i = 0 ; i < erode ; i++)
      MRIerode(mri_out, mri_out) ;
  }
  printf("writing output to %s.\n", out_fname) ;
  MRIwrite(mri_out, out_fname) ;

  if (exit_none_found && (nvoxels == 0))
  {
    printf("No voxels with specified label were found!\n");
    exit(1);
  }

  exit(0) ;
  return(0) ;  /* for ansi */
}
Ejemplo n.º 15
0
MRI *
MRIflattenOverlay(MRI_SURFACE *mris, MRI *mri_overlay, MRI *mri_flat, double res, LABEL *label_overlay,
                  MRI **pmri_vertices)
{
  double   xmin, ymin, xmax, ymax, fdist, lambda[3], xf, yf, val0, val1, val2, val ;
  int      width, height, x, y, fno, ret, z ;
  MHT      *mht ;
  FACE     *face;
  MRI      *mri_vertices ;

  find_biggest_inscribed_rectangle(mris, &xmin, &ymin, &xmax, &ymax) ;
  width = (int)ceil((xmax-xmin)/res) ; width = (int)(floor(width/2.0)*2.0+1) ;   xmax=xmin+width;
  height = (int)ceil((ymax-ymin)/res) ;height = (int)(floor(height/2.0)*2.0+1) ; ymax=ymin+height;

  // 1st frame is correlations and 2nd is vertex #
  mri_vertices = MRIalloc(width, height, 1, MRI_FLOAT) ;
  MRIsetValues(mri_vertices, -1) ;
  mri_flat = MRIalloc(width, height, mri_overlay->nframes, MRI_FLOAT) ;
  mri_vertices->xstart = mri_flat->xstart = xmin ; mri_vertices->xend = mri_flat->xend = xmax ;
  mri_vertices->ystart = mri_flat->ystart = ymin ; mri_vertices->yend = mri_flat->yend = ymax ;
  mri_vertices->zstart = mri_flat->zstart = 0 ; 
  mri_vertices->zend = mri_flat->zend = mri_overlay->nframes-1 ;
  mri_vertices->c_r = mri_flat->c_r = xmin ;  mri_vertices->c_a = mri_flat->c_a = ymin ; 
  mri_vertices->c_s = mri_flat->c_s = 0 ;
  MRIsetResolution(mri_flat, res, res, 1) ;
  MRIsetResolution(mri_vertices, res, res, 1) ;
  if (label_overlay)  // constrain processing to only this label
    LabelRipRestOfSurface(label_overlay, mris) ;
  mht = MHTfillTableAtResolution(mris, NULL, CURRENT_VERTICES, 1.0) ;
  for (x = 0 ; x < width; x++)
    for (y = 0 ; y < height ; y++)
    {
      xf = x*res + xmin ;  yf = y*res + ymin ;   // back to flattened coords
      MHTfindClosestFaceGeneric(mht, mris, xf, yf, 0.0, 10*res, 2, 1, &face, &fno, &fdist) ;
      if (fno >= 0)  // otherwise this point is not in a face
      {
        ret = face_barycentric_coords(mris, fno, CURRENT_VERTICES, xf, yf, 0, &lambda[0], &lambda[1],&lambda[2]); 
        if (ret >= 0)
        {
          if (lambda[0] > lambda[1])
          {
            if (lambda[0] > lambda[2])
            {
              if (face->v[0] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[0]) ;
            }
            else
            {
              if (face->v[2] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[2]) ;
            }
          }
          else
          {
            if (lambda[1] > lambda[2])
            {
              if (face->v[1] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[1]) ;
            }
            else
            {
              if (face->v[2] == Gdiag_no)
                DiagBreak() ;
              MRIsetVoxVal(mri_vertices, x, y, 0, 0, face->v[2]) ;
            }
          }

          for (z = 0 ;z < mri_flat->depth ; z++)
          {
            val0 = MRIgetVoxVal(mri_overlay, face->v[0], 0, 0, z) ;
            val1 = MRIgetVoxVal(mri_overlay, face->v[1], 0, 0, z) ;
            val2 = MRIgetVoxVal(mri_overlay, face->v[2], 0, 0, z) ;
            val = lambda[0]*val0 + lambda[1]*val1 + lambda[2]*val2 ;
            MRIsetVoxVal(mri_flat, x, y, z, 0, val) ;
          }
        }
        else if (fabs(xf) < 10 && fabs(yf) < 10)
        {
          MHTfindClosestFaceGeneric(mht, mris, xf, yf, 0.0, 1000, -1, 1, &face, &fno, &fdist) ;
          printf("(%d, %d) --> %f %f unmapped (goes to face %d, v (%d, %d, %d) if projected\n",
                 x, y, xf, yf, fno, face->v[0], face->v[1], face->v[2]) ;
          DiagBreak() ;
        }
      }
    }

  if (pmri_vertices)
    *pmri_vertices = mri_vertices ;
  MHTfree(&mht) ;
  return(mri_flat) ;
}
Ejemplo n.º 16
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.º 17
0
int
main(int argc,
     char* argv[])
{
  IoParams params;
  try
  {
    params.parse(argc,argv);
  }
  catch (const std::exception& excp)
  {
    std::cerr << " Exception while parsing cmd-line\n"
    << excp.what() << std::endl;
    exit(1);
  }
  catch (...)
  {
    std::cerr << " unhandled exception caught while parsing cmd line\n";
    exit(1);
  }


  boost::shared_ptr<gmp::VolumeMorph> pmorph(new gmp::VolumeMorph);

  if ( !params.strTemplate.empty() )
  {
    MRI* mri = MRIread( const_cast<char*>(params.strTemplate.c_str()) );
    if (!mri)
      std::cerr << " Failed to open template mri "
                << params.strTemplate << std::endl;
    else
      pmorph->set_volGeom_fixed(mri);
    MRIfree(&mri);
  }
  if ( !params.strSubject.empty() )
  {
    MRI* mri = MRIread( const_cast<char*>(params.strSubject.c_str()) );
    if (!mri)
      std::cerr << " Failed to open subject mri "
                << params.strSubject << std::endl;
    else
      pmorph->set_volGeom_moving(mri);
    MRIfree(&mri);
  }

  IoParams::MorphContainerType::iterator it;
  for ( it = params.items.begin();
        it != params.items.end();
        ++it )
  {
    if ( it->type == "affine" )
    {
      boost::shared_ptr<gmp::AffineTransform3d>
      paffine( new gmp::AffineTransform3d);
      float* pf = read_transform( it->file.c_str() );
      if ( !pf )
      {
        std::cerr << " failed to read transform\n";
        exit(1);
      }
      paffine->set_pars( pf);
      pmorph->m_transforms.push_back( paffine );

    }
    else if ( it->type == "volume" )
    {
      boost::shared_ptr<gmp::DeltaTransform3d>
      pvol( new gmp::DeltaTransform3d);
      MRI* field = MRIread
                   ( const_cast<char*>( it->file.c_str() ) );
      if ( !field )
      {
        std::cerr << " failed to read field "  << std::endl;
        exit(1);
      }
      pvol->set_field(field);

      pmorph->m_transforms.push_back( pvol );
    }
    else if ( it->type == "gcam" )
    {
      boost::shared_ptr<gmp::DeltaTransform3d>
      pvol( new gmp::DeltaTransform3d);
      GCA_MORPH* gcam = GCAMread( const_cast<char*>( it->file.c_str() ) );
      if ( !gcam )
      {
        std::cerr << " failed to read GCAM " << std::endl;
        exit(1);
      }
      // create bogus MRI to hold the geometry
      MRI* mri_template = MRIread( const_cast<char*>
                                   ( params.strTemplate.c_str() ) );
      MRI* mriBuf = MRIalloc( gcam->image.width,
                              gcam->image.height,
                              gcam->image.depth,
                              MRI_UCHAR);
      useVolGeomToMRI( &gcam->image, mriBuf );
      GCAMrasToVox(gcam, mriBuf );
      MRIfree( &mriBuf );

      std::cout << " atlas geometry = "
      << gcam->atlas.width << " , " << gcam->atlas.height
      << " , " << gcam->atlas.depth << std::endl
      << " image geometry = "
      << gcam->image.width << " , " << gcam->image.height
      << " , " << gcam->image.depth << std::endl;


      MRI* mri = MRIallocSequence( mri_template->width,
                                   mri_template->height,
                                   mri_template->depth,
                                   MRI_FLOAT,
                                   3);
      MRIcopyHeader(mri_template, mri);
      g_vDbgCoords = params.vDbgCoords;
      try
      {
        //MRI* mask =
        CopyGcamToDeltaField(gcam, mri);

        pvol->set_field(mri);
        //pvol->set_mask(mask);
        pmorph->m_transforms.push_back( pvol );
      }
      catch (const std::string& e)
      {
        std::cerr << " Exception caught while processing GCAM node\n"
        << e << std::endl;
        exit(1);
      }
      MRIfree(&mri_template);
    }
    else if ( it->type == "morph" )
    {
      boost::shared_ptr<gmp::VolumeMorph> tmpMorph(new gmp::VolumeMorph);
      try
      {
        tmpMorph->load( it->file.c_str() );
      }
      catch (const char* msg)
      {
        std::cerr << " Exception caught while loading morph in file "
        << it->file << std::endl;
        exit(1);
      }
      for ( gmp::VolumeMorph::TransformContainerType::iterator transformIter
            = tmpMorph->m_transforms.begin();
            transformIter != tmpMorph->m_transforms.end();
            ++transformIter )
        pmorph->m_transforms.push_back( *transformIter );

    }
    else if ( it->type == "mesh" )
    {
      boost::shared_ptr<gmp::FemTransform3d> pfem(new gmp::FemTransform3d);
      boost::shared_ptr<CMesh3d> pmesh(new CMesh3d);
      pmesh->load( it->file.c_str() );
      pfem->m_sharedMesh = pmesh;
      pmorph->m_transforms.push_back(pfem);
    }
    else
    {
      std::cerr << " unhandled transform type "
      << it->type << std::endl;
    }
  } // next it

  // finally write morph file
  try
  {
    pmorph->save( params.strOut.c_str() );
  }
  catch (const char* msg)
  {
    std::cerr << " Exception caught while saving morph\n"
    << msg << std::endl;
    exit(1);
  }

  return 0;
}
Ejemplo n.º 18
0
// returns the mask if necessary
MRI*
CopyGcamToDeltaField(GCA_MORPH* gcam, MRI* field)
{
  if ( !field ) throw std::string(" Field not set in CopyGcamToDeltaField\n");

  // allocate the mask
  MRI* mask = MRIalloc( field->width,
                        field->height,
                        field->depth,
                        MRI_UCHAR );
  unsigned int maskCounter = 0;
  unsigned char ucOne(1);//, ucZero(0);
  // fill the mask with true values to start with

  for (int z=0; z<field->depth; ++z)
    for (int y=0; y<field->height; ++y)
      for (int x=0; x<field->width; ++x)
        MRIvox(mask, x,y,z) = ucOne;


  GMN* pnode = NULL;

  // currently bug in transform.c - names are swapped
  //MATRIX* v2r_atlas = VGgetVoxelToRasXform( &gcam->atlas, NULL, 0);
  //MATRIX* r2v_image = VGgetRasToVoxelXform( &gcam->image, NULL, 0);
  MATRIX* v2r_atlas = VGgetRasToVoxelXform( &gcam->atlas, NULL, 0);
  //MATRIX* r2v_image = VGgetVoxelToRasXform( &gcam->image, NULL, 0);
  MATRIX* r2v_image = extract_r_to_i( field );
  MATRIX* transform = MatrixMultiply( r2v_image, v2r_atlas, NULL);

  std::cout << " vox 2 ras atlas = \n";
  MatrixPrint( stdout, v2r_atlas );
  std::cout << " ras 2 vox image = \n";
  MatrixPrint( stdout, r2v_image );
  std::cout << " product = \n";
  MatrixPrint( stdout, transform);
  std::cout << std::endl;

  // using the above matrix, go through the nodes of the GCAM
  // and associate the delta to the transformed node
  //
  // !!!! The strong underlying assumption is that the IMAGE and ATLAS associated
  // with the GCAM share the same RAS
  //
  VECTOR *vx = VectorAlloc(4, MATRIX_REAL);
  VECTOR_ELT(vx, 4) = 1.0;
  VECTOR_ELT(vx, 1) = 0.0;
  VECTOR_ELT(vx, 2) = 0.0;
  VECTOR_ELT(vx, 3) = 0.0;

  VECTOR *vfx= VectorAlloc(4, MATRIX_REAL);

  MatrixMultiply(transform, vx, vfx);
  std::cout << " transform at origin\n";
  MatrixPrint(stdout, vfx);

  int shift_x, shift_y, shift_z;

  shift_x = myNint( VECTOR_ELT(vfx, 1) );
  shift_y = myNint( VECTOR_ELT(vfx, 2) );
  shift_z = myNint( VECTOR_ELT(vfx, 3) );

  unsigned int invalidCount = 0;
  int img_x, img_y, img_z;
  for ( int z=0, maxZ=gcam->depth; z<maxZ; ++z)
    for ( int y=0, maxY=gcam->height; y<maxY; ++y)
      for ( int x=0, maxX=gcam->width; x<maxX; ++x)
      {
#if 0
        // indexing is 1-based - NR
        VECTOR_ELT(vx, 1) = x;
        VECTOR_ELT(vx, 2) = y;
        VECTOR_ELT(vx, 3) = z;

        MatrixMultiply(transform, vx, vfx);

        img_x = myNint( VECTOR_ELT(vfx, 1) );
        img_y = myNint( VECTOR_ELT(vfx, 2) );
        img_z = myNint( VECTOR_ELT(vfx, 3) );
#endif

        img_x = x + shift_x;
        img_y = y + shift_y;
        img_z = z + shift_z;

        if ( img_x < 0 || img_x > field->width-1 ||
             img_y < 0 || img_y > field->height-1 ||
             img_z < 0 || img_z > field->depth-1 )
        {
          maskCounter++;
          continue;
        }
        pnode = &gcam->nodes[x][y][z];

        //if (pnode->invalid) continue;
        if ( pnode->invalid == GCAM_POSITION_INVALID )
        {
          ++invalidCount;
          continue;
        }

#if 0
        if ( img_x == g_vDbgCoords[0] &&
             img_y == g_vDbgCoords[1] &&
             img_z == g_vDbgCoords[2] )
        {
          std::cout << " node " << img_x
          << " , " << img_y
          << " , " << img_z
          << " comes from "
          << x << " , " << y << " , " << z
          << " -> " << pnode->x
          << " , " << pnode->y
          << " , " << pnode->z << std::endl;
        }
#endif

        MRIsetVoxVal(mask, img_x, img_y, img_z, 0, ucOne );

        MRIsetVoxVal( field, img_x, img_y, img_z, 0,
                      pnode->x - img_x );
        MRIsetVoxVal( field, img_x, img_y, img_z, 1,
                      pnode->y - img_y );
        MRIsetVoxVal( field, img_x, img_y, img_z, 2,
                      pnode->z - img_z );

      }
  std::cout << " invalid voxel count = " << invalidCount << std::endl;
  if ( !g_vDbgCoords.empty() )
  {
    int x,y,z;

    pnode = &gcam->nodes[gcam->width/2][gcam->height/2][gcam->depth/2];

    for (unsigned int ui=0; ui<3; ++ui)
      VECTOR_ELT(vx, ui+1) = g_vDbgCoords[ui];

    MATRIX* minv = MatrixInverse(transform, NULL);
    MatrixMultiply(minv, vx, vfx);

    std::cout << " debugging at coords = \n";
    std::copy( g_vDbgCoords.begin(), g_vDbgCoords.end(),
               std::ostream_iterator<int>( std::cout, " ") );
    std::cout << std::endl;

    x = myNint( VECTOR_ELT( vfx, 1) );
    y = myNint( VECTOR_ELT( vfx, 2) );
    z = myNint( VECTOR_ELT( vfx, 3) );

    std::cout << " linear transf to get gcam xyz = "
    << x << " , " << y << " , " << z << std::endl;
    if ( x < 0 || x > gcam->width -1 ||
         y < 0 || y > gcam->height-1 ||
         z < 0 || z > gcam->depth -1 )
      std::cout << " out of bounds\n";
    else
    {
      pnode = &gcam->nodes[x][y][z];
      std::cout << " value of gcam = "
      << pnode->x << " , "
      << pnode->y << " , "
      << pnode->z << std::endl;
    }
  }


//   for( int z(0), maxZ(field->depth); z<maxZ; ++z)
//     for( int y(0), maxY(field->height); y<maxY; ++y)
//       for( int x(0), maxX(field->width); x<maxX; ++x)
//  {

//    if ( !GCAMsampleMorph(gcam, x,y,z,
//     &pxd, &pyd, &pzd) )
//      {
//        MRIvox(mask, x,y,z) = ucZero;
//        maskCounter++;
//        continue;
//      }
//    MRIsetVoxVal( field, x,y,z, 0,
//    pxd - x );
//    MRIsetVoxVal( field, x,y,z, 1,
//    pyd - y );
//    MRIsetVoxVal( field, x,y,z, 2,
//    pzd - z );

//  } // next x,y,z

  if ( !maskCounter )
  {
    MRIfree(&mask);
    return NULL;
  }
  return mask;
}
Ejemplo n.º 19
0
// the following only cares about finding the max segments
// ignoring the rest
MRI_SEGMENTATION *
MRImaxsegment(MRI *mri, float low_val, float hi_val)
{
  MRI_SEGMENTATION  *mriseg ;
  MRI_SEGMENT       *mseg, *mseg2 ;
  int               x, y, z, width, height, depth, xi, yi, zi, xk, yk, zk,
  val, border_labels[NBR_VOX], nlabels, label, nvox ;
  MRI               *mri_labeled ;
  float             voxel_size ;
  int max;
  int count =0;
  int totcount = 0;
  int mem =0;
  int maxarea=0;

  voxel_size = mri->xsize * mri->ysize * mri->zsize ;
  width = mri->width ;
  height = mri->height ;
  depth = mri->depth ;
  mriseg = MRIsegmentAlloc(MAX_SEGMENTS, MAX_VOXELS) ;
  mriseg->mri = mri ;

  for (z =0; z < depth; z++)
    for (y=0; y < height; y++)
      for (x=0; x < width; x++)
      {
        val = MRIgetVoxVal(mri, x, y, z, 0) ;
        if (val >= low_val && val <= hi_val)
          totcount++;
      }

  /* mri_labeled will contain the label number for each voxel (if it
     has been assigned to a segment).
  */
  mri_labeled = MRIalloc(width, height, depth, MRI_SHORT) ;
  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
        MRISvox(mri_labeled, x, y, z) = -1 ;
    }
  }

  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
      {
        val = MRIgetVoxVal(mri, x, y, z, 0) ;
        // if within the range
        if (val >= low_val && val <= hi_val)
        {
          count++;

          // initializer for border_labels
          memset(border_labels, -1, NBR_VOX*sizeof(int)) ;
          for (nvox = 0, zk = -1 ; zk <= 1 ; zk++)
          {
            zi = z+zk ;
            if ((zi < 0) || (zi >= depth))
              continue ;
            for (yk = -1 ; yk <= 1 ; yk++)
            {
              yi = y+yk ;
              if ((yi < 0) || (yi >= height))
                continue ;
              // increment nvox count here
              for (xk = -1 ; xk <= 1 ; xk++, nvox++)
              {
#if 1
                if ((abs(xk) + abs(yk) + abs(zk)) > 1)
                  continue ;  /* only allow 4 (6 in 3-d) connectivity */
#endif

                xi = x+xk ;
                if ((xi < 0) || (xi >= width))
                  continue ;
                // get the neighbor label
                label = MRISvox(mri_labeled, xi, yi, zi) ;
                if (label >= 0)
                  border_labels[nvox] = label ;
              }
            }
          }
          // count nonzero labels in nbrs
          for (nlabels = nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if ((label >= 0) && (!mriseg->segments[label].found))
            {
              mriseg->segments[label].found = 1 ;
              nlabels++ ;
            }
          }
          // reset found
          for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if (label >= 0)
              mriseg->segments[label].found = 0 ; /* for next time */
          }
          //
          label = 0 ;
          // create labels for those points which are not connected
          switch (nlabels)
          {
          case 0:          /* allocate a new segment */
            if (mriseg->nsegments >= mriseg->max_segments)
            {
              mem = getMemoryUsed();
              // only Linux gives the correct value
              // (the rest returns -1
              // mem > 800*1024) // 800 Mbytes virtual memory usage
              if (mriseg->max_segments >
                  MAX_SEGMENTS*VOX_INCREASE)
              {
                if (mem > 0) // only Linux can do this
                  fprintf(stdout, "\n             "
                          "heap usage = %d Kbytes.", mem);
                // find the region with the largest area
                maxarea = MRImaxSegmentArea(mriseg);
                fprintf
                (stdout,
                 "\n             current max segment has "
                 "%d voxels", maxarea);
                // the second max area can have area up to
                // (current - maxarea) + (total - maxarea)
                //  = total + current - 2*maxarea
                // if this value is less than maxarea,
                // then the second candidate never
                // becomes the top. Thus I can remove
                // small segments
                // if (count+totcount < 3*maxarea)
                //
                // For those which has < 100*N % of maxarea,
                // the possible max count is
                //    = maxarea*N + remaining voxels
                //    = maxarea*N + (total - count)
                // Thus I can remove those when
                // maxarea*N + (total-count) < maxarea
                // or total - count < maxarea*(1 - N)
                //
                // Note that if you remove too much,
                // then possbile merging voxels will be lost
                //
                if (totcount - count < maxarea*0.99)
                {
                  int i,j,k;
                  fprintf(stdout, "\n             removing "
                          "small segments (less than 1 "
                          "percent of maxarea).");
                  MRIremoveSmallSegments(mriseg, maxarea*0.01);
                  // this does compactify
                  // go through mri_labeled to
                  // remove this label value s
                  for (k=0; k < mri_labeled->depth; ++k)
                    for (j=0; j < mri_labeled->height; ++j)
                      for (i=0; i < mri_labeled->width; ++i)
                      {
                        if (MRISvox(mri_labeled, i,j,k)
                            >= mriseg->nsegments)
                          MRISvox(mri_labeled, i,j,k) = -1;
                      }
                }
              }
            }
            label = mriSegmentNew(mriseg) ;
            // returns this added segment position
            mseg = &mriseg->segments[label] ;
            if (DIAG_VERBOSE_ON && 0)
              fprintf(stdout, "allocating new label %d (%d total)\n",
                      label, mriseg->nsegments) ;
            break ;
          case 1:          /* assign this voxel to the one that it borders */
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
              {
                label = border_labels[nvox] ;
                break ;
              }
            // points to the same label position
            mseg = &mriseg->segments[label] ;
            break ;
          default:         /* merge segments and assign to lowest number */
            mseg = NULL ;
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
            {
              if (border_labels[nvox] >= 0)
              {
                // the 1st encountered label case
                if (!mseg)
                {
                  // set the first index position
                  label = border_labels[nvox] ;
                  mseg = &mriseg->segments[label] ;
                  mseg->found = 1 ;
                }
                // the rest
                else
                {
                  mseg2 =
                    &mriseg->segments[border_labels[nvox]] ;
                  if (mseg2->found == 0)
                  {
                    mseg2->found = 1 ;  /* prevent merging more than once */
                    // merge to the label position
                    if (mriSegmentMerge(mriseg,
                                        label,
                                        border_labels[nvox],
                                        mri_labeled)
                        != NO_ERROR)
                    {
                      // nsegments decreased by one
                      MRIsegmentFree(&mriseg) ;
                      return(NULL) ;
                    }
                  }
                }
              }
            }
            // reset found
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
                mriseg->segments[border_labels[nvox]].found = 0 ;
            break ;
          }
          /* add it to the existing list */
          if (mseg->nvoxels >= mseg->max_voxels)
          {
            // this max could be the same as mseg->max_voxels
            // this is taken care in mriSegmentReallocateVoxels()
            max = nint(mseg->max_voxels*VOX_INCREASE);
            // if (mriSegmentReallocateVoxels(mriseg, label,
            //            nint(mseg->max_voxels*VOX_INCREASE))
            //    != NO_ERROR)
            if (mriSegmentReallocateVoxels(mriseg, label, max)
                != NO_ERROR)
            {
              MRIsegmentFree(&mriseg) ;
              return(NULL) ;
            }
          }
          mseg->voxels[mseg->nvoxels].x = x ;
          mseg->voxels[mseg->nvoxels].y = y ;
          mseg->voxels[mseg->nvoxels].z = z ;
          mseg->nvoxels++ ;
          mseg->area += voxel_size ; // voxel_size = volume
#if 0
          // this is for only 1mm voxel case
          if (mseg->nvoxels != (int)mseg->area)
            DiagBreak() ;
#endif
          MRISvox(mri_labeled, x, y, z) = label ;
        }
      }
    }
  }
  mem = getMemoryUsed();
  if (mem > 0) // only Linux can do this
    fprintf(stdout, "\n             heap usage = %d Kbytes.", mem);
  maxarea = MRImaxSegmentArea(mriseg);
  fprintf(stdout, "\n             removing small segments (less "
          "than 1 percent of maxarea).");
  MRIremoveSmallSegments(mriseg, 0.01*maxarea);
  // MRIcompactSegments(mriseg) ;

  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON && 0)
    MRIwrite(mri_labeled, "labeled.mgh") ;
  MRIfree(&mri_labeled) ;
  mriComputeSegmentStatistics(mriseg) ;
  return(mriseg) ;
}
Ejemplo n.º 20
0
MRI_SEGMENTATION *
MRIsegment(MRI *mri, float low_val, float hi_val)
{
  MRI_SEGMENTATION  *mriseg ;
  MRI_SEGMENT       *mseg, *mseg2 ;
  int               x, y, z, width, height, depth, xi, yi, zi, xk, yk, zk,
  border_labels[NBR_VOX], nlabels, label, nvox ;
  MRI               *mri_labeled ;
  float             voxel_size, val ;
  int max;
  int count =0;

  voxel_size = mri->xsize * mri->ysize * mri->zsize ;
  width = mri->width ;
  height = mri->height ;
  depth = mri->depth ;
  mriseg = MRIsegmentAlloc(MAX_SEGMENTS, MAX_VOXELS) ;
  mriseg->mri = mri ;

  /* mri_labeled will contain the label number for each voxel (if it
     has been assigned to a segment).
  */
  mri_labeled = MRIalloc(width, height, depth, MRI_SHORT) ;
  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
        MRISvox(mri_labeled, x, y, z) = -1 ;
    }
  }

  for (z = 0 ; z < depth ; z++)
  {
    for (y = 0 ; y < height ; y++)
    {
      for (x = 0 ; x < width ; x++)
      {
        val = MRIgetVoxVal(mri, x, y, z, 0) ;
        // if within the range
        if (val >= low_val && val <= hi_val)
        {
          count++;

          // initializer for border_labels
          memset(border_labels, -1, NBR_VOX*sizeof(int)) ;
          for (nvox = 0, zk = -1 ; zk <= 1 ; zk++)
          {
            zi = z+zk ;
            if ((zi < 0) || (zi >= depth))
              continue ;
            for (yk = -1 ; yk <= 1 ; yk++)
            {
              yi = y+yk ;
              if ((yi < 0) || (yi >= height))
                continue ;
              // increment nvox count here
              for (xk = -1 ; xk <= 1 ; xk++, nvox++)
              {
#if 1
                if ((abs(xk) + abs(yk) + abs(zk)) > 1)
                  continue ;  /* only allow 4 (6 in 3-d) connectivity */
#endif

                xi = x+xk ;
                if ((xi < 0) || (xi >= width))
                  continue ;
                // get the neighbor label
                label = MRISvox(mri_labeled, xi, yi, zi) ;
                if (label >= 0)
                  border_labels[nvox] = label ;
              }
            }
          }
          // count nonzero labels in nbrs
          for (nlabels = nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if ((label >= 0) && (!mriseg->segments[label].found))
            {
              mriseg->segments[label].found = 1 ;
              nlabels++ ;
            }
          }
          // reset found
          for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
          {
            label = border_labels[nvox] ;
            if (label >= 0)
              mriseg->segments[label].found = 0 ; /* for next time */
          }
          //
          label = 0 ;
          // create labels for those points which are not connected
          switch (nlabels)
          {
          case 0:          /* allocate a new segment */
            label = mriSegmentNew(mriseg) ;
            // returns this added segment position
            mseg = &mriseg->segments[label] ;
            if (DIAG_VERBOSE_ON && 0)
              fprintf(stdout, "allocating new label %d (%d total)\n",
                      label, mriseg->nsegments) ;
            break ;
          case 1:          /* assign this voxel to the one that it borders */
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
              {
                label = border_labels[nvox] ;
                break ;
              }
            // points to the same label position
            mseg = &mriseg->segments[label] ;
            break ;
          default:         /* merge segments and assign to lowest number */
            mseg = NULL ;
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
            {
              if (border_labels[nvox] >= 0)
              {
                // the 1st encountered label case
                if (!mseg)
                {
                  // set the first index position
                  label = border_labels[nvox] ;
                  mseg = &mriseg->segments[label] ;
                  mseg->found = 1 ;
                }
                // the rest
                else
                {
                  mseg2 =
                    &mriseg->segments[border_labels[nvox]] ;
                  if (mseg2->found == 0)
                  {
                    mseg2->found = 1 ;  /* prevent merging more than once */
                    // merge to the label position
                    if (mriSegmentMerge(mriseg,
                                        label,
                                        border_labels[nvox],
                                        mri_labeled)
                        != NO_ERROR)
                    {
                      // nsegments decreased by one
                      MRIsegmentFree(&mriseg) ;
                      return(NULL) ;
                    }
                  }
                }
              }
            }
            // reset found
            for (nvox = 0 ; nvox < NBR_VOX ; nvox++)
              if (border_labels[nvox] >= 0)
                mriseg->segments[border_labels[nvox]].found = 0 ;
            break ;
          }
          /* add it to the existing list */
          if (mseg->nvoxels >= mseg->max_voxels)
          {
            // this max could be the same as mseg->max_voxels
            // this is taken care in mriSegmentReallocateVoxels()
            max = nint(mseg->max_voxels*VOX_INCREASE);
            // if (mriSegmentReallocateVoxels(mriseg, label,
            //            nint(mseg->max_voxels*VOX_INCREASE))
            //    != NO_ERROR)
            if (mriSegmentReallocateVoxels(mriseg, label, max)
                != NO_ERROR)
            {
              MRIsegmentFree(&mriseg) ;
              return(NULL) ;
            }
          }
          mseg->voxels[mseg->nvoxels].x = x ;
          mseg->voxels[mseg->nvoxels].y = y ;
          mseg->voxels[mseg->nvoxels].z = z ;
          mseg->nvoxels++ ;
          mseg->area += voxel_size ; // voxel_size = volume
#if 0
          // this is for only 1mm voxel case
          if (mseg->nvoxels != (int)mseg->area)
            DiagBreak() ;
#endif
          MRISvox(mri_labeled, x, y, z) = label ;
        }
      }
    }
  }
  MRIcompactSegments(mriseg) ;

  if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON && 0)
    MRIwrite(mri_labeled, "labeled.mgh") ;
  MRIfree(&mri_labeled) ;
  mriComputeSegmentStatistics(mriseg) ;
  return(mriseg) ;
}
Ejemplo n.º 21
0
int
main(int argc, char *argv[])
{
  char   **av, *in_fname;
  int    ac, nargs, i, j,  x, y, z, width, height, depth;
  MRI    *mri_flash[MAX_IMAGES], *mri_label, *mri_mask;
  int index;
  int    msec, minutes, seconds, nvolumes, nvolumes_total ;
  struct timeb start ;
  float max_val, min_val, value;
  float *LDAweight = NULL;
  float **LDAmeans = NULL; /* Centroid for each considered class */
  float *classSize =NULL; /* relative size of each class */
  MATRIX **SWs; /* Within class scatter-matrix for each considered class */
  MATRIX *AdjMatrix; /* Adjacency matrix of all classes */

  FILE *fp;

  int num_classes;
  double cnr;


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

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

  TimerStart(&start) ;

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

  if (argc < 2)
    usage_exit(1) ;

  printf("command line parsing finished\n");

  if (label_fname == NULL)
  {
    printf("Use -label option to specify file for segmentation \n");
    usage_exit(0);
  }


  if (have_weight == 1 && weight_fname == NULL)
  {
    printf("Use -weight option to specify file for input LDA weights \n") ;
    usage_exit(0);
  }

  if (have_weight == 1 && synth_fname == NULL)
  {
    printf("Use -synth option to specify file for output synthesized volume \n") ;
    usage_exit(0);
  }


  if (ldaflag)
  {
    MINLABEL = MIN(class1, class2);
    MAXLABEL = MAX(class1, class2);
  }

  num_classes = MAXLABEL - MINLABEL + 1;

  printf("Total of %d classes considered in LDA training\n", num_classes);

  if (num_classes <= 1)
  {
    printf("Need to specify at least two classes to evaluate CNR\n");
    usage_exit(0);
  }

  //////////////////////////////////////////////////////////////////////////////////
  /*** Read in the input multi-echo volumes ***/
  nvolumes = 0 ;
  for (i = 1 ; i < argc; i++)
  {
    in_fname = argv[i] ;
    printf("reading %s...\n", in_fname) ;

    mri_flash[nvolumes] = MRIread(in_fname) ;
    if (mri_flash[nvolumes] == NULL)
      ErrorExit(ERROR_NOFILE, "%s: could not read volume %s",
                Progname, in_fname) ;
    /* conform will convert all data to UCHAR, which will reduce data resolution*/
    printf("%s read in. \n", in_fname) ;
    if (conform)
    {
      MRI *mri_tmp ;

      printf("embedding and interpolating volume\n") ;
      mri_tmp = MRIconform(mri_flash[nvolumes]) ;
      mri_flash[nvolumes] = mri_tmp ;
    }

    /* Change all volumes to float type for convenience */
    if (mri_flash[nvolumes]->type != MRI_FLOAT)
    {
      printf("Volume %d type is %d\n", nvolumes+1, mri_flash[nvolumes]->type);
      MRI *mri_tmp;
      printf("Change data to float type \n");
      mri_tmp = MRIchangeType(mri_flash[nvolumes], MRI_FLOAT, 0, 1.0, 1);
      MRIfree(&mri_flash[nvolumes]);
      mri_flash[nvolumes] = mri_tmp; //swap
    }

    nvolumes++ ;
  }

  printf("All data read in\n");

  ///////////////////////////////////////////////////////////////////////////
  nvolumes_total = nvolumes ;   /* all volumes read in */

  for (i = 0 ; i < nvolumes ; i++)
  {
    for (j = i+1 ; j < nvolumes ; j++)
    {
      if ((mri_flash[i]->width != mri_flash[j]->width) ||
          (mri_flash[i]->height != mri_flash[j]->height) ||
          (mri_flash[i]->depth != mri_flash[j]->depth))
        ErrorExit(ERROR_BADPARM, "%s:\nvolumes %d (type %d) and %d (type %d) don't match (%d x %d x %d) vs (%d x %d x %d)\n",
                  Progname, i, mri_flash[i]->type, j, mri_flash[j]->type, mri_flash[i]->width,
                  mri_flash[i]->height, mri_flash[i]->depth,
                  mri_flash[j]->width, mri_flash[j]->height, mri_flash[j]->depth) ;
    }
  }

  width = mri_flash[0]->width;
  height = mri_flash[0]->height;
  depth = mri_flash[0]->depth;

  if (label_fname != NULL)
  {
    mri_label = MRIread(label_fname);
    if (!mri_label)
      ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n",
                Progname, label_fname);

    if ((mri_label->width != mri_flash[0]->width) ||
        (mri_label->height != mri_flash[0]->height) ||
        (mri_label->depth != mri_flash[0]->depth))
      ErrorExit(ERROR_BADPARM, "%s: label volume size doesn't match data volumes\n", Progname);

    /* if(mri_label->type != MRI_UCHAR)
       ErrorExit(ERROR_BADPARM, "%s: label volume is not UCHAR type \n", Progname); */
  }

  if (mask_fname != NULL)
  {
    mri_mask = MRIread(mask_fname);
    if (!mri_mask)
      ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n",
                Progname, mask_fname);

    if ((mri_mask->width != mri_flash[0]->width) ||
        (mri_mask->height != mri_flash[0]->height) ||
        (mri_mask->depth != mri_flash[0]->depth))
      ErrorExit(ERROR_BADPARM, "%s: mask volume size doesn't macth data volumes\n", Progname);

    if (mri_mask->type != MRI_UCHAR)
      ErrorExit(ERROR_BADPARM, "%s: mask volume is not UCHAR type \n", Progname);
  }
  else
  {
    mri_mask = MRIalloc(mri_flash[0]->width, mri_flash[0]->height, mri_flash[0]->depth, MRI_UCHAR);
    MRIcopyHeader(mri_flash[0], mri_mask);

    /* Simply set mask to be 1 everywhere */
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++)
        {
          MRIvox(mri_mask, x, y,z) = 1;
        }
  }


  if (debug_flag && window_flag)
  {
    /* Limit LDA to a local window */
    printf("Local window size = %d\n", window_size);
    window_size /= 2;
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++)
        {
          if (MRIvox(mri_mask, x, y,z) == 0) continue;

          if (z < (Gz - window_size) || z >(Gz + window_size)
              || y <(Gy - window_size) || y > (Gy + window_size)
              || x < (Gx - window_size) || x > (Gx + window_size))
            MRIvox(mri_mask, x, y,z) = 0;
        }

  }

  LDAweight = (float *)calloc(nvolumes_total, sizeof(float));

  /* Allocate memory */
  LDAmeans = (float **)malloc(num_classes*sizeof(float *));
  SWs = (MATRIX **)malloc(num_classes*sizeof(MATRIX *));
  classSize = (float *)malloc(num_classes*sizeof(float));
  for (i=0; i< num_classes; i++)
  {
    LDAmeans[i] = (float *)malloc(nvolumes_total*sizeof(float));
    SWs[i] = (MATRIX *)MatrixAlloc(nvolumes_total, nvolumes_total, MATRIX_REAL);
    if (SWs[i] == NULL || LDAmeans[i] == NULL)
      ErrorExit(ERROR_BADPARM, "%s: unable to allocate required memory \n", Progname);
  }

  if (ldaflag)
  {
    AdjMatrix = (MATRIX *)MatrixAlloc(num_classes, num_classes, MATRIX_REAL);

    /* The diagnoal entries of AdjMatrix is set to zero initially */
    for (i=1; i <= num_classes;i++)
      for (j=i; j <= num_classes; j++)
      {
        AdjMatrix->rptr[i][j] = 0.0;
        AdjMatrix->rptr[j][i] = 0.0;
      }

    AdjMatrix->rptr[class1-MINLABEL +1][class2-MINLABEL+1] = 1.0;
    AdjMatrix->rptr[class1-MINLABEL +1][class1-MINLABEL+1] = 1.0;
    AdjMatrix->rptr[class2-MINLABEL +1][class2-MINLABEL+1] = 1.0;
    AdjMatrix->rptr[class2-MINLABEL +1][class1-MINLABEL+1] = 1.0;
  }
  else if (MINLABEL <=2 && MAXLABEL >= 76)
  {
    printf("Manually set adjacent matrix \n");

    AdjMatrix = (MATRIX *)MatrixAlloc(num_classes, num_classes, MATRIX_REAL);

    /* The diagnoal entries of AdjMatrix is set to zero initially */
    for (i=1; i <= num_classes;i++)
      for (j=i; j <= num_classes; j++)
      {
        AdjMatrix->rptr[i][j] = 0.0;
        AdjMatrix->rptr[j][i] = 0.0;
      }

    for (index = 0; index < CNR_pairs; index++)
    {
      i = ilist[index] - MINLABEL;
      j = jlist[index] - MINLABEL;

      AdjMatrix->rptr[i+1][j+1] = 1.0;
      AdjMatrix->rptr[j+1][i+1] = 1.0;
    }

    /* left-hemisphere */
    /*
    AdjMatrix->rptr[2+1-MINLABEL][17+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[17+1-MINLABEL][18+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[3+1-MINLABEL][17+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[5+1-MINLABEL][17+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[4+1-MINLABEL][17+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[18+1-MINLABEL][2+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[18+1-MINLABEL][3+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[18+1-MINLABEL][5+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[18+1-MINLABEL][4+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[10+1-MINLABEL][11+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[10+1-MINLABEL][4+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[10+1-MINLABEL][12+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[10+1-MINLABEL][2+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[2+1-MINLABEL][3+1-MINLABEL] = 1.0;
    */

    /* right-hemisphere */
    /*
    AdjMatrix->rptr[53+1-MINLABEL][41+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[53+1-MINLABEL][54+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[53+1-MINLABEL][42+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[53+1-MINLABEL][44+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[53+1-MINLABEL][43+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[54+1-MINLABEL][41+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[54+1-MINLABEL][42+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[54+1-MINLABEL][44+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[54+1-MINLABEL][43+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[49+1-MINLABEL][50+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[49+1-MINLABEL][43+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[49+1-MINLABEL][51+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[49+1-MINLABEL][41+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[41+1-MINLABEL][42+1-MINLABEL] = 1.0;

    for(i=1; i < num_classes;i++)
      for(j=i+1; j <= num_classes; j++){
    if(AdjMatrix->rptr[i][j] > 0.5)
    AdjMatrix->rptr[j][i] = AdjMatrix->rptr[i][j];
    else
    AdjMatrix->rptr[i][j] = AdjMatrix->rptr[j][i];
      }
    */

    /*    AdjMatrix->rptr[2+1-MINLABEL][3+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[2+1-MINLABEL][10+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[2+1-MINLABEL][11+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[2+1-MINLABEL][12+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[2+1-MINLABEL][13+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[2+1-MINLABEL][17+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[2+1-MINLABEL][18+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[3+1-MINLABEL][12+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[3+1-MINLABEL][17+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[3+1-MINLABEL][18+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[4+1-MINLABEL][10+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[4+1-MINLABEL][11+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[10+1-MINLABEL][11+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[10+1-MINLABEL][13+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[12+1-MINLABEL][13+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[12+1-MINLABEL][26+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[17+1-MINLABEL][18+1-MINLABEL] = 1.0;
    */
    /* right-hemisphere */
    /* AdjMatrix->rptr[41+1-MINLABEL][42+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[41+1-MINLABEL][49+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[41+1-MINLABEL][50+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[41+1-MINLABEL][51+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[41+1-MINLABEL][52+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[41+1-MINLABEL][53+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[41+1-MINLABEL][54+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[42+1-MINLABEL][51+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[42+1-MINLABEL][53+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[42+1-MINLABEL][54+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[43+1-MINLABEL][49+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[43+1-MINLABEL][50+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[49+1-MINLABEL][50+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[49+1-MINLABEL][52+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[51+1-MINLABEL][52+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[51+1-MINLABEL][58+1-MINLABEL] = 1.0;
    AdjMatrix->rptr[53+1-MINLABEL][54+1-MINLABEL] = 1.0;
    */
  }
  else
    AdjMatrix = ComputeAdjMatrix(mri_label, mri_mask, MINLABEL, MAXLABEL);
  /* AdjMatrix may need manual adjusted to avoid meaningless comparisons
   * such as computing CNR between left WM and right WM
   */


  for (i=1; i <= num_classes;i++)
    for (j=1; j <= num_classes; j++)
    {
      if (j==i) continue;
      /* the diagonal term will indicate whether the class is useful or not */
      AdjMatrix->rptr[i][i] +=  AdjMatrix->rptr[i][j] + AdjMatrix->rptr[j][i];
    }


  printf("Compute individual class statistics\n");
  /* Compute class means and covariance matrix */
  /* Note that here SWs will be covaraince matrix, not scatter matrix */
  for (i=0; i < num_classes; i++)
  {
    if (AdjMatrix->rptr[i+1][i+1] < 0.5) continue;
    computeClassStats(LDAmeans[i], SWs[i], &classSize[i], mri_flash, mri_label, mri_mask, nvolumes_total, MINLABEL + i);
  }
  printf("class statistics computed \n");

  if (fname != NULL)
    fp = fopen(fname, "w");
  else
    fp = 0;

  printf("compute pair-wise CNR/Mahalanobis distances \n");
  if (ldaflag)
  {
    for (i=0; i <num_classes-1;i++)
      for (j=i+1; j < num_classes; j++)
      {
        if (AdjMatrix->rptr[i+1][j+1] < 0.5) continue;
        cnr = computePairCNR(LDAmeans[i], LDAmeans[j], SWs[i], SWs[j], classSize[i],  classSize[j], nvolumes_total, LDAweight, 1);
        if (fp)
          fprintf(fp, "%9.4f ", (float)cnr);

        printf("CNR of class %d and class %d is %g\n", i+MINLABEL, j+MINLABEL, cnr);

      }

    if (fp)
    {
      fprintf(fp, "\n");
      fclose(fp);
    }

  }
  else
  {

    for (index = 0; index < CNR_pairs; index++)
    {
      i = ilist[index] - MINLABEL;
      j = jlist[index] - MINLABEL;

      if (AdjMatrix->rptr[i+1][j+1] < 0.5) continue;
      if (i== (2-MINLABEL) && j == (3-MINLABEL) && nvolumes_total > 1)
        cnr = computePairCNR(LDAmeans[i], LDAmeans[j], SWs[i], SWs[j], classSize[i],  classSize[j], nvolumes_total, LDAweight, 1);
      else
        cnr = computePairCNR(LDAmeans[i], LDAmeans[j], SWs[i], SWs[j], classSize[i], classSize[j], nvolumes_total, 0, 0);

      if (fp)
        fprintf(fp, "%9.4f ", (float)cnr);

      printf("CNR of class %d and class %d is %g\n", i+MINLABEL, j+MINLABEL, cnr);

    }

    if (fp)
    {
      fprintf(fp, "\n");
      fclose(fp);
    }
  }

  /* output weights for optimize CNR for class 2 and class 3 */
  if (weight_fname != NULL)
  {
    output_weights_to_file(LDAweight, weight_fname, nvolumes_total);
  }

  free(classSize);

  for (i=0; i< num_classes; i++)
  {
    free(LDAmeans[i]);
    MatrixFree(&SWs[i]);
  }
  free(LDAmeans);
  free(SWs);
  MatrixFree(&AdjMatrix);

  if (nvolumes_total > 1 && ((MINLABEL <=2 && MAXLABEL >= 3) || ldaflag))
  {
    if (ldaflag)
    {
      printf("LDA weights for %d-%d are: \n", class1, class2);
    }
    else
    {
      printf("LDA weights for 2-3 are: \n");
    }
    for (i=0; i < nvolumes_total; i++)
    {
      printf("%g ", LDAweight[i]);
    }
    printf("\n");

    if (synth_fname != NULL)
    {
      /* linear projection of input volumes to a 1D volume */
      min_val = 10000.0;
      max_val = -10000.0;
      for (z=0; z < depth; z++)
        for (y=0; y< height; y++)
          for (x=0; x < width; x++)
          {
            if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue;

            value = 0.0;

            for (i=0; i < nvolumes_total; i++)
            {
              value += MRIFvox(mri_flash[i], x, y, z)*LDAweight[i];
            }



            if (max_val < value) max_val = value;
            if (min_val > value) min_val = value;

            /* Borrow mri_flash[0] to store the float values first */
            MRIFvox(mri_flash[0], x, y, z) = value;
          }

      printf("max_val = %g, min_val = %g \n", max_val, min_val);

      /* Scale output to [0, 255] */
      for (z=0; z < depth; z++)
        for (y=0; y< height; y++)
          for (x=0; x < width; x++)
          {
            if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue;

            value = (MRIFvox(mri_flash[0], x, y, z) - min_val)*255.0/(max_val - min_val) + 0.5; /* +0.5 for round-off */

            if (value > 255.0) value = 255.0;
            if (value < 0) value = 0;

            /* Borrow mri_flash[0] to store the float values first */
            MRIvox(mri_mask, x, y, z) = (BUFTYPE) value;
          }

      /* Output synthesized volume */
      MRIwrite(mri_mask, synth_fname);
    }
  }

  free(LDAweight);

  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  printf("LDA took %d minutes and %d seconds.\n", minutes, seconds) ;

  MRIfree(&mri_mask);

  MRIfree(&mri_label);


  for (i=0; i < nvolumes_total; i++)
  {
    MRIfree(&mri_flash[i]);
  }
  exit(0);
}
Ejemplo n.º 22
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()  */
MRI *  
correct_gmwm_boundaries(MRI *segmri, MRI *outmri)
{
  int x, y, z, width, height, depth = 0;
  double val;
  MRI *tmpvol = NULL;
  MRI *allmaskdist, *label2, *label2distmap, *label3, *label3distmap, *label41, *label41distmap, *label42, *label42distmap = NULL;

  width  = segmri->width ;
  height = segmri->height ;
  depth  = segmri->depth ;

  // all lables
  tmpvol = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val > 0)
	    MRIsetVoxVal(tmpvol,x,y,z,0,1);
	}
  allmaskdist = MRIalloc(width, height, depth, MRI_FLOAT);
  allmaskdist = MRIextractDistanceMap(tmpvol, allmaskdist, 1, 3, 3, NULL);

  // label 2
  label2 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 2)
	    MRIsetVoxVal(label2,x,y,z,0,1);
	}
  label2distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label2distmap = MRIextractDistanceMap(label2, label2distmap, 1, 3, 3, NULL);

  // label 3
  label3 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 3)
	    MRIsetVoxVal(label3,x,y,z,0,1);
	}
  label3distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label3distmap = MRIextractDistanceMap(label3, label3distmap, 1, 3, 3, NULL);

  // label 41
  label41 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 41)
	    MRIsetVoxVal(label41,x,y,z,0,1);
	}
  label41distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label41distmap = MRIextractDistanceMap(label41, label41distmap, 1, 3, 3, NULL);

  // label 42
  label42 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 42)
	    MRIsetVoxVal(label42,x,y,z,0,1);
	}
  label42distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label42distmap = MRIextractDistanceMap(label42, label42distmap, 1, 3, 3, NULL);

  if (!outmri)
    outmri = MRIclone(segmri, NULL) ;

  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  if(MRIgetVoxVal(label2,x,y,z,0) == 1)
	    {
	      double tmpval  = MRIgetVoxVal(label2distmap,x,y,z,0);
	      double tmpval2 = MRIgetVoxVal(label3distmap,x,y,z,0);
	      // if (-0.5 <= lhwmvoldist(WM_L_ind(i)) && lhwmvoldist(WM_L_ind(i)) <= 0 && abs(lhwmvoldist(WM_L_ind(i))) <= lhgmvoldist(WM_L_ind(i)) && lhgmvoldist(WM_L_ind(i)) >= .5 && segvol(WM_L_ind(i)) == 2 && abs(maskvol(WM_L_ind(i))) <= 0.5)
	      if (-0.5 <= tmpval && tmpval <= 0 && fabs(tmpval) <= tmpval2 && tmpval2 >= .5 && fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= 0.5)
		MRIsetVoxVal(outmri,x,y,z,0,3);
	    }
	  else 
	    if(MRIgetVoxVal(label41,x,y,z,0) == 1)
	      {
		double tmpval  = MRIgetVoxVal(label41distmap,x,y,z,0);
		double tmpval2 = MRIgetVoxVal(label42distmap,x,y,z,0);
		//if (-0.5 <= rhwmvoldist(WM_R_ind(i)) && rhwmvoldist(WM_R_ind(i)) <= 0 && abs(rhwmvoldist(WM_R_ind(i))) <= rhgmvoldist(WM_R_ind(i)) && rhgmvoldist(WM_R_ind(i)) >= .5 && segvol(WM_R_ind(i)) == 41 && abs(maskvol(WM_R_ind(i))) <= 0.5)
		if (-0.5 <= tmpval && tmpval <= 0 && fabs(tmpval) <= tmpval2 && tmpval2 >= .5 && fabs(MRIgetVoxVal(allmaskdist,x,y,z,0)) <= 0.5)
		  MRIsetVoxVal(outmri,x,y,z,0,42);
	      }
	}
  
  return(outmri) ;
}
Ejemplo n.º 24
0
/*---------------------------------------------------------------*/
int main(int argc, char *argv[]) {
  int nargs, nthvtx, nnbrs1, nnbrs2, nthnbr, nbrvtxno1, nbrvtxno2;
  int nthface, annot1, annot2;
  VERTEX *vtx1, *vtx2;
  FACE *face1, *face2;
  float diff, maxdiff;

  nargs = handle_version_option (argc, argv, vcid, "$Name: stable5 $");
  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);

  SUBJECTS_DIR = getenv("SUBJECTS_DIR");
  if (SUBJECTS_DIR == NULL) {
    printf("INFO: SUBJECTS_DIR not defined in environment\n");
    //exit(1);
  }
  if (SUBJECTS_DIR1 == NULL) SUBJECTS_DIR1 = SUBJECTS_DIR;
  if (SUBJECTS_DIR2 == NULL) SUBJECTS_DIR2 = SUBJECTS_DIR;

  if (surf1path == NULL && surfname == NULL) surfname = "orig";

  if (surf1path == NULL) {
    sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR1,subject1,hemi,surfname);
    surf1path = strcpyalloc(tmpstr);
  }
  if (surf2path == NULL) {
    sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR2,subject2,hemi,surfname);
    surf2path = strcpyalloc(tmpstr);
  }
  dump_options(stdout);

  //read-in each surface.  notice that the random number generator is
  //seeded with the same value prior to each read.  this is because in
  //the routine MRIScomputeNormals, if it finds a zero-length vertex
  //normal, is adds a random value to the x,y,z and recomputes the normal.
  //so if comparing identical surfaces, the seed must be the same so that
  //any zero-length vertex normals appear the same.
  setRandomSeed(seed) ;
  surf1 = MRISread(surf1path);
  if (surf1 == NULL) {
    printf("ERROR: could not read %s\n",surf1path);
    exit(1);
  }
  setRandomSeed(seed) ;
  surf2 = MRISread(surf2path);
  if (surf2 == NULL) {
    printf("ERROR: could not read %s\n",surf2path);
    exit(1);
  }
  printf("Number of vertices %d %d\n",surf1->nvertices,surf2->nvertices);
  printf("Number of faces    %d %d\n",surf1->nfaces,surf2->nfaces);

  //Number of Vertices ----------------------------------------
  if (surf1->nvertices != surf2->nvertices) {
    printf("Surfaces differ in number of vertices %d %d\n",
           surf1->nvertices,surf2->nvertices);
    exit(101);
  }
  //Number of Faces ------------------------------------------
  if (surf1->nfaces != surf2->nfaces) {
    printf("Surfaces differ in number of faces %d %d\n",
           surf1->nfaces,surf2->nfaces);
    exit(101);
  }

  //surf1->faces[10000].area = 100;
  //surf1->vertices[10000].x = 100;

  if (ComputeNormalDist) {
    double dist, dx, dy, dz, dot ;
    MRI    *mri_dist ;

    mri_dist = MRIalloc(surf1->nvertices,1,1,MRI_FLOAT) ;
    MRIScomputeMetricProperties(surf1) ;
    MRIScomputeMetricProperties(surf2) ;
    for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) {
      vtx1 = &(surf1->vertices[nthvtx]);
      vtx2 = &(surf2->vertices[nthvtx]);
      dx = vtx2->x-vtx1->x ;
      dy = vtx2->y-vtx1->y ;
      dz = vtx2->z-vtx1->z ;
      dist = sqrt(dx*dx + dy*dy + dz*dz) ;
      dot = dx*vtx1->nx + dy*vtx1->ny + dz*vtx1->nz ;
      dist = dist * dot / fabs(dot) ;
      MRIsetVoxVal(mri_dist, nthvtx, 0, 0, 0, dist) ;
    }
    MRIwrite(mri_dist, out_fname) ;
    MRIfree(&mri_dist) ;
    exit(0);
  }

  maxdiff=0;

  //------------------------------------------------------------
  if (CheckSurf) {
    printf("Comparing surfaces\n");

    // Loop over vertices ---------------------------------------
    error_count=0;
    for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) {
      vtx1 = &(surf1->vertices[nthvtx]);
      vtx2 = &(surf2->vertices[nthvtx]);
      if (vtx1->ripflag != vtx2->ripflag) {
        printf("Vertex %d differs in ripflag %c %c\n",
               nthvtx,vtx1->ripflag,vtx2->ripflag);
        if (++error_count>=MAX_NUM_ERRORS) break;
      }
      if (CheckXYZ) {
        diff=fabs(vtx1->x - vtx2->x);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Vertex %d differs in x %g %g\t(%g)\n",
                 nthvtx,vtx1->x,vtx2->x,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
        diff=fabs(vtx1->y - vtx2->y);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Vertex %d differs in y %g %g\t(%g)\n",
                 nthvtx,vtx1->y,vtx2->y,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
        diff=fabs(vtx1->z - vtx2->z);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Vertex %d differs in z %g %g\t(%g)\n",
                 nthvtx,vtx1->z,vtx2->z,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
      }
      if (CheckNXYZ) {
        diff=fabs(vtx1->nx - vtx2->nx);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Vertex %d differs in nx %g %g\t(%g)\n",
                 nthvtx,vtx1->nx,vtx2->nx,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
        diff=fabs(vtx1->ny - vtx2->ny);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Vertex %d differs in ny %g %g\t(%g)\n",
                 nthvtx,vtx1->ny,vtx2->ny,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
        diff=fabs(vtx1->nz - vtx2->nz);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Vertex %d differs in nz %g %g\t(%g)\n",
                 nthvtx,vtx1->nz,vtx2->nz,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
      }
      nnbrs1 = surf1->vertices[nthvtx].vnum;
      nnbrs2 = surf2->vertices[nthvtx].vnum;
      if (nnbrs1 != nnbrs2) {
        printf("Vertex %d has a different number of neighbors %d %d\n",
               nthvtx,nnbrs1,nnbrs2);
        if (++error_count>=MAX_NUM_ERRORS) break;
      }
      for (nthnbr=0; nthnbr < nnbrs1; nthnbr++) {
        nbrvtxno1 = surf1->vertices[nthvtx].v[nthnbr];
        nbrvtxno2 = surf2->vertices[nthvtx].v[nthnbr];
        if (nbrvtxno1 != nbrvtxno2) {
          printf("Vertex %d differs in the identity of the "
                 "%dth neighbor %d %d\n",nthvtx,nthnbr,nbrvtxno1,nbrvtxno2);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
      }
      if (error_count>=MAX_NUM_ERRORS) break;
    }// loop over vertices
    if (maxdiff>0) printf("maxdiff=%g\n",maxdiff);
    if (error_count > 0) {
      printf("Exiting after finding %d errors\n",error_count);
      if (error_count>=MAX_NUM_ERRORS) {
        printf("Exceeded MAX_NUM_ERRORS loop guard\n");
      }
      exit(103);
    }

    // Loop over faces ----------------------------------------
    error_count=0;
    for (nthface=0; nthface < surf1->nfaces; nthface++) {
      face1 = &(surf1->faces[nthface]);
      face2 = &(surf2->faces[nthface]);
      if (CheckNXYZ) {
        diff=fabs(face1->nx - face2->nx);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Face %d differs in nx %g %g\t(%g)\n",
                 nthface,face1->nx,face2->nx,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
        diff=fabs(face1->ny - face2->ny);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Face %d differs in ny %g %g\t(%g)\n",
                 nthface,face1->ny,face2->ny,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
        diff=fabs(face1->nz - face2->nz);
        if (diff>maxdiff) maxdiff=diff;
        if (diff>thresh) {
          printf("Face %d differs in nz %g %g\t(%g)\n",
                 nthface,face1->nz,face2->nz,diff);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
      }
      diff=fabs(face1->area - face2->area);
      if (diff>maxdiff) maxdiff=diff;
      if (diff>thresh) {
        printf("Face %d differs in area %g %g\t(%g)\n",
               nthface,face1->area,face2->area,diff);
        if (++error_count>=MAX_NUM_ERRORS) break;
      }
      if (face1->ripflag != face2->ripflag) {
        printf("Face %d differs in ripflag %c %c\n",
               nthface,face1->ripflag,face2->ripflag);
        if (++error_count>=MAX_NUM_ERRORS) break;
      }
      for (nthvtx = 0; nthvtx < 3; nthvtx++) {
        if (face1->v[nthvtx] != face2->v[nthvtx]) {
          printf("Face %d differs in identity of %dth vertex %d %d\n",
                 nthface,nthvtx,face1->ripflag,face2->ripflag);
          if (++error_count>=MAX_NUM_ERRORS) break;
        }
      } // end loop over nthface vertex
      if (error_count>=MAX_NUM_ERRORS) break;
    } // end loop over faces
    if (maxdiff>0) printf("maxdiff=%g\n",maxdiff);
    if (error_count > 0) {
      printf("Exiting after finding %d errors\n",error_count);
      if (error_count>=MAX_NUM_ERRORS) {
        printf("Exceeded MAX_NUM_ERRORS loop guard\n");
      }
      exit(103);
    }

    printf("Surfaces are the same\n");
    exit(0);
  } // end check surf

  // -----------------------------------------------------------------
  if (CheckCurv) {
    printf("Checking curv file %s\n",curvname);
    sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR1,subject1,hemi,curvname);
    printf("Loading curv file %s\n",tmpstr);
    if (MRISreadCurvatureFile(surf1, tmpstr) != 0) {
      printf("ERROR: reading curvature file %s\n",tmpstr);
      exit(1);
    }
    sprintf(tmpstr,"%s/%s/surf/%s.%s",SUBJECTS_DIR2,subject2,hemi,curvname);
    printf("Loading curv file %s\n",tmpstr);
    if (MRISreadCurvatureFile(surf2, tmpstr) != 0) {
      printf("ERROR: reading curvature file %s\n",tmpstr);
      exit(1);
    }
    error_count=0;
    for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) {
      vtx1 = &(surf1->vertices[nthvtx]);
      vtx2 = &(surf2->vertices[nthvtx]);
      diff=fabs(vtx1->curv - vtx2->curv);
      if (diff>maxdiff) maxdiff=diff;
      if (diff > thresh) {
        printf("curv files differ at vertex %d %g %g\t(%g)\n",
               nthvtx,vtx1->curv,vtx2->curv,diff);
        if (++error_count>=MAX_NUM_ERRORS) break;
      }
    } // end loop over vertices
    if (maxdiff>0) printf("maxdiff=%g\n",maxdiff);
    if (error_count > 0) {
      printf("Exiting after finding %d errors\n",error_count);
      if (error_count>=MAX_NUM_ERRORS) {
        printf("Exceeded MAX_NUM_ERRORS loop guard\n");
      }
      exit(103);
    }
    printf("Curv files are the same\n");
    exit(0);
  } // end check curv

  // ---------------------------------------------------------
  if (CheckAParc) {
    printf("Checking AParc %s\n",aparcname);
    sprintf(tmpstr,"%s/%s/label/%s.%s.annot",
            SUBJECTS_DIR1,subject1,hemi,aparcname);
    printf("Loading aparc file %s\n",tmpstr);
    fflush(stdout);
    if (MRISreadAnnotation(surf1, tmpstr)) {
      printf("ERROR: MRISreadAnnotation() failed %s\n",tmpstr);
      exit(1);
    }
    if (aparc2name) aparcname = aparc2name;
    sprintf(tmpstr,"%s/%s/label/%s.%s.annot",
            SUBJECTS_DIR2,subject2,hemi,aparcname);
    printf("Loading aparc file %s\n",tmpstr);
    fflush(stdout);
    if (MRISreadAnnotation(surf2, tmpstr)) {
      printf("ERROR: MRISreadAnnotation() failed %s\n",tmpstr);
      exit(1);
    }
    error_count=0;
    for (nthvtx=0; nthvtx < surf1->nvertices; nthvtx++) {
      annot1 = surf1->vertices[nthvtx].annotation;
      annot2 = surf2->vertices[nthvtx].annotation;
      if (annot1 != annot2) {
        printf("aparc files differ at vertex %d: 1:%s 2:%s\n",
               nthvtx,
               CTABgetAnnotationName(surf1->ct,annot1),
               CTABgetAnnotationName(surf2->ct,annot2));
        if (++error_count>=MAX_NUM_ERRORS) break;
      }
    } // end loop over vertices
    if (error_count > 0) {
      printf("Exiting after finding %d errors\n",error_count);
      if (error_count>=MAX_NUM_ERRORS) {
        printf("Exceeded MAX_NUM_ERRORS loop guard\n");
      }
      exit(103);
    }
    printf("\n"
           "AParc files are the same\n"
           "------------------------\n");
    exit(0);
  }

  return 0;
}
Ejemplo n.º 25
0
/*-------------------------------------------------------
  Translate MHT data to an MRI volume in various different ways so
  that it can be visualized.
  Does not attempt to be a proper spatial transform to MRI space,
  (because what to do when mht->vres is large?)
  just a way to read out the MHT data in 3D
  ---------------------------------------------------------*/
MRI * MRIFromMHTandMRIS(MHT * mht, MRIS * mris, MFMM_Option_t mfmm_option)
{
  MRI * amri;
  int mhtvx, mhtvy, mhtvz;       // MHT "voxels"
  int mrix , mriy , mriz ;       // MRI voxels
  MHBT * bucket;
  MHB  * bin;
  int binnum;
  int fno_usage;   //
  int outval;

#define HALFMHTFOV 200
#define HALFMRIFOV 128

  fno_usage = mht->fno_usage;

  amri = MRIalloc(256, 256, 256, MRI_SHORT);
  for (mriz = 0; mriz < 255; mriz++) {
    for (mriy = 0; mriy < 255; mriy++) {
      for (mrix = 0; mrix < 255; mrix++) {
        MRISvox(amri, mrix, mriy, mriz) = 100;
      }
    }
  }
//  goto done;

  for (mriz = 0; mriz < 255; mriz++) {
    mhtvz = HALFMHTFOV - HALFMRIFOV + mriz;
    for (mriy = 0; mriy < 255; mriy++) {
      mhtvy = HALFMHTFOV - HALFMRIFOV + mriy;
      for (mrix = 0; mrix < 255; mrix++) {
        mhtvx = HALFMHTFOV - HALFMRIFOV + mrix;

        bucket = MHTgetBucketAtVoxIx(mht, mhtvx, mhtvy, mhtvz);

        outval = 0;

        if (bucket) {
          if (MFMM_None == mfmm_option) {
            outval = 1;
            goto outval_done;
          }
          for (binnum = 0; binnum < bucket->nused; binnum++ ){
            bin = &(bucket->bins[binnum]);

            switch (mfmm_option) {
            case MFMM_None: break;
            case MFMM_Num:
              outval = bin->fno;
              goto outval_done;
            case MFMM_NumDiv16:
              outval = bin->fno >> 4;
              goto outval_done;
            case MFMM_Count:
              outval++;
              break;
            }
          }
        }
      outval_done:
        if (outval > MAXSHORT)
          outval = MAXSHORT;

        // MRI?vox is a type-specific macro!
        MRISvox(amri, mrix, mriy, mriz) = outval;

      } // for mrix
    } // for mriy
  } // for mriz
//done:
  return amri;
}
Ejemplo n.º 26
0
MRI*
MRIcomputeVolumeFractionFromSurface(MRI_SURFACE *mris, double acc, MRI *mri_src, MRI *mri_fractions)
{
  const int width = mri_src->width;
  const int height = mri_src->height;
  const int depth = mri_src->depth;
  int x,y,z, vno;
  double xs, ys, zs, dist; 
  MRIS_HASH_TABLE *mht;
  VERTEX *v; 
  
  /* preparing the output */
  printf("preparing the output\n");
  if (mri_fractions == NULL)
    {
      mri_fractions = MRIalloc(width,height,depth,MRI_FLOAT);
      MRIcopyHeader(mri_src, mri_fractions);
    }
  MRI *mri_shell, *mri_interior; 
  /* creating a shell from the surface */
  printf("computing the shell\n");
  mri_shell = MRIclone(mri_src, NULL);
  mri_shell = MRISshell(mri_src, mris, mri_shell, 1);
  /* creating an interior image from the surface */
  printf("computing an interior image\n");
  mri_interior = MRIclone(mri_src, NULL);
  MRIclear(mri_interior);
  mri_interior = MRISfillInterior(mris, 0.0, mri_interior);
  /* creating the hash table related to the surface vertices */
  printf("computing the hash table\n");
  mht = MHTfillVertexTableRes(mris, NULL, CURRENT_VERTICES, 10);
  /* looping over the nonzero elements of the shell */
  printf("computing the fractions\n");
  volFraction frac;
  octTreeVoxel V; 
  double vox[3], vsize[3];
  vsize[0] = mri_src->xsize; vsize[1] = mri_src->ysize; vsize[2] = mri_src->zsize; 
  for (x = 0; x < width; x++)
    {
      for (y = 0; y < height; y++)
	{
	  for (z = 0; z < depth; z++)
	    {	  
	      if (MRIgetVoxVal (mri_shell, x, y, z, 0) > 125.0)
		{	      
		  /* change of coordinates from image to surface domain */
		  MRIvoxelToSurfaceRAS(mri_shell, x, y, z, &xs, &ys, &zs);
		  /* find the closest vertex to the point */
		  MHTfindClosestVertexGeneric(mht, mris, xs, ys, zs, 10, 2, &v, &vno, &dist);	      
		  /* creating the oct tree voxel structure */
		  vox[0] = xs - vsize[0] / 2.0; 
		  vox[1] = ys - vsize[1] / 2.0; 
		  vox[2] = zs - vsize[2] / 2.0; 
		  V = octTreeVoxelCreate(vox,vsize);
		  /* compute the volume fraction of this voxel */	      
		  frac = MRIcomputeVoxelFractions( V, v, acc, 1, mris);
		  MRIsetVoxVal(mri_fractions,x,y,z,0,frac.frac);
		}
	      else if(MRIgetVoxVal(mri_interior,x,y,z,0) > 0.0)
		MRIsetVoxVal(mri_fractions,x,y,z,0,1.0);

	    }
	}

    }
  return mri_fractions;
}
MRI *  
correct_putamen_pallidum_boundaries(MRI *segmri, MRI *outmri)
{
  int x, y, z, width, height, depth = 0;
  double val;
  MRI *label42, *label3, *label12, *label12distmap, *label13, *label13distmap, *label51, *label51distmap, *label52, *label52distmap = NULL;

  width  = segmri->width ;
  height = segmri->height ;
  depth  = segmri->depth ;

  // label 42
  label42 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 42)
	    MRIsetVoxVal(label42,x,y,z,0,1);
	}

  // label 3
  label3 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 3)
	    MRIsetVoxVal(label3,x,y,z,0,1);
	}

 // label 12
  label12 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 12)
	    MRIsetVoxVal(label12,x,y,z,0,1);
	}
  label12distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label12distmap = MRIextractDistanceMap(label12, label12distmap, 1, 3, 3, NULL);

  // label 13
  label13 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 13)
	    MRIsetVoxVal(label13,x,y,z,0,1);
	}
  label13distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label13distmap = MRIextractDistanceMap(label13, label13distmap, 1, 3, 3, NULL);

  // label 51
  label51 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 51)
	    MRIsetVoxVal(label51,x,y,z,0,1);
	}
  label51distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label51distmap = MRIextractDistanceMap(label51, label51distmap, 1, 3, 3, NULL);

  // label 52
  label52 = MRIclone(segmri, NULL) ;
  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  val = MRIgetVoxVal(segmri,x,y,z,0);
	  if (val == 52)
	    MRIsetVoxVal(label52,x,y,z,0,1);
	}
  label52distmap = MRIalloc(width, height, depth, MRI_FLOAT);
  label52distmap = MRIextractDistanceMap(label52, label52distmap, 1, 3, 3, NULL);

  for (z = 0 ; z < depth ; z++)
    for (y = 0 ; y < height ; y++)
      for (x = 0 ; x < width ; x++)
	{
	  if(MRIgetVoxVal(label42,x,y,z,0) == 1)
	    {
	      // if (rhputvoldist(Rcort_ind(i))<=.5 ||  rhpalvoldist(Rcort_ind(i)) <= .5)
	      if (MRIgetVoxVal(label51distmap,x,y,z,0) <= .5  || MRIgetVoxVal(label52distmap,x,y,z,0) <= .5)
		MRIsetVoxVal(outmri,x,y,z,0,41);
	    }
	  if(MRIgetVoxVal(label3,x,y,z,0) == 1)
	    {
	      // if (lhputvoldist(Lcort_ind(i))<=.5 ||  lhpalvoldist(Lcort_ind(i)) <= .5)
	      if (MRIgetVoxVal(label12distmap,x,y,z,0) <= .5  || MRIgetVoxVal(label13distmap,x,y,z,0) <= .5)
		MRIsetVoxVal(outmri,x,y,z,0,2);
	    }
	}

  return(outmri) ;
}
Ejemplo n.º 28
0
int main ( int argc, char** argv ) {

  MRI* mri = NULL;
  int zX = 256;
  int zY = 256;
  int zZ = 256;
  int err = NO_ERROR;
  int nX = 0;
  int nY = 0;
  int nZ = 0;
  float sizeX = 1.0;
  float sizeY = 1.0;
  float sizeZ = 1.0;
  int setMethod = SET_METHOD_XYZ;
  int setValue = 0;
  char fnVol[256] = "new_volume.mgz";
  int i;
  char* arg = NULL;

  for ( i = 1; i < argc; i++ ) {

    arg = argv[i];

    if ( argv[i] && *argv[i] != '-' ) {
      printf( "ERROR: Unrecognized argument %s\n", argv[i] );
      PrintUsage( NULL );
      exit( 1 );
    }

    while ( arg[0] == '-' )
      arg = arg+1;

    if ( strlen(arg) <= 0 )
      continue;

    if ( strcmp(arg,"h") == 0 ||
         strcmp(arg,"help") == 0 ) {
      PrintUsage( NULL );
      exit( 0 );
    }

    if ( strcmp(arg,"f") == 0 ||
         strcmp(arg,"filename") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to filename option." );
        exit( 1 );
      }
      strcpy( fnVol, argv[i+1] );
      i++;
    }

    if ( strcmp(arg,"x") == 0 ||
         strcmp(arg,"width") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to width option." );
        exit( 1 );
      }
      zX = atoi(argv[i+1]);
      i++;
    }
    if ( strcmp(arg,"y") == 0 ||
         strcmp(arg,"height") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to height option." );
        exit( 1 );
      }
      zY = atoi(argv[i+1]);
      i++;
    }
    if ( strcmp(arg,"z") == 0 ||
         strcmp(arg,"depth") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to depth option." );
        exit( 1 );
      }
      zZ = atoi(argv[i+1]);
      i ++;
    }

    if ( strcmp(arg,"sizex") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to sizex option." );
        exit( 1 );
      }
      sizeX = atof(argv[i+1]);
      i++;
    }
    if ( strcmp(arg,"sizey") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to sizey option." );
        exit( 1 );
      }
      sizeY = atof(argv[i+1]);
      i++;
    }
    if ( strcmp(arg,"sizez") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to sizez optoin." );
        exit( 1 );
      }
      sizeZ = atof(argv[i+1]);
      i++;
    }

    if ( strcmp(arg,"set-method") == 0 ) {
      if ( i+1 >= argc ) {
        PrintUsage( "No argument to set-method option." );
        exit( 1 );
      }
      if ( strcmp( argv[i+1], "xyz" ) == 0 ) {
        setMethod = SET_METHOD_XYZ;
        i++;
        printf( "set_method is xyz\n" );
      } else if ( strcmp( argv[i+1], "random" ) == 0 ) {
        setMethod = SET_METHOD_RANDOM;
        i++;
        printf( "set_method is random\n" );
      } else if ( strncmp( argv[i+1], "constant", 9 ) == 0 ) {
        if ( i+2 >= argc ) {
          PrintUsage( "No value argument to constant method option." );
          exit( 1 );
        }
        setMethod = SET_METHOD_CONSTANT;
        setValue = atoi( argv[i+2] );
        i+=2;
        printf( "set_method is constant, %d\n", setValue );
      } else {
        PrintUsage( "Unrecognized argument to set-method option" );
        exit( 1 );
      }
    }
  }

  printf( "Creating volume %s\n"
          "  width = %d height = %d depth = %d\n"
          "  xsize = %f ysize = %f zsize = %f\n"
          "  set method = %s, constant = %d\n",
          fnVol, zX, zY, zZ,
          sizeX, sizeY, sizeZ,
          sSetMethods[setMethod], setValue );

  mri = MRIalloc( zX, zY, zZ, MRI_UCHAR );
  if ( NULL == mri ) {
    fprintf( stderr, "Couldn't create volume.\n" );
    return 1;
  }
  MRIsetResolution( mri, sizeX, sizeY, sizeZ );

  switch ( setMethod ) {
  case SET_METHOD_CONSTANT:
    MRIvalueFill( mri, 0 );
    break;
  case SET_METHOD_RANDOM:
    for ( nZ = 0; nZ < zZ; nZ++ ) {
      for ( nY = 0; nY < zY; nY++ ) {
        for ( nX = 0; nX < zX; nX++ ) {
          MRIvox( mri, nX, nY, nZ ) = (int)((random()/(float)RAND_MAX)*255.0);
        }
      }
    }
    break;
  case SET_METHOD_XYZ:
    for ( nZ = 0; nZ < zZ; nZ++ ) {
      for ( nY = 0; nY < zY; nY++ ) {
        for ( nX = 0; nX < zX; nX++ ) {
          MRIvox( mri, nX, nY, nZ ) =
            (((float)nZ/(float)zZ)*255.0/3.0) +
            (((float)nY/(float)zY)*255.0/3.0) +
            (((float)nX/(float)zX)*255.0/3.0) ;
        }
      }
    }
    break;
  default:
    for ( nZ = (zZ/2) - (zZ/4); nZ < (zZ/2) + (zZ/4); nZ++ ) {
      for ( nY = (zY/2) - (zY/4); nY < (zY/2) + (zY/4); nY++ ) {
        for ( nX = (zX/2) - (zX/4); nX < (zX/2) + (zX/4); nX++ ) {
          MRIvox( mri, nX, nY, nZ ) = 255;
        }
      }
    }
  }

  err = MRIwrite( mri, fnVol );
  if ( NO_ERROR != err ) {
    fprintf( stderr, "Couldn't write volume.\n" );
    return 1;
  }

  MRIfree( &mri );

  return 0;
}
MRI *  
correct_largestCC_and_fill_holes(MRI *segmri, MRI *outmri)
{
  int i, x, y, z, width, height, depth = 0, val;
  width  = segmri->width ;
  height = segmri->height ;
  depth  = segmri->depth ;
  // char fname[STR_LEN];

  if (!outmri)
    printf("no outmri volume exists!\n") ;
    //outmri = MRIclone(segmri, NULL) ;
    //outmri = MRIalloc(width, height, depth, MRI_INT);
  
  int *segidlist;
  int nsegids = 0;
  segidlist = MRIsegIdListNot0(segmri, &nsegids, 0);

  MRI *currlabelvol = MRIalloc(width, height, depth, MRI_INT); 
  int currlabel = 0;

  for (i = 0; i < nsegids; i++)
    {
      currlabel = segidlist[i];
      
      if (currlabel > 0) 
	{
	  // label volume 
	  for (x = 0 ; x < width ; x++)
	    for (y = 0 ; y < height ; y++)
	      for (z = 0 ; z < depth ; z++)
		if (MRIgetVoxVal(segmri,x,y,z,0) == currlabel)
		  MRIsetVoxVal(currlabelvol,x,y,z,0,1);
		else
		  MRIsetVoxVal(currlabelvol,x,y,z,0,0);
	  
	  // choose largest connected components
	  // sprintf(fname, "/tmp/%d.%s", currlabel, "before-largest-conn-component.mgz") ;
	  // MRIwrite(currlabelvol, fname) ;
	  GetLargestCC6(currlabelvol); // Note: how to fill the background???!! -- WM
	  // sprintf(fname, "/tmp/%d.%s", currlabel, "largest-conn-component.mgz") ;
	  // MRIwrite(currlabelvol, fname) ;
	  // remove holes on that component
	  RemoveHoles(currlabelvol);
	  // sprintf(fname, "/tmp/%d.%s", currlabel, "holes-removed.mgz") ;
	  // MRIwrite(currlabelvol, fname) ;
	  
	  //fill ouput volume with new labels
	  for (x = 0 ; x < width ; x++)
	    for (y = 0 ; y < height ; y++)
	      for (z = 0 ; z < depth ; z++)
		{
		  val = MRIgetVoxVal(currlabelvol,x,y,z,0);
		  if (val == 1)
		    MRIsetVoxVal(outmri,x,y,z,0,currlabel);
		}
	}
    }
  
  return(outmri) ;
}
Ejemplo n.º 30
0
int
main(int argc, char *argv[]) {
  char   **av, *in_fname;
  int    ac, nargs, i, j,  x, y, z, width, height, depth;
  MRI    *mri_flash[MAX_IMAGES], *mri_label, *mri_mask, *mri_tmp;
  int    msec, minutes, seconds, nvolumes, nvolumes_total ;
  struct timeb start ;
  float max_val, min_val, value;
  float *LDAmean1, *LDAmean2, *LDAweight;
  int label;
  double sum_white, sum_gray;
  int count_white, count_gray;

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

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

  TimerStart(&start) ;

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

  if (argc < 2)
    usage_exit(1) ;

  printf("command line parsing finished\n");

  if (have_weight == 0 && ldaflag == 0) {
    printf("Use -lda option to specify two class labels to optimize CNR on \n");
    usage_exit(0);
  }

  if (have_weight == 0 && label_fname == NULL) {
    printf("Use -label option to specify file for segmentation \n");
    usage_exit(0);
  }


  if (have_weight == 1 && weight_fname == NULL) {
    printf("Use -weight option to specify file for input LDA weights \n") ;
    usage_exit(0);
  }

  if (have_weight == 1 && synth_fname == NULL) {
    printf("Use -synth option to specify file for output synthesized volume \n") ;
    usage_exit(0);
  }

  //////////////////////////////////////////////////////////////////////////////////
  /*** Read in the input multi-echo volumes ***/
  nvolumes = 0 ;
  for (i = 1 ; i < argc; i++) {
    in_fname = argv[i] ;
    printf("reading %s...\n", in_fname) ;

    mri_flash[nvolumes] = MRIread(in_fname) ;
    if (mri_flash[nvolumes] == NULL)
      ErrorExit(ERROR_NOFILE, "%s: could not read volume %s",
                Progname, in_fname) ;
    /* conform will convert all data to UCHAR, which will reduce data resolution*/
    printf("%s read in. \n", in_fname) ;
    if (conform) {
      printf("embedding and interpolating volume\n") ;
      mri_tmp = MRIconform(mri_flash[nvolumes]) ;
      MRIfree(&mri_flash[nvolumes]);
      mri_flash[nvolumes] = mri_tmp ;
    }

    /* Change all volumes to float type for convenience */
    if (mri_flash[nvolumes]->type != MRI_FLOAT) {
      printf("Volume %d type is %d\n", nvolumes+1, mri_flash[nvolumes]->type);
      printf("Change data to float type \n");
      mri_tmp = MRIchangeType(mri_flash[nvolumes], MRI_FLOAT, 0, 1.0, 1);
      MRIfree(&mri_flash[nvolumes]);
      mri_flash[nvolumes] = mri_tmp; //swap
    }

    nvolumes++ ;
  }

  printf("All data read in\n");

  ///////////////////////////////////////////////////////////////////////////
  nvolumes_total = nvolumes ;   /* all volumes read in */

  for (i = 0 ; i < nvolumes ; i++) {
    for (j = i+1 ; j < nvolumes ; j++) {
      if ((mri_flash[i]->width != mri_flash[j]->width) ||
          (mri_flash[i]->height != mri_flash[j]->height) ||
          (mri_flash[i]->depth != mri_flash[j]->depth))
        ErrorExit(ERROR_BADPARM, "%s:\nvolumes %d (type %d) and %d (type %d) don't match (%d x %d x %d) vs (%d x %d x %d)\n",
                  Progname, i, mri_flash[i]->type, j, mri_flash[j]->type, mri_flash[i]->width,
                  mri_flash[i]->height, mri_flash[i]->depth,
                  mri_flash[j]->width, mri_flash[j]->height, mri_flash[j]->depth) ;
    }
  }

  width = mri_flash[0]->width;
  height = mri_flash[0]->height;
  depth = mri_flash[0]->depth;

  if (label_fname != NULL) {
    mri_label = MRIread(label_fname);
    if (!mri_label)
      ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n",
                Progname, label_fname);

    if ((mri_label->width != mri_flash[0]->width) ||
        (mri_label->height != mri_flash[0]->height) ||
        (mri_label->depth != mri_flash[0]->depth))
      ErrorExit(ERROR_BADPARM, "%s: label volume size doesn't match data volumes\n", Progname);

    /* if(mri_label->type != MRI_UCHAR)
       ErrorExit(ERROR_BADPARM, "%s: label volume is not UCHAR type \n", Progname); */
  }

  if (mask_fname != NULL) {
    mri_mask = MRIread(mask_fname);
    if (!mri_mask)
      ErrorExit(ERROR_NOFILE, "%s: could not read input volume %s\n",
                Progname, mask_fname);

    if ((mri_mask->width != mri_flash[0]->width) ||
        (mri_mask->height != mri_flash[0]->height) ||
        (mri_mask->depth != mri_flash[0]->depth))
      ErrorExit(ERROR_BADPARM, "%s: mask volume size doesn't macth data volumes\n", Progname);

    if (mri_mask->type != MRI_UCHAR)
      ErrorExit(ERROR_BADPARM, "%s: mask volume is not UCHAR type \n", Progname);
  } else {

    if (have_weight == 1)
      noise_threshold = - 1e20;

    printf("Threshold input vol1 at %g to create mask \n", noise_threshold);
    printf("this threshold is useful to process skull-stripped data \n");

    mri_mask = MRIalloc(mri_flash[0]->width, mri_flash[0]->height, mri_flash[0]->depth, MRI_UCHAR);
    MRIcopyHeader(mri_flash[0], mri_mask);

    /* Simply set mask to be 1 everywhere */
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++) {

          if ((float)MRIgetVoxVal(mri_flash[0], x, y,z,0) < noise_threshold)
            MRIvox(mri_mask, x, y,z) = 0;
          else
            MRIvox(mri_mask, x, y,z) = 1;
        }
  }

  /* Normalize input volumes */
  if (normflag) {
    printf("Normalize input volumes to zero mean, variance 1\n");
    for (i=0; i <nvolumes_total; i++) {
      mri_flash[i] = MRInormalizeXH(mri_flash[i], mri_flash[i], mri_mask);
    }
    printf("Normalization done.\n");
  }

  if (0) {
    printf("Using both hemi-sphere by changing rh-labels\n");
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++) {
          label = (int)MRIgetVoxVal(mri_label, x, y,z,0);
          if (label == 41) /* white matter */
            MRIsetVoxVal(mri_label, x, y, z, 0, 2);
          else if (label == 42) /* gm */
            MRIsetVoxVal(mri_label, x, y, z, 0, 3);
        }
  }


  if (debug_flag && window_flag) {
    /* Limit LDA to a local window */
    printf("Local window size = %d\n", window_size);
    window_size /= 2;
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++) {
          if (MRIvox(mri_mask, x, y,z) == 0) continue;

          if (z < (Gz - window_size) || z >(Gz + window_size)
              || y <(Gy - window_size) || y > (Gy + window_size)
              || x < (Gx - window_size) || x > (Gx + window_size))
            MRIvox(mri_mask, x, y,z) = 0;
        }

  }

  LDAmean1 = (float *)malloc(nvolumes_total*sizeof(float));
  LDAmean2 = (float *)malloc(nvolumes_total*sizeof(float));
  LDAweight = (float *)malloc(nvolumes_total*sizeof(float));

  if (have_weight) {
    printf("Read in LDA weights from weight-file\n");
    input_weights_to_file(LDAweight, weight_fname, nvolumes_total);
  } else { /* compute LDA weights */
    printf("Compute LDA weights to maximize CNR for region %d and region %d\n", class1, class2);
    /* Compute class means */
    update_LDAmeans(mri_flash, mri_label, mri_mask, LDAmean1, LDAmean2, nvolumes_total, class1, class2);
    printf("class means computed \n");

    /* Compute Fisher's LDA weights */
    computeLDAweights(LDAweight, mri_flash, mri_label, mri_mask, LDAmean1, LDAmean2, nvolumes_total, class1, class2);

    if (weight_fname != NULL) {
      output_weights_to_file(LDAweight, weight_fname, nvolumes_total);
    }
  }

  printf("LDA weights are: \n");
  for (i=0; i < nvolumes_total; i++) {
    printf("%g ", LDAweight[i]);
  }
  printf("\n");

  if (synth_fname != NULL) {
    /* linear projection of input volumes to a 1D volume */
    min_val = 10000.0;
    max_val = -10000.0;
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++) {
          if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue;

          value = 0.0;

          for (i=0; i < nvolumes_total; i++) {
            value += MRIFvox(mri_flash[i], x, y, z)*LDAweight[i];
          }

          //     if(value < 0) value = 0;

          if (max_val < value) max_val = value;
          if (min_val > value) min_val = value;

          /* Borrow mri_flash[0] to store the float values first */
          MRIFvox(mri_flash[0], x, y, z) = value;
        }

    printf("max_val = %g, min_val = %g \n", max_val, min_val);

    /* Check to make sure class1 has higher intensity than class2 */
    if (have_weight == 0) {
      sum_white =0;
      count_white = 0;
      sum_gray = 0;
      count_gray = 0;
      for (z=0; z < depth; z++) {
        if (count_white > 300 && count_gray > 300) break;
        for (y=0; y< height; y++) {
          for (x=0; x < width; x++) {

            if ((int)MRIgetVoxVal(mri_label, x, y,z,0) == class1) {
              sum_white += MRIFvox(mri_flash[0], x, y, z);
              count_white += 1;
            } else if ((int)MRIgetVoxVal(mri_label, x, y,z,0) == class2) {
              sum_gray += MRIFvox(mri_flash[0], x, y, z);
              count_gray += 1;
            }
          }
        }
      }

      if (count_white > 1 && count_gray > 1) {
        if (sum_white *count_gray < sum_gray*count_white) {
          for (z=0; z < depth; z++)
            for (y=0; y< height; y++)
              for (x=0; x < width; x++) {
                if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue;
                value = MRIFvox(mri_flash[0], x, y, z);
                MRIFvox(mri_flash[0], x, y, z) = max_val - value;
              }
          max_val = max_val - min_val;
          min_val = 0;
        }
      }
    }

    /* The following is copied to be consistent with mri_synthesize */
    /* Don't know why add min_val, minus should make more sense */
    for (z=0; z < depth; z++)
      for (y=0; y< height; y++)
        for (x=0; x < width; x++) {
          if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) {
            MRIFvox(mri_flash[0], x, y, z) = 0; /*background always set to 0 */
            continue;
          }
          /* Borrow mri_flash[0] to store the float values first */
          if (shift_value > 0) {
            value = MRIFvox(mri_flash[0], x, y, z) + shift_value;
            if (value < 0) value = 0;
            MRIFvox(mri_flash[0], x, y, z) = value;
          } else if (mask_fname != NULL)
            MRIFvox(mri_flash[0], x, y, z) -= min_val;
        }


    MRIfree(&mri_mask);
    if (mri_flash[0]->type == out_type) {
      mri_mask = MRIcopy(mri_flash[0], mri_mask);
    } else {
      mri_mask = MRIchangeType(mri_flash[0], out_type, 0.1, 0.99, 0);
    }

    /* Scale output to [0, 255] */
    if (0) {
      for (z=0; z < depth; z++)
        for (y=0; y< height; y++)
          for (x=0; x < width; x++) {
            if (whole_volume == 0 && MRIvox(mri_mask, x, y, z) == 0) continue;

            value = (MRIFvox(mri_flash[0], x, y, z) - min_val)*255.0/(max_val - min_val) + 0.5; /* +0.5 for round-off */

            if (value > 255.0) value = 255.0;
            if (value < 0) value = 0;

            /* Borrow mri_flash[0] to store the float values first */
            MRIvox(mri_mask, x, y, z) = (BUFTYPE) value;
          }
    }

    /* Output synthesized volume */
    MRIwrite(mri_mask, synth_fname);

  }

  free(LDAmean1);
  free(LDAmean2);
  free(LDAweight);

  msec = TimerStop(&start) ;
  seconds = nint((float)msec/1000.0f) ;
  minutes = seconds / 60 ;
  seconds = seconds % 60 ;
  printf("LDA took %d minutes and %d seconds.\n", minutes, seconds) ;

  MRIfree(&mri_mask);

  if (label_fname)
    MRIfree(&mri_label);


  for (i=0; i < nvolumes_total; i++) {
    MRIfree(&mri_flash[i]);
  }
  exit(0);
}