예제 #1
0
/*
** slicetime correction for non-constant TR
*/
void
VSlicetime_NC(VAttrList list, VShort minval, VFloat tdel,
              VBoolean slicetime_correction, float *onset_array, VString filename) {
    FILE *fp = NULL;
    VImage src;
    VAttrListPosn posn;
    VString buf, str;
    int b, r, c, i, j, nt = 0, mt = 0, val, del = 0;
    double xmin, xmax, sum, nx, estim_tr = 0;
    double *xx = NULL, *yy = NULL, xi, yi, slicetime = 0, u = 0;
    gsl_interp_accel *acc = NULL;
    gsl_spline *spline = NULL;
    xmin = (VShort) VRepnMinValue(VShortRepn);
    xmax = (VShort) VRepnMaxValue(VShortRepn);
    buf = VMalloc(LEN);
    /*
    ** read scan times from file, non-constant TR
    */
    if(strlen(filename) > 2) {
        fp = fopen(filename, "r");
        if(!fp)
            VError(" error opening file %s", filename);
        i = 0;
        while(!feof(fp)) {
            for(j = 0; j < LEN; j++)
                buf[j] = '\0';
            fgets(buf, LEN, fp);
            if(buf[0] == '%' || buf[0] == '#')
                continue;
            if(strlen(buf) < 2)
                continue;
            i++;
        }
        rewind(fp);
        nt = i;
        fprintf(stderr, " num timesteps: %d\n", nt);
        xx = (double *) VCalloc(nt, sizeof(double));
        yy = (double *) VCalloc(nt, sizeof(double));
        i = 0;
        sum = 0;
        while(!feof(fp)) {
            for(j = 0; j < LEN; j++)
                buf[j] = '\0';
            fgets(buf, LEN, fp);
            if(buf[0] == '%' || buf[0] == '#')
                continue;
            if(strlen(buf) < 2)
                continue;
            if(sscanf(buf, "%lf", &u) != 1)
                VError(" line %d: illegal input format", i + 1);
            xx[i] = u * 1000.0;  /* convert to millisec */
            if(i > 1)
                sum += xx[i] - xx[i - 1];
            i++;
        }
        fclose(fp);
        estim_tr = sum / (double)(nt - 2);
        fprintf(stderr, " average scan interval = %.3f sec\n", estim_tr / 1000.0);
    }
    /*
    ** process data
    */
    b = -1;
    for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) {
        if(VGetAttrRepn(& posn) != VImageRepn)
            continue;
        VGetAttrValue(& posn, NULL, VImageRepn, & src);
        if(VPixelRepn(src) != VShortRepn)
            continue;
        VSetAttr(VImageAttrList(src), "repetition_time", NULL, VLongRepn, (VLong)estim_tr);
        VExtractAttr(VImageAttrList(src), "MPIL_vista_0", NULL, VStringRepn, &str, FALSE);
        b++;
        if(VImageNRows(src) < 2)
            continue;
        /*
        ** get header info
        */
        if(VGetAttr(VImageAttrList(src), "slice_time", NULL,
                    VDoubleRepn, (VPointer) & slicetime) != VAttrFound && slicetime_correction && onset_array == NULL)
            VError(" 'slice_time' info missing");
        if(onset_array != NULL)
            slicetime = onset_array[b];
        if(nt != VImageNBands(src))
            VError(" inconsistent number of time steps, %d %d",
                   nt, VImageNBands(src));
        if(acc == NULL && slicetime_correction) {
            acc = gsl_interp_accel_alloc();
            spline = gsl_spline_alloc(gsl_interp_akima, nt);
            for(i = 0; i < 5; i++) {
                if(xx[i] / 1000.0 > tdel)
                    break;
            }
            del = i;
            fprintf(stderr, " The first %.2f secs (%d timesteps) will be replaced.\n", tdel, del);
        }
        /*
        ** loop through all voxels in current slice
        */
        if(slicetime_correction)
            fprintf(stderr, " slice: %3d,  %10.3f ms\r", b, slicetime);
        for(r = 0; r < VImageNRows(src); r++) {
            for(c = 0; c < VImageNColumns(src); c++) {
                if(VPixel(src, 0, r, c, VShort) < minval)
                    continue;
                /* replace first few time steps by average */
                if(del > 0) {
                    mt = del + 10;
                    if(mt > nt)
                        mt = nt;
                    sum = nx = 0;
                    for(i = del; i < mt; i++) {
                        sum += VPixel(src, i, r, c, VShort);
                        nx++;
                    }
                    if(nx < 1)
                        continue;
                    val = sum / nx;
                    for(i = 0; i < del; i++) {
                        VPixel(src, i, r, c, VShort) = val;
                    }
                }
                if(!slicetime_correction)
                    continue;
                /* correct for slicetime offsets using cubic spline interpolation */
                for(i = 0; i < nt; i++) {
                    yy[i] = VPixel(src, i, r, c, VShort);
                }
                gsl_spline_init(spline, xx, yy, nt);
                for(i = 1; i < nt; i++) {
                    xi = xx[i] - slicetime;
                    yi = gsl_spline_eval(spline, xi, acc);
                    val = (int)(yi + 0.49);
                    if(val > xmax)
                        val = xmax;
                    if(val < xmin)
                        val = xmin;
                    VPixel(src, i, r, c, VShort) = val;
                }
            }
        }
    }
    fprintf(stderr, "\n");
}
예제 #2
0
void VImageManager::prepareScaleValue()
{
	QPtrList<V_ImageRec>::iterator it = m_imageList.begin();

	unsigned int lastIndex = 90;

	if ( lastIndex >= m_imageList.count() )
		lastIndex = m_imageList.count();

	for ( unsigned int i = 0; i < lastIndex; i++ ) {

		VImage src = m_imageList.at( i );
		int ncols = VImageNColumns( src );
		int nrows = VImageNRows( src );
		int nbands = VImageNFrames( src );

		int npixels = nbands * nrows * ncols;
		int smin = ( int )VRepnMinValue( VShortRepn );
		int smax = ( int )VRepnMaxValue( VShortRepn );
		int i = 0, j = 0;
		int dim = 2 * smax + 1;

		float *histo = new float[dim];

		for ( j = 0; j < dim; j++ ) histo[j] = 0;

		VShort *src_pp = ( VShort * ) VImageData( src );

		for ( i = 0; i < ( int )( npixels ); i++ ) {
			j = *src_pp;
			src_pp ++;
			j -= smin;
			histo[j]++;
		}

		float sum = 0;

		for ( j = 0; j < dim; j++ ) sum += histo[j];

		for ( j = 0; j < dim; j++ ) histo[j] /= sum;

		sum  = 0;

		for ( j = 0; j < dim; j++ ) {
			sum += histo[j];

			if ( sum > m_black ) break;
		}

		int xmin = j + smin;

		sum = 0;

		for ( j = dim; j > 0; j-- ) {
			sum += histo[j];

			if ( sum > m_white ) break;
		}

		int xmax = j + smin;


		if ( xmin < m_xmin ) m_xmin = xmin;

		if ( xmax > m_xmax ) m_xmax = xmax;
	}
}
예제 #3
0
파일: KMeans.c 프로젝트: Rollmops/lipsia
int *
KMeans(gsl_matrix *mat, int nclusters, double *bic, double *aic) {
    int *labels = NULL, *bestlabels = NULL, *list = NULL;
    int i, j, s, dim, iter, nvectors, maxiter = 1000;
    double xmax, dmin, d, nx, mx, best, xbic = 0;
    double rss = 0;
    gsl_vector *kmean[N], *kmean_sav[N];
    gsl_vector *vec = NULL, *tmp = NULL;
    unsigned long int seed;
    gsl_rng *rx = NULL;
    const gsl_rng_type *T = NULL;
    /* random */
    seed = 35521738;
    gsl_rng_env_setup();
    T  = gsl_rng_default;
    rx = gsl_rng_alloc(T);
    gsl_rng_set(rx, (unsigned long int)seed);
    /* alloc */
    xmax = VRepnMaxValue(VDoubleRepn);
    dim = mat->size1;        /* vector length */
    nvectors = mat->size2;   /* num vectors (matrix columns) */
    vec = gsl_vector_calloc(dim);
    tmp = gsl_vector_calloc(dim);
    labels     = (int *) VCalloc(nvectors, sizeof(int));
    bestlabels = (int *) VCalloc(nvectors, sizeof(int));
    list       = (int *) VCalloc(nclusters, sizeof(int));
    for(i = 0; i < nclusters; i++) {
        kmean[i] = gsl_vector_calloc(dim);
        kmean_sav[i] = gsl_vector_calloc(dim);
    }
    /* ini */
    best = VRepnMaxValue(VDoubleRepn);
    /* best = 1.0e+999 !!!!!!!!!!!!!! */
    for(s = 0; s < 50; s++) {    /* try several starting values */
        Centers(nvectors, nclusters, list, rx);
        for(i = 0; i < nclusters; i++)
            gsl_matrix_get_col(kmean[i], mat, list[i]);
        /* iterations */
        for(iter = 0; iter < maxiter; iter++) {
            /* get nearest neighbour */
            for(j = 0; j < nvectors; j++) {
                gsl_matrix_get_col(vec, mat, j);
                dmin = xmax;
                for(i = 0; i < nclusters; i++) {
                    d = dist(kmean[i], vec);
                    if(d < dmin) {
                        dmin = d;
                        labels[j] = i;
                    }
                }
            }
            /* update cluster means */
            for(i = 0; i < nclusters; i++) {
                gsl_vector_memcpy(kmean_sav[i], kmean[i]);
                gsl_vector_set_zero(kmean[i]);
                nx = 0;
                for(j = 0; j < nvectors; j++) {
                    if(labels[j] != i)
                        continue;
                    gsl_matrix_get_col(vec, mat, j);
                    gsl_vector_add(kmean[i], vec);
                    nx++;
                }
                gsl_vector_scale(kmean[i], 1.0 / nx);
            }
            /* stop iterations if no significant changes occurr */
            d = 0;
            for(i = 0; i < nclusters; i++)
                d += dist(kmean[i], kmean_sav[i]);
            if(d < 1.0e-10)
                break;
        }
        /* residual sum of squares, RSS */
        rss = 0;
        for(i = 0; i < nclusters; i++) {
            for(j = 0; j < nvectors; j++) {
                if(labels[j] != i)
                    continue;
                gsl_matrix_get_col(vec, mat, j);
                rss += dist(kmean[i], vec);
            }
        }
        if(rss < best) {
            best = rss;
            for(j = 0; j < nvectors; j++)
                bestlabels[j] = labels[j];
        }
    }
    /* Bayesian information criterion (not very useful) */
    nx = (double)nvectors;
    mx = (double)nclusters;
    xbic = nx * log(best) + mx * log(nx);
    (*bic) = log(best) + log(nx) * mx / nx;
    (*aic) = log(best) + 2.0 * mx / nx;
    (*bic) = xbic;
    return bestlabels;
}
예제 #4
0
/*
** slicetime correction with constant TR
*/
void
VSlicetime(VAttrList list, VShort minval, VFloat tdel,
           VBoolean slicetime_correction, float *onset_array) {
    VImage src;
    VAttrListPosn posn;
    VString str, buf;
    int b, r, c, i, nt, mt, val, del = 0;
    double xmin, xmax, sum, nx;
    double *xx = NULL, *yy = NULL, xi, yi, tr = 0, xtr = 0, slicetime = 0;
    gsl_interp_accel *acc = NULL;
    gsl_spline *spline = NULL;
    xmin = (VShort) VRepnMinValue(VShortRepn);
    xmax = (VShort) VRepnMaxValue(VShortRepn);
    buf = VMalloc(256);
    /*
    ** process data
    */
    b = -1;
    for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) {
        if(VGetAttrRepn(& posn) != VImageRepn)
            continue;
        VGetAttrValue(& posn, NULL, VImageRepn, & src);
        if(VPixelRepn(src) != VShortRepn)
            continue;
        b++;
        if(VImageNRows(src) < 2)
            continue;
        /*
        ** get header info
        */
        if(VGetAttr(VImageAttrList(src), "slice_time", NULL,
                    VDoubleRepn, (VPointer) & slicetime) != VAttrFound && slicetime_correction && onset_array == NULL)
            VError(" 'slice_time' info missing");;
        if(onset_array != NULL)
            slicetime = onset_array[b];
        tr = 0;
        if(VGetAttr(VImageAttrList(src), "repetition_time", NULL,
                    VDoubleRepn, (VPointer) & tr) != VAttrFound) {
            tr = 0;
            if(VGetAttr(VImageAttrList(src), "MPIL_vista_0", NULL,
                        VStringRepn, (VPointer) & str) == VAttrFound) {
                sscanf(str, " repetition_time=%lf %s", &tr, buf);
            }
        }
        if(tr < 1)
            VError(" attribute 'repetition_time' missing");
        xtr = tr / 1000.0;
        del = (int)(tdel / xtr + 0.5);     /* num timesteps to be ignored */
        nt = VImageNBands(src);
        if(acc == NULL) {
            acc = gsl_interp_accel_alloc();
            spline = gsl_spline_alloc(gsl_interp_akima, nt);
            xx = (double *) VCalloc(nt, sizeof(double));
            yy = (double *) VCalloc(nt, sizeof(double));
            fprintf(stderr, " The first %.2f secs (%d timesteps) will be replaced.\n", tdel, del);
        }
        /*
        ** loop through all voxels in current slice
        */
        if(slicetime_correction)
            fprintf(stderr, " slice: %3d,  %10.3f ms,  TR: %.3f\r", b, slicetime, xtr);
        for(r = 0; r < VImageNRows(src); r++) {
            for(c = 0; c < VImageNColumns(src); c++) {
                if(VPixel(src, 0, r, c, VShort) < minval)
                    continue;
                /* replace first few time steps by average */
                if(del > 0) {
                    mt = del + 10;
                    if(mt > nt)
                        mt = nt;
                    sum = nx = 0;
                    for(i = del; i < mt; i++) {
                        sum += VPixel(src, i, r, c, VShort);
                        nx++;
                    }
                    if(nx < 1)
                        continue;
                    val = sum / nx;
                    for(i = 0; i < del; i++) {
                        VPixel(src, i, r, c, VShort) = val;
                    }
                }
                if(!slicetime_correction)
                    continue;
                /* correct for slicetime offsets using cubic spline interpolation */
                for(i = 0; i < nt; i++) {
                    xi = i;
                    xx[i] = xi * tr;
                    yy[i] = VPixel(src, i, r, c, VShort);
                }
                gsl_spline_init(spline, xx, yy, nt);
                for(i = 1; i < nt; i++) {
                    xi = xx[i] - slicetime;
                    yi = gsl_spline_eval(spline, xi, acc);
                    val = (int)(yi + 0.49);
                    if(val > xmax)
                        val = xmax;
                    if(val < xmin)
                        val = xmin;
                    VPixel(src, i, r, c, VShort) = val;
                }
            }
        }
    }
    fprintf(stderr, "\n");
}
예제 #5
0
파일: Contrast.c 프로젝트: Rollmops/via
/*!
\fn VImage VContrastShort(VImage src,VImage dest,VFloat percent,VFloat background)
\param src   input image  (short repn)
\param dest  output image  (ubyte repn)
*/
VImage
VContrastShort(VImage src,VImage dest,VFloat low,VFloat high)
{
  int nbands,nrows,ncols,npixels;
  float u,v,xmin,xmax,slope,sum;
  float *histo;
  int i,j,dim;
  VShort *src_pp;
  VUByte *dest_pp;
  double smin,smax;
  double percent1,percent2;

  if (VPixelRepn(src) != VShortRepn) VError(" input pixel repn must be short");

  nbands = VImageNBands(src);
  nrows  = VImageNRows(src);
  ncols  = VImageNColumns(src);
  npixels = nbands * nrows * ncols;

  dest = VSelectDestImage("VContrastShort",dest,nbands,nrows,ncols,VUByteRepn);
  if (! dest) VError(" err creating dest image");
  VFillImage(dest,VAllBands,0);


  smin = VRepnMinValue(VShortRepn);
  smax = VRepnMaxValue(VShortRepn);

  percent1 = low;    /* unten  */
  percent2 = high;   /* oben   */


  dim = 2.0 * smax + 1.0;
  histo = (float *) VCalloc(dim,sizeof(float));
  for (j=0; j<dim; j++) histo[j] = 0;


  src_pp = (VShort *) VImageData(src);
  for (i=0; i<npixels; i++) {
    j = *src_pp++;
    j -= smin;
    histo[j]++;
  }
 
  sum = 0;
  for (j=0; j<dim; j++) sum += histo[j];
  for (j=0; j<dim; j++) histo[j] /= sum;

  xmin = 0;
  sum  = 0;
  for (j=0; j<dim; j++) {
    sum += histo[j];
    if (sum > percent1) break;
  }
  xmin = j+smin;

  xmax = dim;
  sum = 0;
  for (j=dim; j>0; j--) {
    sum += histo[j];
    if (sum > percent2) break;
  }
  xmax = j+smin;


  slope = 255.0f / (xmax - xmin);
  
  src_pp  = (VShort *) VImageData(src);
  dest_pp = (VUByte *) VImageData(dest);
  for (i=0; i<npixels; i++) {
    u = *src_pp++;
    v = (int) (slope * (u - xmin) + 0.5);
    if (v < 0) v = 0;
    if (v > 255) v = 255;
    *dest_pp++ = (VUByte) v;
  }

  VFree(histo);
  VCopyImageAttrs (src, dest);
  return dest;
}
예제 #6
0
파일: Contrast.c 프로젝트: Rollmops/via
VImage
VHistoEqualize(VImage src,VImage dest,VFloat exponent)
{
  int nbands,nrows,ncols,npixels;
  float u,v,sum;
  float *histo,*p;
  int i,j,dim;
  VShort *src_pp;
  VUByte *dest_pp;
  double smin,smax,x,y;


  if (VPixelRepn(src) != VShortRepn) VError(" input pixel repn must be short");
  if (exponent < 0.5) VError("parameter '-exponent' should be >= 0.5"); 
  if (exponent > 10) VWarning("parameter '-exponent' should be < 10"); 

  nbands = VImageNBands(src);
  nrows  = VImageNRows(src);
  ncols  = VImageNColumns(src);
  npixels = nbands * nrows * ncols;

  dest = VSelectDestImage("VContrastShort",dest,nbands,nrows,ncols,VUByteRepn);
  if (! dest) VError(" err creating dest image");
  VFillImage(dest,VAllBands,0);


  y = (double) exponent;
  smin = VRepnMinValue(VShortRepn);
  smax = VRepnMaxValue(VShortRepn);

  dim = 2.0 * smax + 1.0;
  histo = (float *) VCalloc(dim,sizeof(float));
  for (j=0; j<dim; j++) histo[j] = 0;

  p = (float *) VCalloc(dim,sizeof(float));


  src_pp = (VShort *) VImageData(src);
  for (i=0; i<npixels; i++) {
    j = *src_pp++;
    j -= smin;
    if (j == 0) continue;
    histo[j]++;
  }
 
  sum = 0;
  for (j=0; j<dim; j++) sum += histo[j];
  for (j=0; j<dim; j++) histo[j] /= sum;


  /* cumulative hist */
  for (i=0; i<dim; i++) {
    sum = 0;
    for (j=0; j<=i; j++) sum += histo[j];
    p[i] = sum;
  }


  /* make lut */
  for (i=0; i<dim; i++) {
    x = (double)p[i];
    if (x > 0)
      p[i] = (float)(pow(x,y) * 255.0);
  }

  /* apply lut */
  src_pp  = (VShort *) VImageData(src);
  dest_pp = (VUByte *) VImageData(dest);
  for (i=0; i<npixels; i++) {
    u = *src_pp++;
    j = (int) (u-smin);
    v = (double)p[j];
    if (v < 0) v = 0;
    if (v > 255) v = 255;
    *dest_pp++ = (VUByte) v;
  }

  VFree(p);
  VFree(histo);
  VCopyImageAttrs (src, dest);
  return dest;
}
예제 #7
0
VImage VScaleIntensity(VImage src, double white, double black)
/* scale any input image to VUByte,
   mapping white (black) percent of the voxel to white (black) */
{
	int x, y, z, nx, ny, nz, i, range, maxshort;
	unsigned int lb, ub, limit, sum, *histo;
	double m, b, max, min, mean, var, v;
	VImage dst;
	
	maxshort = (int)(VRepnMaxValue(VShortRepn));
	histo = (unsigned int *)VCalloc(maxshort, sizeof(unsigned int));
	nx = VImageNColumns(src);
	ny = VImageNRows(src);	
	nz = VImageNBands(src);

	if (white < 0 || white > 100 || black < 0 || black > 100 || white+black >= 100)  {
		fprintf(stderr, "VScaleIntensity: illegal percentage given.\n");
		return 0;
	};
	
	/* first pass: find maximum and minimum values */
	VImageStats(src, VAllBands, &min, &max, &mean, &var);
	if (max == min) {
		fprintf(stderr, "VScaleIntensity: illegal data in image.\n");
		return 0;
	};
	b = min;
	m = (max-min) / (double)maxshort;

	/* second pass: build a histogram*/
	for (z = 0; z < nz; z++)  {
		for (y = 0; y < ny; y++)  {
			for (x = 0; x < nx; x++)  {
				v = VGetPixel(src, z, y, x);
				i = (int)((v-b)/m+0.5);
				histo[i]++;
			};
		};
	};

	/* throw away pc percent of the voxel below lb and pc percent above ub */
	limit = (black * nx * ny * nz) / 100;
        lb = 0; sum = 0;
        for (i = 0; i < maxshort; i++)  {
        	sum += histo[i];
        	if (sum >= limit) { lb = i; break; };
        };
	limit = (white * nx * ny * nz) / 100;
        ub = maxshort-1; sum = 0;
        for (i = maxshort-1; i >= 0; i--)  {
        	sum += histo[i];
        	if (sum >= limit) { ub = i; break; };
        };
	min = lb*m+b;
	max = ub*m+b;

	/* third pass: create and convert image */
	dst = VCreateImage(nz, ny, nx, VUByteRepn);
	if (dst == 0) return 0;
	
	range = 256;
        m = range / (max - min);
        b = range - (m * max);
	for (z = 0; z < nz; z++)  {
		for (y = 0; y < ny; y++)  {
			for (x = 0; x < nx; x++)  {
				v = VGetPixel(src, z, y, x);
				i = (int)(v * m + b + 0.5);
                        	if (i < 0) i = 0;
                        	else if (i >= range) i = range-1;
                        	VPixel(dst, z, y, x, VUByte) = i;
                	};
                };
        };
        VFree(histo);
	VCopyImageAttrs(src, dst);
        return dst;
}
예제 #8
0
파일: vbayes.c 프로젝트: Rollmops/lipsia
VAttrList
VBayes(VImage cbeta_images[], VImage sd_images[], int nimages, VBoolean level, VBoolean zscore) {
    VAttrList out_list = NULL;
    VImage dest = NULL, sigma_image = NULL;
    int    i, j, k, npixels;
    VFloat *dest_pp, *beta_pp[N], *sd_pp[N], *sigma_pp = NULL;
    VFloat pmin, pmax;
    double mean = 0, sigma = 0;
    float  rx, wsum, msum, w0, wx, s, msumold;
    float  result = 0;
    float  gmean[N], gvar[N];
    float  tiny = 1.0e-12;
    /*
    ** create output image
    */
    dest = VCopyImage(cbeta_images[0], NULL, VAllBands);
    if(!dest)
        return NULL;
    VFillImage(dest, VAllBands, 0);
    VSetAttr(VImageAttrList(dest), "num_images", NULL, VShortRepn, (VShort)nimages);
    VSetAttr(VImageAttrList(dest), "modality", NULL, VStringRepn, "bayes_map");
    VSetAttr(VImageAttrList(dest), "name", NULL, VStringRepn, "bayes");
    if(level == TRUE) {
        VSetAttr(VImageAttrList(dest), "modality", NULL, VStringRepn, "mean");
        VSetAttr(VImageAttrList(dest), "name", NULL, VStringRepn, "mean");
        sigma_image = VCopyImage(dest, NULL, VAllBands);
        if(!sigma_image)
            return NULL;
        VFillImage(sigma_image, VAllBands, 0);
        VSetAttr(VImageAttrList(sigma_image), "num_images", NULL, VShortRepn, (VShort)nimages);
        VSetAttr(VImageAttrList(sigma_image), "modality", NULL, VStringRepn, "std_dev");
        VSetAttr(VImageAttrList(sigma_image), "name", NULL, VStringRepn, "std_dev");
    }
    /*
    ** for each voxel
    */
    pmax = VRepnMinValue(VFloatRepn);
    pmin = VRepnMaxValue(VFloatRepn);
    npixels = VImageNPixels(cbeta_images[0]);
    for(i = 0; i < nimages; i++) {
        beta_pp[i] = (VFloat *) VImageData(cbeta_images[i]);
        sd_pp[i]   = (VFloat *) VImageData(sd_images[i]);
    }
    dest_pp = (VFloat *) VImageData(dest);
    if(level == TRUE)
        sigma_pp = (VFloat *) VImageData(sigma_image);
    for(j = 0; j < npixels; j++) {
        if(j % 10000 == 0)
            fprintf(stderr, "...%.2f%%\r", (float)100 * j / (float)npixels);
        result = mean = sigma = 0;
        /*
        ** read data from input images
        */
        for(k = 0; k < nimages; k++) {
            gmean[k] = *beta_pp[k]++;  /* mean c*beta */
            rx       = *sd_pp[k]++;    /* standard deviation of c*beta*/
            gvar[k]  = rx * rx;        /* variation of c*beta*/
        }
        /* see Box,Tiao, pp.17-18     calculate probability distribution */
        wsum = 0;
        msum = 0;
        w0 = 0;
        for(k = 0; k < nimages; k++) {    /* for each image */
            s = gvar[k];
            if(s < tiny)
                goto next;
            s = sqrt((double)s);
            if(s < tiny)
                goto next;
            wx = 1.0 / (s * s);
            wsum = w0 + wx;
            msumold = msum;
            msum = (w0 * msum  +  wx * gmean[k]) / wsum;
            w0 = wsum;
            sigma = 1.0 / sqrt(wsum);
        }
        if(wsum < tiny)
            goto next;
        /* resulting mean and std dev */
        mean = msum;
        sigma = 1.0 / sqrt(wsum);
        if(level == TRUE) {
            result = mean;
            goto next;
        }
        /* calculate probability under distribution */
        result = CumulativeNormal(mean, sigma);
        /* output */
        if(zscore) {
            /* CHECK HERE IF "1.0-" is correct */
            result = (float)p2z((double)(1.0 - result));
            if(mean < 0)
                result = -result;
            if(result >  20)
                result =  20;
            if(result < -20)
                result = -20;
        } else {
            result *= 100.0;
            if(result >  100)
                result =  100;
            if(mean < 0)
                result = -result;
        }
        if(result < pmin)
            pmin = result;
        if(result > pmax)
            pmax = result;
next:
        *dest_pp++ = result;
        if(level)
            *sigma_pp++ = sigma;
    }
    out_list = VCreateAttrList();
    fprintf(stderr, "...100.00%%\n");
    if(level == FALSE) {
        fprintf(stderr, "\n min: %.3f, max: %.3f\n", pmin, pmax);
        VAppendAttr(out_list, "zmap", NULL, VImageRepn, dest);
        return out_list;
    } else {
        VAppendAttr(out_list, "mean", NULL, VImageRepn, dest);
        VAppendAttr(out_list, "std_dev", NULL, VImageRepn, sigma_image);
        return out_list;
    }
    return NULL;
}
예제 #9
0
파일: GetTransf.c 프로젝트: karda/lipsia
VImage
VGetTrans(VImage ref, VImage src, int minval, int maxval,
          float pitch, float roll, float yaw, float shift[3], float shiftcorr,
          float offset, VShort scanwidth, VShort type) {
    VImage transform = NULL;
    VString str;
    long i, j, k, b, r, c, n = 6;
    float sb, sr, sc, range, range2;
    float theta, phi, psi;
    float theta0, phi0, psi0, step1, step2, angle;
    float theta1 = 0, phi1 = 0, psi1 = 0, sb1 = 0, sr1 = 0, sc1 = 0;
    float nx, u, deg;
    int    iter, maxiter;
    double d, dmin;
    char typename[40];
    const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
    gsl_multimin_fminimizer *s = NULL;
    gsl_vector *stepsizes = NULL, *p = NULL;
    gsl_multimin_function minex_func;
    size_t np = 6;
    struct my_params params;
    int status;
    double size, fret = 0;
    deg = (float) 180.0 / (float) PI;
    xminval = minval;
    xmaxval = maxval;
    itype = type;
    if(type == 0)
        sprintf(typename, "corr");
    if(type == 1)
        sprintf(typename, "MI");
    s1 = ref;
    s2 = src;
    nbands1 = VImageNBands(ref);
    nrows1  = VImageNRows(ref);
    ncols1  = VImageNColumns(ref);
    nbands2 = VImageNBands(src);
    nrows2  = VImageNRows(src);
    ncols2  = VImageNColumns(src);
    if(VPixelRepn(ref) != VUByteRepn)
        VError(" ref must be ubyte");
    if(VPixelRepn(src) != VUByteRepn)
        VError(" src must be ubyte");
    if(offset < 1)
        offset = 1;
    slicedist = offset;    /* distance between slices */
    center[0] = (float) nbands1 * 0.5;    /* center of rotation */
    center[1] = (float) nrows1 * 0.5;
    center[2] = (float) ncols1 * 0.5;
    bmin = rmin = cmin = VRepnMaxValue(VLongRepn);
    bmax = rmax = cmax = 0;
    ave2 = nx = 0;
    for(b = 0; b < nbands2; b++) {
        for(r = 0; r < nrows2; r++) {
            for(c = 0; c < ncols2; c++) {
                u = VPixel(src, b, r, c, VUByte);
                if(u > xminval && u < xmaxval) {
                    if(r > rmax)
                        rmax = r;
                    if(c > cmax)
                        cmax = c;
                    if(r < rmin)
                        rmin = r;
                    if(c < cmin)
                        cmin = c;
                    ave2 += u;
                    nx++;
                }
            }
        }
    }
    ave2 /= nx;
    ave1 = nx = 0;
    b = (int) VRint((float) nbands1 * 0.5);
    step2 = nbands2 + 2;
    for(b = 0; b < nbands1; b += (int)offset) {
        for(r = 0; r < nrows1; r += step2) {
            for(c = 0; c < ncols1; c += step2) {
                u = VPixel(ref, b, r, c, VUByte);
                if(u > minval && u < xmaxval) {
                    ave1 += u;
                    nx++;
                }
            }
        }
    }
    ave1 /= nx;
    /*
    ** get initial shift
    */
    range  = 30;
    range2 = 10;
    step1  = 2;
    psi0   = pitch / deg; /* set initial guesses of angles */
    phi0   = roll / deg;
    theta0 = yaw / deg;
    n = 6;
    p = gsl_vector_calloc(n);
    shift[0]  = center[0];
    shift[1] += center[1];
    shift[2] += center[2];
    dmin = VRepnMaxValue(VFloatRepn);
    for(sb = 0; sb < nbands1; sb += step1) {
        for(sr = -range2 + shift[1]; sr <= range2 + shift[1]; sr += step1) {
            for(sc = -range2 + shift[2]; sc <= range2 + shift[2]; sc += step1) {
                gsl_vector_set(p, 0, sb);
                gsl_vector_set(p, 1, sr);
                gsl_vector_set(p, 2, sc);
                gsl_vector_set(p, 3, psi0);
                gsl_vector_set(p, 4, psi0);
                gsl_vector_set(p, 5, theta0);
                if(type == 0)
                    d = func1(p, &params);
                else
                    d = func2(p, &params);
                if(d < dmin) {
                    dmin = d;
                    sb1 = sb;
                    sr1 = sr;
                    sc1 = sc;
                }
            }
        }
    }
    shift[0] = sb1;
    shift[1] = sr1;
    shift[2] = sc1;
    /*
    ** get both shift and rotation
    */
    if(scanwidth == 0) {
        maxiter = 2;
        angle = 9.0 / deg;
        step2 = 3.0 / deg;
        range = 6;
        step1 = 3;
    } else {
        maxiter = 3;
        angle = 12.0 / deg;
        step2 =  3.0 / deg;
        range = 12;
        step1 =  4;
    }
    psi0 = pitch / deg;
    phi0 = 0;
    theta0 = 0;
    psi = psi1 = psi0;
    phi = phi1 = phi0;
    theta = theta1 = theta0;
    gsl_vector_set(p, 0, shift[0]);
    gsl_vector_set(p, 1, shift[1]);
    gsl_vector_set(p, 2, shift[2]);
    gsl_vector_set(p, 3, psi0);
    gsl_vector_set(p, 4, phi0);
    gsl_vector_set(p, 5, theta0);
    if(type == 0)
        d = func1(p, &params);
    else
        d = func2(p, &params);
    if(verbose >= 1)
        fprintf(stderr, " %6.2f  %6.2f  %6.2f,  %6.2f  %6.2f  %6.2f,  %s: %7.4f\n",
                shift[0], shift[1], shift[2], psi0 * deg, phi0 * deg, theta0 * deg, typename, sqrt(ABS(d)));
    dmin = d;
    for(k = 0; k < maxiter; k++) {
        if(verbose >= 1)
            fprintf(stderr, "  shift range: %g (step=%g),  angle range: %g (step=%g)\n",
                    range, step1, angle * deg, step2 * deg);
        for(sb = -range + shift[0]; sb <= range + shift[0]; sb += step1) {
            for(sr = -range + shift[1]; sr <= range + shift[1]; sr += step1) {
                for(sc = -range + shift[2]; sc <= range + shift[2]; sc += step1) {
                    for(psi = psi0 - angle; psi <= psi0 + angle; psi += step2) {
                        for(phi = phi0 - angle; phi <= phi0 + angle; phi += step2) {
                            for(theta = theta0 - angle; theta <= theta0 + angle; theta += step2) {
                                gsl_vector_set(p, 0, sb);
                                gsl_vector_set(p, 1, sr);
                                gsl_vector_set(p, 2, sc);
                                gsl_vector_set(p, 3, psi);
                                gsl_vector_set(p, 4, phi);
                                gsl_vector_set(p, 5, theta);
                                if(type == 0)
                                    d = func1(p, &params);
                                else
                                    d = func2(p, &params);
                                if(d < dmin) {
                                    dmin = d;
                                    sb1  = sb;
                                    sr1  = sr;
                                    sc1  = sc;
                                    psi1 = psi;
                                    phi1 = phi;
                                    theta1 = theta;
                                    if(verbose >= 1)
                                        fprintf(stderr, " %6.2f  %6.2f  %6.2f,  %6.2f  %6.2f  %6.2f,  %s: %7.4f\n",
                                                sb, sr, sc, psi * deg, phi * deg, theta * deg, typename, sqrt(ABS(dmin)));
                                }
                            }
                        }
                    }
                }
            }
        }
        angle -= 3.0 / deg;
        step2 *= 0.5;
        if(step2 < 2.0 / deg)
            step2 = 2.0 / deg;
        if(scanwidth == 0)
            range -= 2;
        else
            range -= 3;
        step1 -= 1;
        if(step1 < 2)
            step1 = 2;
        psi0 = psi1;
        phi0 = phi1;
        theta0 = theta1;
        shift[0] = sb1;
        shift[1] = sr1;
        shift[2] = sc1;
    }
예제 #10
0
파일: GetTransf.c 프로젝트: karda/lipsia
/*
**  goal function 1, linear correlation
*/
double
func1(const gsl_vector *vec, void *params) {
    struct my_params *par = params;
    float u, v, nx1, nx2;
    float sum1, sum2, sum3;
    int b = 0, r, c, bb, rr, cc;
    float bx, rx, cx;
    float bx1, bx2, bx3, rx1, rx2, rx3;
    float phi, psi, theta, sb, sr, sc;
    int step;
    double corr;
    VDouble reject = VRepnMaxValue(VFloatRepn);
    step = 2 + nbands2;
    if(step > 8)
        step = 8;
    sb    = gsl_vector_get(vec, 0);
    sr    = gsl_vector_get(vec, 1);
    sc    = gsl_vector_get(vec, 2);
    psi   = gsl_vector_get(vec, 3);
    phi   = gsl_vector_get(vec, 4);
    theta = gsl_vector_get(vec, 5);
    rotation_matrix(psi, phi, theta);
    corr = 0;
    sum1 = sum2 = sum3 = 0;
    nx1 = nx2 = 0;
    for(b = 0; b < nbands2; b++) {
        bx = (float) b * slicedist;
        bx -= center[0];
        bx1 = rot[0][0] * bx;
        bx2 = rot[1][0] * bx;
        bx3 = rot[2][0] * bx;
        for(r = rmin; r < rmax; r += step) {
            rx = (float) r;
            rx -= center[1];
            rx1 = rot[0][1] * rx;
            rx2 = rot[1][1] * rx;
            rx3 = rot[2][1] * rx;
            for(c = cmin; c < cmax; c += step) {
                cx = (float) c;
                cx -= center[2];
                nx2++;
                bb = (int) VRint(bx1 + rx1 + rot[0][2] * cx + sb);
                if(bb < 0 || bb >= nbands1)
                    continue;
                rr = (int) VRint(bx2 + rx2 + rot[1][2] * cx + sr);
                if(rr < 0 || rr >= nrows1)
                    continue;
                cc = (int) VRint(bx3 + rx3 + rot[2][2] * cx + sc);
                if(cc < 0 || cc >= ncols1)
                    continue;
                u = VPixel(s1, bb, rr, cc, VUByte);
                if(u < xminval || u > xmaxval)
                    continue;
                u -= ave1;
                v = (float) VPixel(s2, b, r, c, VUByte) - ave2;
                sum1 += u * v;
                sum2 += u * u;
                sum3 += v * v;
                nx1++;
            }
        }
    }
    if(nx1 < nx2 * 0.33)
        return reject;
    if(sum2 *sum3 != 0)
        corr = (sum1 * sum1) / (sum2 * sum3);
    else
        corr = 1.0;
    return -corr;
}
예제 #11
0
파일: GetTransf.c 프로젝트: karda/lipsia
/*
**  goal function 2, mutual information
*/
double
func2(const gsl_vector *vec, void *params) {
    struct my_params *par = params;
    VDouble reject = VRepnMaxValue(VFloatRepn);
    int   i, j, n, m;
    float nx1, nx2;
    int   u, v;
    int   b = 0, r, c, bb, rr, cc;
    float bx, rx, cx;
    float bx1, bx2, bx3, rx1, rx2, rx3;
    float phi, psi, theta, sb, sr, sc;
    int   step;
    float nn[N][N];
    float sumi[N], sumj[N];
    float hxy, hx, hy, ixy, px, sum;
    float tiny = 1.0e-30;
    m = 16;
    m = 8;
    n = 256 / m;
    if(n > N)
        VError(" MI arrays too large");
    step = 2 + nbands2;
    if(step > 8)
        step = 8;
    sb    = gsl_vector_get(vec, 0);
    sr    = gsl_vector_get(vec, 1);
    sc    = gsl_vector_get(vec, 2);
    psi   = gsl_vector_get(vec, 3);
    phi   = gsl_vector_get(vec, 4);
    theta = gsl_vector_get(vec, 5);
    rotation_matrix(psi, phi, theta);
    for(i = 0; i < n; i++)
        for(j = 0; j < n; j++)
            nn[i][j] = 0;
    nx1 = nx2 = 0;
    for(b = 0; b < nbands2; b++) {
        bx = (float) b * slicedist;
        bx -= center[0];
        bx1 = rot[0][0] * bx;
        bx2 = rot[1][0] * bx;
        bx3 = rot[2][0] * bx;
        for(r = rmin; r < rmax; r += step) {
            rx = (float) r;
            rx -= center[1];
            rx1 = rot[0][1] * rx;
            rx2 = rot[1][1] * rx;
            rx3 = rot[2][1] * rx;
            for(c = cmin; c < cmax; c += step) {
                cx = (float) c;
                cx -= center[2];
                nx2++;
                bb = (int) VRint(bx1 + rx1 + rot[0][2] * cx + sb);
                if(bb < 0 || bb >= nbands1)
                    continue;
                rr = (int) VRint(bx2 + rx2 + rot[1][2] * cx + sr);
                if(rr < 0 || rr >= nrows1)
                    continue;
                cc = (int) VRint(bx3 + rx3 + rot[2][2] * cx + sc);
                if(cc < 0 || cc >= ncols1)
                    continue;
                u = (int) VPixel(s1, bb, rr, cc, VUByte);
                i = u / m;
                v = (int) VPixel(s2, b, r, c, VUByte);
                j = v / m;
                nn[i][j]++;
                nx1++;
            }
        }
    }
    if(nx1 < nx2 * 0.33)
        return reject;
    sum = 0;
    for(i = 0; i < n; i++) {
        sumi[i] = 0;
        for(j = 0; j < n; j++) {
            sumi[i] += nn[i][j];
            sum += nn[i][j];
        }
    }
    if(sum < tiny)
        return reject;
    for(j = 0; j < n; j++) {
        sumj[j] = 0;
        for(i = 0; i < n; i++)
            sumj[j] += nn[i][j];
    }
    hx = hy = 0;
    for(i = 0; i < n; i++) {
        if(sumi[i] > 0) {
            px  = sumi[i] / sum;
            hx -= px * log(px);
        }
        if(sumj[i] > 0) {
            px  = sumj[i] / sum;
            hy -= px * log(px);
        }
    }
    hxy = 0;
    for(i = 0; i < n; i++) {
        for(j = 0; j < n; j++) {
            if(nn[i][j] > 0) {
                px   = nn[i][j] / sum;
                hxy -= px * log(px);
            }
        }
    }
    ixy = hx + hy - hxy;
    return (double)(-ixy);
}