Exemple #1
0
void VolumeTexture::generateChargeTexture(float vmin, float vmax) {
  // need a volumetric dataset for this
  if (!v) return;

  int x, y, z;
  int addr, addr2;
  int daddr;
  float vscale, vrange;

  size[0] = v->xsize;
  size[1] = v->ysize;
  size[2] = v->zsize;
  for (int i=0; i<3; i++) {
    size[i] = nextpower2(size[i]);
  }
  int num = size[0]*size[1]*size[2];
  if (!allocateTextureMap(num)) return;

  vrange = vmax - vmin;
  if (fabs(vrange) < 0.00001)
    vscale = 0.0f;
  else
    vscale = 1.00001f / vrange;

  // map volume data scalars to colors
  for (z=0; z<v->zsize; z++) {
    for (y=0; y<v->ysize; y++) {
       addr = z * size[0] * size[1] + y * size[0];
      daddr = z * v->xsize * v->ysize + y * v->xsize;
      for (x=0; x<v->xsize; x++) {
        addr2 = (addr + x) * 3;
        float level, r, g, b;

        // map data to range 0->1        
        level = (v->data[daddr + x] - vmin) * vscale; 
        level = level < 0 ? 0 :
                level > 1 ? 1 : level;

        // low values are mapped to red, high to blue
        r = (1.0f - level) * 255.0f;
        b = level * 255.0f;
        if (level < 0.5f) {
          g = level * 2.0f * 128.0f;
        } else {
          g = (0.5f - (level - 0.5f)) * 2.0f * 128.0f;
        }

        texmap[addr2    ] = (unsigned char) r;
        texmap[addr2 + 1] = (unsigned char) g;
        texmap[addr2 + 2] = (unsigned char) b;
      }
    }
  }
}
Exemple #2
0
void VolumeTexture::generateHSVTexture(float vmin, float vmax) {
  int x, y, z;
  int index, addr, addr2, addr3;
  int daddr;
  float vscale, vrange;
  unsigned char coltable[3 * 4096];

  size[0] = v->xsize;
  size[1] = v->ysize;
  size[2] = v->zsize;
  for (int i=0; i<3; i++) {
    size[i] = nextpower2(size[i]);
  }
  int num = size[0]*size[1]*size[2];
  if (!allocateTextureMap(num)) return;

  // build a fast color lookup table
  for (index=0; index<4096; index++) {
    addr = index * 3;
    HSItoRGB(4.0f * index / 4096.0f, 0.75, 1.0,
             coltable+addr, coltable+addr+1, coltable+addr+2);
  }

  // calculate scaling factors
  vrange = vmax - vmin;
  if (fabs(vrange) < 0.00001)
    vscale = 0.0f;
  else
    vscale = 1.00001f / vrange;

  // map volume data scalars to colors
  for (z=0; z<v->zsize; z++) {
    for (y=0; y<v->ysize; y++) {
       addr = z * size[0] * size[1] + y * size[0];
      daddr = z * v->xsize * v->ysize + y * v->xsize;
      for (x=0; x<v->xsize; x++) {
        addr2 = (addr + x) * 3;
        float level;

        // map data to range 0->1        
        level = (v->data[daddr + x] - vmin) * vscale; 
        level = level < 0 ? 0 :
                level > 1 ? 1 : level;

        // map values to an HSV color map
        addr3 = ((int) (level * 4095)) * 3;
        texmap[addr2    ] = coltable[addr3    ];
        texmap[addr2 + 1] = coltable[addr3 + 1];
        texmap[addr2 + 2] = coltable[addr3 + 2];
      }
    }
  }
}
Exemple #3
0
void VolumeTexture::generateContourLineTexture(float densityperline, float linewidth) {
  int x, y, z;
  int addr, addr2;
  float xp, yp, zp;

printf("Contour lines...\n");
printf("range / densityperline: %f\n", log(v->datamax - v->datamin) / densityperline);

  size[0] = nextpower2(v->xsize*2);
  size[1] = nextpower2(v->ysize*2);
  size[2] = nextpower2(v->zsize*2);
  int num = size[0]*size[1]*size[2];
  if (!allocateTextureMap(num)) return;

  // map volume data scalars to contour line colors
  for (z=0; z<size[2]; z++) {
    zp = ((float) z / size[2]) * v->zsize;
    for (y=0; y<size[1]; y++) {
      addr = z * size[0] * size[1] + y * size[0];
      yp = ((float) y / size[1]) * v->ysize;
      for (x=0; x<size[0]; x++) {
        addr2 = (addr + x) * 3;
        xp = ((float) x / size[0]) * v->xsize;
        float level;

        level = float(fmod(log(v->voxel_value_interpolate(xp,yp,zp)), densityperline) / densityperline);

        if (level < linewidth) {
          texmap[addr2    ] = 0;
          texmap[addr2 + 1] = 0;
          texmap[addr2 + 2] = 0;
        } else {        
          texmap[addr2    ] = 255;
          texmap[addr2 + 1] = 255;
          texmap[addr2 + 2] = 255;
        }
      }
    }
  }
}
Exemple #4
0
void VolumeTexture::generateColorScaleTexture(float vmin, float vmax, const Scene *scene) {

  int x, y, z;
  int addr, addr2;
  int daddr;
  float vscale, vrange;

  size[0] = v->xsize;
  size[1] = v->ysize;
  size[2] = v->zsize;
  for (int i=0; i<3; i++) {
    size[i] = nextpower2(size[i]);
  }
  int num = size[0]*size[1]*size[2];
  if (!allocateTextureMap(num)) return;

  vrange = vmax - vmin;
  if (fabs(vrange) < 0.00001)
    vscale = 0.0f;
  else
    vscale = 1.00001f / vrange;

  // map volume data scalars to colors
  for (z=0; z<v->zsize; z++) {
    for (y=0; y<v->ysize; y++) {
       addr = z * size[0] * size[1] + y * size[0];
      daddr = z * v->xsize * v->ysize + y * v->xsize;
      for (x=0; x<v->xsize; x++) {
        addr2 = (addr + x) * 3;
        float level;

        // map data min/max to range 0->1
        // values must be clamped before use, since user-specified
        // min/max can cause out-of-range color indices to be generated
        level = (v->data[daddr + x] - vmin) * vscale; 

        int colindex = (int)(level * MAPCLRS-1);

        if (colindex < 0) 
          colindex = 0;
        else if (colindex >= MAPCLRS) 
          colindex = MAPCLRS-1;

        const float *rgb = scene->color_value(MAPCOLOR(colindex));
        texmap[addr2    ] = (unsigned char)(rgb[0]*255.0f);
        texmap[addr2 + 1] = (unsigned char)(rgb[1]*255.0f);
        texmap[addr2 + 2] = (unsigned char)(rgb[2]*255.0f);
      }
    }
  }
}
Exemple #5
0
int main(int argc, char* argv[])
{
    	bool verb, pow2;
    	char key[7], *mode;;
    	int n1, n2, n1padded, n2padded, num, dim, n[SF_MAX_DIM], npadded[SF_MAX_DIM], ii[SF_MAX_DIM];
	int i, j, i1, i2, index, nw, iter, niter, nthr, *pad;
    	float thr, pclip, normp;
    	float *dobs_t, *thresh, *mask;
    	fftwf_complex *mm, *dd, *dobs;
    	fftwf_plan fft1, ifft1, fftrem, ifftrem;/* execute plan for FFT and IFFT */
    	sf_file in, out, Fmask;	/* mask and I/O files*/ 

    	sf_init(argc,argv);	/* Madagascar initialization */
    	in=sf_input("in");	/* read the data to be interpolated */
    	out=sf_output("out"); 	/* output the reconstructed data */
    	Fmask=sf_input("mask");	/* read the (n-1)-D mask for n-D data */
 
    	if(!sf_getbool("verb",&verb))    	verb=false;
    	/* verbosity */
    	if(!sf_getbool("pow2",&pow2))    	pow2=false;
    	/* round up the length of each axis to be power of 2 */
    	if (!sf_getint("niter",&niter)) 	niter=100;
    	/* total number of iterations */
    	if (!sf_getfloat("pclip",&pclip)) 	pclip=10.;
    	/* starting data clip percentile (default is 10)*/
    	if ( !(mode=sf_getstring("mode")) ) 	mode = "exp";
    	/* thresholding mode: 'hard', 'soft','pthresh','exp';
	  'hard', hard thresholding;	   'soft', soft thresholding; 
	  'pthresh', generalized quasi-p;  'exp', exponential shrinkage */
    	if (pclip <=0. || pclip > 100.)	sf_error("pclip=%g should be > 0 and <= 100",pclip);
    	if (!sf_getfloat("normp",&normp)) 	normp=1.;
    	/* quasi-norm: normp<2 */
   	for (i=0; i < SF_MAX_DIM; i++) {/* dimensions */
		snprintf(key,3,"n%d",i+1);
		if (!sf_getint(key,n+i) && 
		    (NULL == in || !sf_histint(in,key,n+i))) break;
		/*( n# size of #-th axis )*/  
		sf_putint(out,key,n[i]);
    	}
    	if (0==i) sf_error("Need n1=");
    	dim=i;
    	pad=sf_intalloc (dim);
	for (i=0; i<dim; i++) pad[i]=0;
	sf_getints("pad",pad,dim); /* number of zeros to be padded for each axis */

    	n1=n[0];
    	n2=sf_leftsize(in,1);
	for (i=0; i<SF_MAX_DIM; i++) npadded[i]=1;
	npadded[0]=n1+pad[0];
	n1padded=npadded[0];
	n2padded=1;
	for (i=1; i<dim; i++){
	  npadded[i]=n[i]+pad[i];
	  if (pow2) {/* zero-padding to be power of 2 */
	    npadded[i]=nextpower2(n[i]);
	    fprintf(stderr,"n%d=%d n%dpadded=%d\n",i,n[i],i,npadded[i]);
	  }
	  n2padded*=npadded[i];
	}
	nw=npadded[0]/2+1;
	num=nw*n2padded;/* data: total number of elements in frequency domain */

    	/* allocate data and mask arrays */
	thresh=(float*)            malloc(nw*n2padded*sizeof(float));
    	dobs_t=(float*)      fftwf_malloc(n1padded*n2padded*sizeof(float));  /* time domain observation */
    	dobs=(fftwf_complex*)fftwf_malloc(nw*n2padded*sizeof(fftwf_complex));/* freq-domain observation */
    	dd=(fftwf_complex*)  fftwf_malloc(nw*n2padded*sizeof(fftwf_complex));
    	mm=(fftwf_complex*)  fftwf_malloc(nw*n2padded*sizeof(fftwf_complex));
 
    	if (NULL != sf_getstring("mask")){
		mask=sf_floatalloc(n2padded);
    	} else sf_error("mask needed!");

	/* initialize the input data and mask arrays */
	memset(dobs_t,0,n1padded*n2padded*sizeof(float));
	memset(mask,0,n2padded*sizeof(float));
	for (i=0; i<n1*n2; i+=n1){
	  sf_line2cart(dim,n,i,ii);
	  j=sf_cart2line(dim,npadded,ii);
	  sf_floatread(&dobs_t[j], n1, in);
	  sf_floatread(&mask[j/n1padded], 1, Fmask);
	}

	/* FFT for the 1st dimension and the remaining dimensions */
     	fft1=fftwf_plan_many_dft_r2c(1, &n1padded, n2padded, dobs_t, &n1padded, 1, n1padded, dobs, &n1padded, 1, nw, FFTW_MEASURE);
   	ifft1=fftwf_plan_many_dft_c2r(1, &n1padded, n2padded, dobs, &n1padded, 1, nw, dobs_t, &n1padded, 1, n1padded, FFTW_MEASURE);
	fftrem=fftwf_plan_many_dft(dim-1, &npadded[1], nw, dd, &npadded[1], nw, 1, dd, &npadded[1], nw, 1, FFTW_FORWARD, FFTW_MEASURE);
	ifftrem=fftwf_plan_many_dft(dim-1, &npadded[1], nw, dd, &npadded[1], nw, 1, dd, &npadded[1], nw, 1, FFTW_BACKWARD, FFTW_MEASURE);

	/* transform the data from time domain to frequency domain: dobs_t-->dobs */
	fftwf_execute(fft1);
	for(i=0; i<num; i++) dobs[i]/=sqrtf(n1padded);
	memset(mm,0,num*sizeof(fftwf_complex));

	/* Iterative Shrinkage-Thresholding (IST) Algorithm:
	   	mm^{k+1}=T[mm^k+A^* M^* (dobs-M A mm^k)] (M^*=M; Mdobs=dobs)
		   	=T[mm^k+A^*(dobs-M A mm^k)]; (k=0,1,...niter-1)
	   	dd^=A mm^; 
	*/
    	for(iter=0; iter<niter; iter++)
    	{
		/* dd<-- A mm^k */
		memcpy(dd, mm, num*sizeof(fftwf_complex));
		fftwf_execute(ifftrem);
		for(i=0; i<num; i++) dd[i]/=sqrtf(n2padded);

		/* apply mask: dd<--dobs-M A mm^k=dobs-M dd */
		for(i2=0; i2<n2padded; i2++)
		for(i1=0; i1<nw; i1++)
		{ 
			index=i1+nw*i2;
			dd[index]=dobs[index]-mask[i2]*dd[index];
		}

		/* mm^k += A^*(dobs-M A mm^k); dd=dobs-M A mm^k */
		fftwf_execute(fftrem);
		for(i=0; i<num; i++) mm[i]+=dd[i]/sqrtf(n2padded);		

		/* perform thresholding */
		for(i=0; i<num; i++)	thresh[i]=cabsf(mm[i]);
	   	nthr = 0.5+num*(1.-0.01*pclip);  /* round off */
	    	if (nthr < 0) nthr=0;
	    	if (nthr >= num) nthr=num-1;
		thr=sf_quantile(nthr, num, thresh);
		sf_cpthresh(mm, num, thr, normp, mode);

		if (verb) sf_warning("iteration %d;",iter+1);
    	}

	/* frequency--> time domain: dobs-->dobs_t */
	memcpy(dd, mm, num*sizeof(fftwf_complex));
	fftwf_execute(ifftrem);
	for(i=0; i<num; i++) dd[i]/=sqrtf(n2padded);
	memcpy(dobs, dd, num*sizeof(fftwf_complex));
	fftwf_execute(ifft1);
	for(i=0; i<n1padded*n2padded; i++) dobs_t[i]/=sqrtf(n1padded);
	
	for (i=0; i<n1*n2; i+=n1){
	  sf_line2cart(dim,n,i,ii);
	  j=sf_cart2line(dim,npadded,ii);
	  sf_floatwrite(&dobs_t[j],n1,out);
	}

	free(thresh);
	fftwf_free(dobs_t);
	fftwf_free(dobs);
	fftwf_free(dd);
	fftwf_free(mm);

    	exit(0);
}