static int remove_surface_outliers(MRI *mri_ctrl_src, MRI *mri_dist, MRI *mri_src, MRI *mri_ctrl_dst) { int x, y, z, wsize ; HISTOGRAM *h, *hs ; double mean, sigma, val ; MRI *mri_outlier = MRIclone(mri_ctrl_src, NULL) ; mri_ctrl_dst = MRIcopy(mri_ctrl_src, mri_ctrl_dst) ; wsize = nint(WSIZE_MM/mri_src->xsize) ; for (x = 0 ; x < mri_src->width ; x++) for (y = 0 ; y < mri_src->height ; y++) for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } if ((int)MRIgetVoxVal(mri_ctrl_src, x, y,z, 0) == 0) { continue ; // not a control point } val = MRIgetVoxVal(mri_src, x, y, z, 0) ; #if 1 if (val < 80 || val > 130) { MRIsetVoxVal(mri_ctrl_dst, x, y, z, 0, 0) ; // remove it as a control point MRIsetVoxVal(mri_outlier, x, y, z, 0, 1) ; // diagnostics continue ; } #endif #if 1 if (val > 100 || val < 120) { continue ; // not an outlier } #endif h = MRIhistogramVoxel(mri_src, 0, NULL, x, y, z, wsize, mri_dist, mri_src->xsize) ; HISTOsoapBubbleZeros(h, h, 100) ; hs = HISTOsmooth(h, NULL, .5); HISTOrobustGaussianFit(hs, .5, &mean, &sigma) ; #define MAX_SIGMA 10 // for intensity normalized images if (sigma > MAX_SIGMA) { sigma = MAX_SIGMA ; } if (fabs((mean-val)/sigma) > 2) { MRIsetVoxVal(mri_ctrl_dst, x, y, z, 0, 0) ; // remove it as a control point MRIsetVoxVal(mri_outlier, x, y, z, 0, 1) ; // diagnostics } if (Gdiag & DIAG_WRITE) { HISTOplot(h, "h.plt") ; HISTOplot(h, "hs.plt") ; } HISTOfree(&h) ; HISTOfree(&hs) ; } if (Gdiag & DIAG_WRITE) { MRIwrite(mri_outlier, "o.mgz") ; } MRIfree(&mri_outlier) ; return(NO_ERROR) ; }
static MRI * MRIremoveWMOutliers(MRI *mri_src, MRI *mri_src_ctrl, MRI *mri_dst_ctrl, int intensity_below) { MRI *mri_bin, *mri_outliers = NULL ; float max, thresh, val; HISTOGRAM *histo, *hsmooth ; int wm_peak, x, y, z, nremoved = 0, whalf = 5, total ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_src_ctrl, "sc.mgz") ; } if (mri_dst_ctrl == NULL) { mri_dst_ctrl = MRIcopy(mri_src_ctrl, NULL) ; } mri_bin = MRIbinarize(mri_src_ctrl, NULL, 1, 0, CONTROL_MARKED) ; histo = MRIhistogramLabel(mri_src, mri_bin, 1, 256) ; hsmooth = HISTOcopy(histo, NULL) ; HISTOsmooth(histo, hsmooth, 2) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { HISTOplot(histo, "h.plt") ; HISTOplot(hsmooth, "hs.plt") ; } wm_peak = HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins-1) ; wm_peak = hsmooth->bins[wm_peak] ; thresh = wm_peak-intensity_below ; HISTOfree(&histo) ; HISTOfree(&hsmooth) ; if (Gdiag & DIAG_WRITE) { mri_outliers = MRIclone(mri_dst_ctrl, NULL) ; } for (total = x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } if (nint(MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0)) == 0) { continue ; } max = MRImaxInLabelInRegion(mri_src, mri_bin, 1, x, y, z, whalf); val = MRIgetVoxVal(mri_src, x, y, z, 0) ; total++ ; if (val+intensity_below < max && val < thresh) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; if (mri_outliers) { MRIsetVoxVal(mri_outliers, x, y, z, 0, 128) ; } nremoved++ ; } } } } printf( "%d control points removed (%2.1f%%)\n", nremoved, 100.0*(double)nremoved/(double)total) ; if (mri_outliers) { printf( "writing out.mgz outlier volume\n") ; MRIwrite(mri_outliers, "out.mgz") ; MRIfree(&mri_outliers) ; } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dst_ctrl, "dc.mgz") ; } MRIfree(&mri_bin) ; return(mri_dst_ctrl); }
static MRI * MRIremoveWMOutliersAndRetainMedialSurface(MRI *mri_src, MRI *mri_src_ctrl, MRI *mri_dst_ctrl, int intensity_below) { MRI *mri_inside, *mri_bin ; HISTOGRAM *histo, *hsmooth ; int wm_peak, x, y, z, nremoved ; float thresh, hi_thresh ; double val, lmean, max ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_src_ctrl, "sc.mgz") ; } if (mri_dst_ctrl != mri_src_ctrl) { mri_dst_ctrl = MRIcopy(mri_src_ctrl, mri_dst_ctrl) ; } mri_inside = MRIerode(mri_dst_ctrl, NULL) ; MRIbinarize(mri_inside, mri_inside, 1, 0, 1) ; histo = MRIhistogramLabel(mri_src, mri_inside, 1, 256) ; hsmooth = HISTOcopy(histo, NULL) ; HISTOsmooth(histo, hsmooth, 2) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { HISTOplot(histo, "h.plt") ; HISTOplot(hsmooth, "hs.plt") ; } printf("using wm (%d) threshold %2.1f for removing exterior voxels\n", wm_peak, thresh) ; wm_peak = HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins-1) ; wm_peak = hsmooth->bins[wm_peak] ; thresh = wm_peak-intensity_below ; hi_thresh = wm_peak-.5*intensity_below ; printf("using wm (%d) threshold %2.1f for removing exterior voxels\n", wm_peak, thresh) ; // now remove stuff that's on the border and is pretty dark for (nremoved = x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } /* if it's a control point, it's not in the interior of the wm, and it's T1 val is too low */ if (MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0) == 0) { continue ; // not a control point } /* if it's way far from the wm mode then remove it even if it's in the interior */ val = MRIgetVoxVal(mri_src, x, y, z, 0) ; if (val < thresh-5) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } if (nint(MRIgetVoxVal(mri_inside, x, y, z, 0)) > 0) // don't process interior voxels further { continue ; // in the interior } if (val < thresh) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } else { lmean = MRImeanInLabelInRegion(mri_src, mri_inside, 1, x, y, z, 7); if (val < lmean-10) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } } } } } #if 0 for (x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } /* if it's a control point, it's not in the interior of the wm, and it's T1 val is too low */ if (MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0) == 0) { continue ; // not a control point } if (MRIcountNonzeroInNbhd(mri_dst_ctrl,3, x, y, z)<=2) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } } } } #endif /* now take out voxels that have too big an intensity diff with surrounding ones */ mri_bin = MRIbinarize(mri_dst_ctrl, NULL, 1, 0, 1) ; for (x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } /* if it's a control point, it's not in the interior of the wm, and it's T1 val is too low */ if (MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0) == 0) { continue ; // not a control point } val = MRIgetVoxVal(mri_src, x, y, z, 0) ; max = MRImaxInLabelInRegion(mri_src, mri_bin, 1, x, y, z, 3); if (val+7 < max && val < hi_thresh) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; nremoved++ ; } } } } MRIfree(&mri_bin) ; printf( "%d control points removed\n", nremoved) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dst_ctrl, "dc.mgz") ; } HISTOfree(&histo) ; HISTOfree(&hsmooth) ; MRIfree(&mri_inside) ; return(mri_dst_ctrl) ; }
static MRI * MRIremoveWMOutliersAndRetainMedialSurface(MRI *mri_src, MRI *mri_src_ctrl, MRI *mri_dst_ctrl, int intensity_below) { MRI *mri_bin, *mri_dist, *mri_dist_sup, *mri_outliers = NULL ; float max, thresh, val; HISTOGRAM *histo, *hsmooth ; int wm_peak, x, y, z, nremoved = 0, whalf = 5 ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_src_ctrl, "sc.mgz") ; } mri_bin = MRIbinarize(mri_dst_ctrl, NULL, 1, 0, 1) ; mri_dist = MRIdistanceTransform(mri_bin, NULL, 1, -1, DTRANS_MODE_SIGNED, NULL); MRIscalarMul(mri_dist, mri_dist, -1) ; mri_dist_sup = MRInonMaxSuppress(mri_dist, NULL, 0, 1) ; mri_dst_ctrl = MRIbinarize(mri_dist_sup, mri_dst_ctrl, 1, 0, 1) ; histo = MRIhistogramLabel(mri_src, mri_src_ctrl, 1, 256) ; hsmooth = HISTOcopy(histo, NULL) ; HISTOsmooth(histo, hsmooth, 2) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { HISTOplot(histo, "h.plt") ; HISTOplot(hsmooth, "hs.plt") ; } wm_peak = HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins-1) ; wm_peak = hsmooth->bins[wm_peak] ; thresh = wm_peak-intensity_below ; HISTOfree(&histo) ; HISTOfree(&hsmooth) ; if (Gdiag & DIAG_WRITE) { mri_outliers = MRIclone(mri_dst_ctrl, NULL) ; } for (x = 0 ; x < mri_src->width ; x++) { for (y = 0 ; y < mri_src->height ; y++) { for (z = 0 ; z < mri_src->depth ; z++) { if (x == Gx && y == Gy && z == Gz) { DiagBreak() ; } if (nint(MRIgetVoxVal(mri_dst_ctrl, x, y, z, 0)) == 0) { continue ; } max = MRImaxInLabelInRegion(mri_src, mri_dst_ctrl, 1, x, y, z, whalf); val = MRIgetVoxVal(mri_src, x, y, z, 0) ; if (val+intensity_below < max && val < thresh) { MRIsetVoxVal(mri_dst_ctrl, x, y, z, 0, 0) ; if (mri_outliers) { MRIsetVoxVal(mri_outliers, x, y, z, 0, 128) ; } nremoved++ ; } } } } printf( "%d control points removed\n", nremoved) ; if (mri_outliers) { printf( "writing out.mgz outlier volume\n") ; MRIwrite(mri_outliers, "out.mgz") ; MRIfree(&mri_outliers) ; } if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) { MRIwrite(mri_dst_ctrl, "dc.mgz") ; } MRIfree(&mri_bin) ; MRIfree(&mri_dist); MRIfree(&mri_dist_sup); return(mri_dst_ctrl); }
static GCA_SAMPLE * find_control_points(GCA *gca, GCA_SAMPLE *gcas_total, int total_samples, int *pnorm_samples, int nregions, int label, MRI *mri_in, TRANSFORM *transform, double min_prior, double ctl_point_pct) { int i, j, *ordered_indices, nsamples, xmin, ymin, zmin, xmax, ymax, zmax, xv,yv,zv, x, y, z, xi, yi, zi, region_samples, used_in_region, prior_wsize=5, image_wsize=3, histo_peak, n, nbins ; GCA_SAMPLE *gcas, *gcas_region, *gcas_norm ; double means[MAX_GCA_INPUTS], vars[MAX_GCA_INPUTS], val, nsigma ; HISTOGRAM *histo, *hsmooth ; GC1D *gc ; float fmin, fmax ; MRI *mri_T1 = NULL ; if (label == Gdiag_no) DiagBreak() ; MRIvalRange(mri_in, &fmin, &fmax) ; nbins = (int)(fmax-fmin+1); histo = HISTOalloc(nbins) ; hsmooth = HISTOalloc(nbins) ; for (nsamples = i = 0 ; i < total_samples ; i++) { if (gcas_total[i].label != label) continue ; nsamples++ ; } *pnorm_samples = 0 ; printf("found %d control points for structure...\n", nsamples) ; if (nsamples == 0) { DiagBreak() ; return(NO_ERROR) ; } gcas = (GCA_SAMPLE *)calloc(nsamples, sizeof(GCA_SAMPLE)) ; gcas_region = (GCA_SAMPLE *)calloc(nsamples, sizeof(GCA_SAMPLE)) ; gcas_norm = (GCA_SAMPLE *)calloc(nsamples, sizeof(GCA_SAMPLE)) ; if (!gcas || !gcas_region || !gcas_norm) ErrorExit (ERROR_NOMEMORY, "find_control_points: could not allocate %d samples\n",nsamples); for (j = i = 0 ; i < total_samples ; i++) { if (gcas_total[i].label != label) continue ; memmove(&gcas[j], &gcas_total[i], sizeof(GCA_SAMPLE)) ; j++ ; } ordered_indices = (int *)calloc(nsamples, sizeof(int)) ; gcas_bounding_box(gcas, nsamples, &xmin, &ymin, &zmin, &xmax, &ymax, &zmax, label) ; printf("bounding box (%d, %d, %d) --> (%d, %d, %d)\n", xmin, ymin, zmin, xmax, ymax, zmax) ; for (x = 0 ; x < nregions ; x++) { for (y = 0 ; y < nregions ; y++) { for (z = 0 ; z < nregions ; z++) { /* only process samples in this region */ nsigma = 1.0 ; do { for (region_samples = i = 0 ; i < nsamples ; i++) { xi = (int)(nregions*(gcas[i].x - xmin) / (xmax-xmin+1)) ; yi = (int)(nregions*(gcas[i].y - ymin) / (ymax-ymin+1)) ; zi = (int)(nregions*(gcas[i].z - zmin) / (zmax-zmin+1)) ; if ((xi < 0 || xi >= nregions) || (yi < 0 || yi >= nregions) || (zi < 0 || zi >= nregions)) DiagBreak() ; xv = gcas[i].x ; yv = gcas[i].y ; zv = gcas[i].z ; if (xi != x || yi != y || zi != z || gcas[i].prior < min_prior) continue ; if (xv == Gx && yv == Gy && zv == Gz) DiagBreak() ; if (sqrt(SQR(xv-Gx)+SQR(yv-Gy)+SQR(zv-Gz)) < 2) DiagBreak() ; if (min_region_prior(gca, gcas[i].xp, gcas[i].yp, gcas[i].zp,prior_wsize, label) < min_prior) continue ; if (uniform_region(gca, mri_in, transform, xv, yv, zv, image_wsize, &gcas[i], nsigma) == 0) continue ; memmove(&gcas_region[region_samples], &gcas[i], sizeof(GCA_SAMPLE)) ; region_samples++ ; if (gcas[i].x == Gx && gcas[i].y == Gy && gcas[i].z == Gz) DiagBreak() ; } nsigma *= 1.1 ; } while (region_samples < 8 && nsigma < 3) ; if (region_samples < 8)/* can't reliably estimate statistics */ continue ; if (DIAG_VERBOSE_ON) printf("\t%d total samples found in region (%d, %d, %d)\n", region_samples,x, y,z) ; /* compute mean and variance of label within this region */ for (n = 0 ; n < mri_in->nframes ; n++) { HISTOclear(histo, histo) ; histo->bin_size = 1 ; for (means[n] = vars[n] = 0.0, i = 0 ; i < region_samples ; i++) { MRIsampleVolumeFrame (mri_in, gcas_region[i].x,gcas_region[i].y,gcas_region[i].z, n, &val) ; if (FZERO(val)) { if (i < (region_samples-1)) memmove(&gcas_region[i], &gcas_region[i+1], (region_samples-(i+1))*sizeof(GCA_SAMPLE)); i-- ; region_samples-- ; continue ; } histo->counts[(int)val]++ ; means[n] += val ; vars[n] += (val*val) ; } HISTOsmooth(histo, hsmooth, 2) ; histo_peak = HISTOfindHighestPeakInRegion(hsmooth, 1, hsmooth->nbins) ; if (histo_peak < 0) /* couldn't find a valid peak? */ break ; for (means[n] = vars[n] = 0.0, i = 0 ; i < region_samples ; i++) { if (gcas_region[i].label < 0) continue ; MRIsampleVolumeFrame (mri_in, gcas_region[i].x, gcas_region[i].y, gcas_region[i].z, n, &val) ; means[n] += val ; vars[n] += (val*val) ; } means[n] /= (double)region_samples ; vars[n] = vars[n] / (double)region_samples - means[n]*means[n] ; means[n] = histo_peak ; if (DIAG_VERBOSE_ON) printf("\tlabel %s[%d]: %2.1f +- %2.1f\n", cma_label_to_name(label), n, means[n], sqrt(vars[n])) ; } /* ignore GCA mean and variance - use image instead (otherwise bias field will mess us up) */ for (i = 0 ; i < region_samples ; i++) { int r ; for (r = 0 ; r < gca->ninputs ; r++) gcas_region[i].means[r] = means[r] ; /* gcas_region[i].var = var ;*/ } GCAcomputeLogSampleProbability (gca, gcas_region, mri_in, transform, region_samples) ; GCArankSamples (gca, gcas_region, region_samples, ordered_indices) ; GCAremoveOutlyingSamples (gca, gcas_region, mri_in, transform, region_samples, 2.0) ; for (used_in_region = i = 0 ; i < region_samples ; i++) { j = ordered_indices[i] ; if (gcas_region[j].label != label) /* it was an outlier */ continue ; memmove (&gcas_norm[*pnorm_samples], &gcas_region[j], sizeof(GCA_SAMPLE)) ; (*pnorm_samples)++ ; used_in_region++ ; } if ((used_in_region <= 0) && region_samples>0) { j = ordered_indices[0] ; /* gcas_region[j].label = label ;*/ printf("forcing use of sample %d @ (%d, %d, %d)\n", j, gcas_region[j].x, gcas_region[j].y, gcas_region[j].z) ; memmove(&gcas_norm[*pnorm_samples], &gcas_region[j], sizeof(GCA_SAMPLE)) ; (*pnorm_samples)++ ; used_in_region++ ; } if (DIAG_VERBOSE_ON) printf("\t%d samples used in region\n", used_in_region) ; } } } /* put gca means back into samples */ for (i = 0 ; i < *pnorm_samples ; i++) { gc = GCAfindPriorGC(gca, gcas_norm[i].xp, gcas_norm[i].yp, gcas_norm[i].zp, gcas_norm[i].label) ; if (gc) { int r, c, v ; for (v = r = 0 ; r < gca->ninputs ; r++) { for (c = r ; c < gca->ninputs ; c++, v++) { gcas_norm[i].means[v] = gc->means[v] ; gcas_norm[i].covars[v] = gc->covars[v] ; } } } } HISTOfree(&histo) ; HISTOfree(&hsmooth) ; free(gcas_region) ; free(gcas) ; if (mri_T1) MRIfree(&mri_T1) ; return(gcas_norm) ; }
static int discard_unlikely_control_points(GCA *gca, GCA_SAMPLE *gcas, int nsamples, MRI *mri_in, TRANSFORM *transform, char *name) { int i, xv, yv, zv, n, peak, start, end, num ; HISTO *h, *hsmooth ; float fmin, fmax ; Real val, mean_ratio ; if (nsamples == 0) return(NO_ERROR) ; for (num = n = 0 ; n < mri_in->nframes ; n++) { int niter = 0 ; MRIvalRangeFrame(mri_in, &fmin, &fmax, n) ; h = HISTOalloc(nint(fmax-fmin)+1) ; h->bin_size = (fmax-fmin)/(float)h->nbins ; for (i = 0 ; i < h->nbins ; i++) h->bins[i] = (i+1)*h->bin_size+fmin ; for (i = 0 ; i < nsamples ; i++) { xv = gcas[i].x ; yv = gcas[i].y ; zv = gcas[i].z ; if (xv == Gx && yv == Gy && zv == Gz) DiagBreak() ; MRIsampleVolumeFrame(mri_in, gcas[i].x,gcas[i].y,gcas[i].z, n, &val) ; if (FZERO(val)) DiagBreak() ; h->counts[nint(val-fmin)]++ ; } /* check to see if peak is unlikely */ hsmooth = HISTOsmooth(h, NULL, 2) ; do { if (gca->ninputs == 1) /* find brightest peak as for n=1 it is T1 weighted */ peak = HISTOfindLastPeak(hsmooth, HISTO_WINDOW_SIZE,MIN_HISTO_PCT); else peak = HISTOfindHighestPeakInRegion(hsmooth, 0, h->nbins-1) ; end = HISTOfindEndOfPeak(hsmooth, peak, 0.01) ; start = HISTOfindStartOfPeak(hsmooth, peak, 0.01) ; for (mean_ratio = 0.0, i = 0 ; i < nsamples ; i++) { mean_ratio += hsmooth->bins[peak] / gcas[i].means[0]; } mean_ratio /= (Real)nsamples ; HISTOclearBins (hsmooth, hsmooth, hsmooth->bins[start], hsmooth->bins[end]) ; if (niter++ > 5) break ; if (niter > 1) DiagBreak() ; } while (mean_ratio < 0.5 || mean_ratio > 2.0) ; printf("%s: limiting intensities to %2.1f --> %2.1f\n", name, fmin+start, fmin+end) ; for (i = 0 ; i < nsamples ; i++) { xv = gcas[i].x ; yv = gcas[i].y ; zv = gcas[i].z ; if (xv == Gx && yv == Gy && zv == Gz) DiagBreak() ; MRIsampleVolumeFrame(mri_in,gcas[i].x,gcas[i].y,gcas[i].z,n,&val) ; if (val-fmin < start || val-fmin > end) { num++ ; gcas[i].label = 0 ; } } HISTOfree(&h) ; HISTOfree(&hsmooth) ; } printf("%d of %d (%2.1f%%) samples deleted\n", num, nsamples, 100.0f*(float)num/(float)nsamples) ; return(NO_ERROR) ; }
MRI * MRIsynthesizeWeightedVolume(MRI *mri_T1, MRI *mri_PD, float w5, float TR5, float w30, float TR30, float target_wm, float TE) { MRI *mri_dst ; int x, y, z, width, height, depth ; MRI *mri30, *mri5 ; Real val30, val5, val, min_val ; #if 0 int mri_peak, n, min_real_bin ; double mean_PD ; MRI_REGION box ; HISTOGRAM *h_mri, *h_smooth ; float x0, y0, z0, min_real_val ; #endif width = mri_T1->width ; height = mri_T1->height ; depth = mri_T1->depth ; mri_dst = MRIalloc(width, height, depth, MRI_FLOAT) ; MRIcopyHeader(mri_T1, mri_dst) ; mri30 = MRIsynthesize(mri_T1, mri_PD, NULL, NULL, TR30, RADIANS(30), TE) ; mri5 = MRIsynthesize(mri_T1, mri_PD, NULL, NULL, TR5, RADIANS(5), TE) ; #if 0 mean_PD = MRImeanFrame(mri_PD, 0) ; /* MRIscalarMul(mri_PD, mri_PD, 1000.0f/mean_PD) ;*/ h_mri = MRIhistogram(mri30, 100) ; h_smooth = HISTOsmooth(h_mri, NULL, 2) ; mri_peak = HISTOfindHighestPeakInRegion(h_smooth, 0, h_smooth->nbins) ; min_real_bin = HISTOfindNextValley(h_smooth, mri_peak) ; min_real_val = h_smooth->bins[min_real_bin] ; MRIfindApproximateSkullBoundingBox(mri30, min_real_val, &box) ; x0 = box.x+box.dx/3 ; y0 = box.y+box.dy/3 ; z0 = box.z+box.dz/2 ; printf("using (%.0f, %.0f, %.0f) as brain centroid...\n",x0, y0, z0) ; box.dx /= 4 ; box.x = x0 - box.dx/2; box.dy /= 4 ; box.y = y0 - box.dy/2; box.dz /= 4 ; box.z = z0 - box.dz/2; printf("using box (%d,%d,%d) --> (%d, %d,%d) " "to find MRI wm\n", box.x, box.y, box.z, box.x+box.dx-1,box.y+box.dy-1, box.z+box.dz-1) ; h_mri = MRIhistogramRegion(mri30, 0, NULL, &box) ; for (n = 0 ; n < h_mri->nbins-1 ; n++) if (h_mri->bins[n+1] > min_real_val) break ; HISTOclearBins(h_mri, h_mri, 0, n) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) HISTOplot(h_mri, "mri.histo") ; mri_peak = HISTOfindLastPeak(h_mri, HISTO_WINDOW_SIZE,MIN_HISTO_PCT); mri_peak = h_mri->bins[mri_peak] ; printf("before smoothing, mri peak at %d\n", mri_peak) ; h_smooth = HISTOsmooth(h_mri, NULL, 2) ; if (Gdiag & DIAG_WRITE && DIAG_VERBOSE_ON) HISTOplot(h_smooth, "mri_smooth.histo") ; mri_peak = HISTOfindLastPeak(h_smooth, HISTO_WINDOW_SIZE,MIN_HISTO_PCT); mri_peak = h_mri->bins[mri_peak] ; printf("after smoothing, mri peak at %d\n", mri_peak) ; HISTOfree(&h_smooth) ; HISTOfree(&h_mri) ; #endif min_val = 0 ; for (x = 0 ; x < width ; x++) { for (y = 0 ; y < height ; y++) { for (z = 0 ; z < depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; MRIsampleVolumeType(mri30, x, y, z, &val30, SAMPLE_NEAREST) ; MRIsampleVolumeType(mri5, x, y, z, &val5, SAMPLE_NEAREST) ; val = w30*val30 + w5*val5 ; MRIFvox(mri_dst, x, y, z) = val ; if (val < min_val) min_val = val ; } } } for (x = 0 ; x < width ; x++) { for (y = 0 ; y < height ; y++) { for (z = 0 ; z < depth ; z++) { if (x == Gx && y == Gy && z == Gz) DiagBreak() ; MRIFvox(mri_dst, x, y, z) += min_val ; } } } MRIfree(&mri30) ; MRIfree(&mri5) ; return(mri_dst) ; }
int MRIShistoThresholdGaussianCurvatureToMarked(MRI_SURFACE *mris, double pct) { HISTOGRAM *h ; double min_curv, max_curv, K, bin_size, total, mode = 0.0, mode_peak, mean, std, dmean, dmin, dmax, dsigma ; int vno, num, b, bin_no, bin_thresh = 0, vno_min, vno_max, skipped, nvertices ; VERTEX *v ; dmean = MRIScomputeVertexSpacingStats(mris, &dsigma,&dmin, &dmax, &vno_min, &vno_max, CURRENT_VERTICES); min_curv = 1e8 ; max_curv = -min_curv ; // compute mean nbr spacing for each vertex so we can ignore tangles for (dmean = 0.0, num = vno = 0 ; vno < mris->nvertices ; vno++) { int n ; v = &mris->vertices[vno] ; if (v->ripflag) { continue ; } for (v->d = 0.0, n = 0 ; n < v->vtotal ; n++) { v->d += v->dist[n] ; } v->d /= v->vtotal ; dmean += v->d ; num++ ; } dmean /= num ; mean = std = 0.0 ; for (skipped = vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (v->ripflag) { continue ; } if (vno == Gdiag_no) { DiagBreak() ; } if (v->d < 0.01*dmean) { skipped++ ; continue ; } K = MIN(fabs(v->k1), fabs(v->k2)) ; K = fabs(v->K) ; if (K < min_curv) { min_curv = K ; } if (K > max_curv) { max_curv = K ; } mean += K ; std += K*K ; } nvertices = mris->nvertices - skipped ; max_curv = MIN(max_curv, 1000) ; mean /= (float)nvertices ; std = sqrt(std/(float)nvertices - mean*mean) ; bin_size = (max_curv - min_curv + 1) / NBINS ; h = HISTOalloc(NBINS) ; h->bin_size = bin_size ; for (b = 0 ; b < NBINS ; b++) { h->bins[b] = (float)b*bin_size + min_curv ; } for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (v->ripflag) { continue ; } if (v->d < 0.01*dmean) { continue ; } K = MIN(fabs(v->k1), fabs(v->k2)) ; K = fabs(v->K) ; bin_no = (int)((float)(K - min_curv) / (float)bin_size) ; if (bin_no > NBINS-1 || bin_no < 0) { bin_no = NBINS-1 ; } h->counts[bin_no]++ ; } mode_peak = 0 ; for (total = 0, b = 0 ; b < NBINS-1 ; b++) { if (h->counts[b] > mode_peak) { mode_peak = h->counts[b]; mode = h->bins[b] ; } total += h->counts[b] ; if (total/nvertices >= pct) { bin_thresh = b+1 ; break ; } #if 0 if (h->bins[b] > mean+10*std) { printf("setting threshold based on mean %2.2f + 4 * std %2.2f\n", mean, std) ; bin_thresh = b ; break ; } #endif } #if 0 { int b1, b2, prev_count, next_count, bthresh ; #define BWIN 3 for (b = BWIN ; b < NBINS ; b++) { prev_count = next_count = 0 ; // if sum of previous BWIN bins is <= sum of next BWIN bins, set thresh here for (b1 = MAX(b-BWIN,0) ; b1 < b ; b1++) { prev_count += h->counts[b1] ; } for (b2 = b+1 ; b2 < MIN(NBINS, b+BWIN) ; b2++) { next_count += h->counts[b2] ; } if (prev_count-3 <= next_count) { bthresh = b ; break ; } } if (bthresh > bin_thresh) { bin_thresh = bthresh ; // use more conservature of the two } } #endif if (bin_thresh == 0) { return(0) ; } if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON) { printf("mode at %2.2f, max %2.2f\n", mode, max_curv) ; } for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (vno == Gdiag_no) { DiagBreak() ; } if (v->ripflag) { continue ; } K = MIN(fabs(v->k1), fabs(v->k2)) ; K = fabs(v->K) ; bin_no = (int)((float)(K - min_curv) / (float)bin_size) ; if (bin_no >= bin_thresh) { if (vno == Gdiag_no) { DiagBreak() ; } v->marked = 1 ; } } for (vno = 0 ; vno < mris->nvertices ; vno++) { v = &mris->vertices[vno] ; if (v->ripflag) { continue ; } if (v->marked == 1) { int n ; VERTEX *vn ; for (n = 0 ; n < v->vtotal ; n++) { vn = &mris->vertices[v->v[n]] ; if (v->v[n] == Gdiag_no) { DiagBreak() ; } if (vn->marked == 0) { vn->marked = 2 ; } } } } HISTOfree(&h) ; return(NO_ERROR) ; }