/******************************************************************************** * Volatile - Volume Visualization Software for SAGE * Copyright (C) 2004 Electronic Visualization Laboratory, * University of Illinois at Chicago * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the distribution. * * Neither the name of the University of Illinois at Chicago nor * the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Direct questions, comments etc about Volatile to www.evl.uic.edu/cavern/forum *********************************************************************************/ #ifndef _CALCULUS_h #define _CALCULUS_h //======================== calculus =================================== //standard scalar derivative measure inline derivative3D(unsigned char *magV1, float *gradV3, const int sx, const int sy, const int sz, const unsigned char *dat) { float *tmp = new float[sx*sy*sz]; float maxm = 0; for(int i = 0; i < sz; ++i){ for(int j = 0; j < (sy); ++j){ for(int k = 0; k < (sx); ++k){ if((k<2)||(k>sx-3)||(j<2)||(j>sy-3)||(i<2)||(i>sz-3)){ gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = 0; tmp[i*sx*sy + j*sx + k] = 0; } else { int dx = dat[i*sx*sy + j*sx + (k+1)] - dat[i*sx*sy + j*sx + (k-1)]; int dy = dat[i*sx*sy + (j+1)*sx + k] - dat[i*sx*sy + (j-1)*sx + k]; int dz = dat[(i+1)*sx*sy + j*sx + k] - dat[(i-1)*sx*sy + j*sx + k]; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = (float)dx; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = (float)dy; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = (float)dz; tmp[i*sx*sy + j*sx + k] = (float)sqrt(dx*dx + dy*dy + dz*dz); maxm = maxm < tmp[i*sx*sy + j*sx + k] ? tmp[i*sx*sy + j*sx + k] : maxm; } } } } for( i = 0; i < sz; ++i){ for(int j = 0; j < sy; ++j){ for(int k = 0; k < sx; ++k){ magV1[i*sx*sy + j*sx + k] = (unsigned char)((tmp[i*sx*sy + j*sx + k]/maxm)*255); } } } delete[] tmp; } //standard scalar derivative measure - vgh volume (value grad hessian) inline derivative3DVGH(float *gradV3, const int sx, const int sy, const int sz, const unsigned char *dat) { //cerr << "hi!!!!!!!!!! " << sz << " " << sy << " " << sx << endl; for(int i = 0; i < sz; ++i){ for(int j = 0; j < (sy); ++j){ for(int k = 0; k < (sx); ++k){ if((k<1)||(k>sx-2)||(j<1)||(j>sy-2)||(i<1)||(i>sz-2)){ gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = 0; } else { int dx = dat[i*sx*sy*3 + j*sx*3 +(k+1)*3] - dat[i*sx*sy*3 + j*sx*3 + (k-1)*3]; int dy = dat[i*sx*sy*3 + (j+1)*sx*3 + k*3] - dat[i*sx*sy*3 + (j-1)*sx*3 + k*3]; int dz = dat[(i+1)*sx*sy*3 + j*sx*3 + k*3] - dat[(i-1)*sx*sy*3 + j*sx*3 + k*3]; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = (float)dx; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = (float)dy; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = (float)dz; } } } } } inline void addDer(unsigned char *magV1, float *gradV3, const int sx, const int sy, const int sz, const unsigned char *dat1, const unsigned char *dat2) { float *tmp = new float[sx*sy*sz]; float maxm = 0; for(int i = 0; i < sz; ++i){ for(int j = 0; j < (sy); ++j){ for(int k = 0; k < (sx); ++k){ if((k<2)||(k>sx-3)||(j<2)||(j>sy-3)||(i<2)||(i>sz-3)){ gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = 0; tmp[i*sx*sy + j*sx + k] = 0; } else { int dx1 = dat1[i*sx*sy + j*sx + (k+1)] - dat1[i*sx*sy + j*sx + (k-1)]; int dy1 = dat1[i*sx*sy + (j+1)*sx + k] - dat1[i*sx*sy + (j-1)*sx + k]; int dz1 = dat1[(i+1)*sx*sy + j*sx + k] - dat1[(i-1)*sx*sy + j*sx + k]; int dx2 = dat2[i*sx*sy + j*sx + (k+1)] - dat2[i*sx*sy + j*sx + (k-1)]; int dy2 = dat2[i*sx*sy + (j+1)*sx + k] - dat2[i*sx*sy + (j-1)*sx + k]; int dz2 = dat2[(i+1)*sx*sy + j*sx + k] - dat2[(i-1)*sx*sy + j*sx + k]; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = (float)(dx1 + dx2); gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = (float)(dy1 + dy2); gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = (float)(dz1 + dz2); tmp[i*sx*sy + j*sx + k] = (float)sqrt((dx1+dx2)*(dx1+dx2) + (dy1+dy2)*(dy1+dy2) + (dz1+dz2)*(dz1+dz2)); maxm = maxm < tmp[i*sx*sy + j*sx + k] ? tmp[i*sx*sy + j*sx + k] : maxm; } } } } for( i = 0; i < sz; ++i){ for(int j = 0; j < sy; ++j){ for(int k = 0; k < sx; ++k){ magV1[i*sx*sy + j*sx + k] = (unsigned char)((tmp[i*sx*sy + j*sx + k]/maxm)*255); } } } delete[] tmp; } template //compute an additive gradient inline int AGradArb(float *gradV3, //put it in here, create your data first int sx, int sy, int sz, //size of each axis int n, //first n elements of data to compute grad with int elts, //number of elements in the data T *data) //the data { #if 0 T **minmax = new T*[elts]; for(int e=0; esx-2)||(j<1)||(j>sy-2)||(i<1)||(i>sz-2)) { gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = 0; } else { gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1] = 0; gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2] = 0; for(int e=0; esx-2)||(j<1)||(j>sy-2)||(i<1)||(i>sz-2)){ tmph[i*sx*sy + j*sx + k] = 0; } else { float h[9]; h[0] = gradV3[i*sx*sy*3 + j*sx*3 + (k+1)*3 + 0] - gradV3[i*sx*sy*3 + j*sx*3 + (k-1)*3 + 0]; h[1] = gradV3[i*sx*sy*3 + (j+1)*sx*3 + k*3 + 0] - gradV3[i*sx*sy*3 + (j-1)*sx*3 + k*3 + 0]; h[2] = gradV3[(i+1)*sx*sy*3 + j*sx*3 + k*3 + 0] - gradV3[(i-1)*sx*sy*3 + j*sx*3 + k*3 + 0]; h[3] = gradV3[i*sx*sy*3 + j*sx*3 + (k+1)*3 + 1] - gradV3[i*sx*sy*3 + j*sx*3 + (k-1)*3 + 1]; h[4] = gradV3[i*sx*sy*3 + (j+1)*sx*3 + k*3 + 1] - gradV3[i*sx*sy*3 + (j-1)*sx*3 + k*3 + 1]; h[5] = gradV3[(i+1)*sx*sy*3 + j*sx*3 + k*3 + 1] - gradV3[(i-1)*sx*sy*3 + j*sx*3 + k*3 + 1]; h[6] = gradV3[i*sx*sy*3 + j*sx*3 + (k+1)*3 + 2] - gradV3[i*sx*sy*3 + j*sx*3 + (k-1)*3 + 2]; h[7] = gradV3[i*sx*sy*3 + (j+1)*sx*3 + k*3 + 2] - gradV3[i*sx*sy*3 + (j-1)*sx*3 + k*3 + 2]; h[8] = gradV3[(i+1)*sx*sy*3 + j*sx*3 + k*3 + 2] - gradV3[(i-1)*sx*sy*3 + j*sx*3 + k*3 + 2]; float tv[3]; float tg[3] = {gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 0]/tmpg[i*sx*sy + j*sx + k], gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 1]/tmpg[i*sx*sy + j*sx + k], gradV3[i*sx*sy*3 + j*sx*3 + k*3 + 2]/tmpg[i*sx*sy + j*sx + k]}; tv[0] = tg[0] * h[0] + tg[1] * h[1] + tg[2] * h[2]; tv[1] = tg[0] * h[3] + tg[1] + tg[2] * h[5]; tv[2] = tg[0] * h[6] + tg[1] * h[7] + tg[2] * h[8]; tmph[i*sx*sy + j*sx + k] = tg[0] * tv[0] + tg[1] * tv[1] + tg[2] * tv[2]; hmax = MAX(hess[i*sx*sy + j*sx + k], hmax); hmin = MIN(hess[i*sx*sy + j*sx + k], hmin); } } } } //now quantize to chars for(i = 0; i < sz; ++i){ for(int j = 0; j < (sy); ++j){ for(int k = 0; k < (sx); ++k){ gmag[i*sx*sy + j*sx + k] = (unsigned char)(tmpg[i*sx*sy + j*sx + k]/maxm * 255.0); if(hess[i*sx*sy + j*sx + k] < 0){ float th = (float)affine(hmin, tmph[i*sx*sy + j*sx + k], 0, 0, 1); //th = (float)(1.0-((1.0-th)*(1.0-th)*(1.0-th))); hess[i*sx*sy + j*sx + k] = (unsigned char)affine(0,th,1, 0, 255/3); } else { float th = (float)affine(0, tmph[i*sx*sy + j*sx + k], hmax, 0, 1); //th = (float)(1.0-((1.0-th)*(1.0-th)*(1.0-th))); hess[i*sx*sy + j*sx + k] = (unsigned char)affine(0,th,1,255/3,255/3*2); } } } } delete[] tmpg; delete[] tmph; } //float vector scale and bias to 8bit unsigned char inline void scalebias(unsigned char *ucgradV3, float *gradV3, int sx, int sy, int sz){ int stx = 3; int sty = sx*3; int stz = sy*sx*3; for(int i = 0; i