00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00029 #ifndef VOLUMETRICDATA_H
00030 #define VOLUMETRICDATA_H
00031
00032 #include <stddef.h>
00033
00035 class VolumetricData {
00036 public:
00037 double origin[3];
00038 double xaxis[3];
00039 double yaxis[3];
00040 double zaxis[3];
00041 int xsize, ysize, zsize;
00042 char *name;
00043 float *data;
00044
00045
00047 VolumetricData(const char *name, const float *origin,
00048 const float *xaxis, const float *yaxis, const float *zaxis,
00049 int xs, int ys, int zs, float *dataptr);
00050
00051 VolumetricData(const char *name, const double *origin,
00052 const double *xaxis, const double *yaxis, const double *zaxis,
00053 int xs, int ys, int zs, float *dataptr);
00054
00056 ~VolumetricData();
00057
00059 ptrdiff_t gridsize() const { return ptrdiff_t(xsize)*ptrdiff_t(ysize)*ptrdiff_t(zsize); }
00060
00062 void datarange(float &min, float &max);
00063
00065 void set_name(const char* name);
00066
00067
00070 float mean();
00071
00074 float sigma();
00075
00077 double integral();
00078
00080 void cell_lengths(float *xl, float *yl, float *zl) const;
00081
00083 void cell_axes(float *xax, float *yax, float *zax) const;
00084 void cell_axes(double *xax, double *yax, double *zax) const;
00085
00087 void cell_dirs(float *xax, float *yax, float *zax) const;
00088
00090 double cell_volume() const;
00091
00093 void set_volume_axes(float *xax, float *yax, float *zax) {
00094 for (int idx = 0; idx < 3; idx++) {
00095 xaxis[idx] = xax[idx];
00096 yaxis[idx] = yax[idx];
00097 zaxis[idx] = zax[idx];
00098 }
00099
00100
00101
00102
00103
00104
00105 invalidate_gradient();
00106 }
00107
00108 void set_volume_axes(double *xax, double *yax, double *zax) {
00109 for (int idx = 0; idx < 3; idx++) {
00110 xaxis[idx] = xax[idx];
00111 yaxis[idx] = yax[idx];
00112 zaxis[idx] = zax[idx];
00113 }
00114
00115
00116
00117
00118
00119
00120 invalidate_gradient();
00121 }
00122
00124 void scale_volume(double scalex, double scaley, double scalez) {
00125 for (int idx = 0; idx < 3; idx++) {
00126 xaxis[idx] *= scalex;
00127 yaxis[idx] *= scaley;
00128 zaxis[idx] *= scalez;
00129 }
00130
00131
00132
00133
00134
00135
00136 invalidate_gradient();
00137 }
00138
00140 void set_volume_origin(float *org) {
00141 for (int idx = 0; idx < 3; idx++) {
00142 origin[idx] = org[idx];
00143 }
00144
00145 }
00146
00147 void set_volume_origin(double *org) {
00148 for (int idx = 0; idx < 3; idx++) {
00149 origin[idx] = org[idx];
00150 }
00151
00152 }
00153
00154
00156 void voxel_coord_from_cartesian_coord(const float *carcoord, float *voxcoord, int shiftflag) const;
00157
00159 ptrdiff_t voxel_index_from_coord(float xpos, float ypos, float zpos) const;
00160
00162 inline float voxel_value(int x, int y, int z) const {
00163 return data[z*ptrdiff_t(xsize)*ptrdiff_t(ysize) + y*ptrdiff_t(xsize) + x];
00164 }
00165
00167 float voxel_value_safe(int x, int y, int z) const;
00168
00170 float voxel_value_interpolate(float xv, float yv, float zv) const;
00171
00173 float voxel_value_from_coord(float xpos, float ypos, float zpos) const;
00174 float voxel_value_interpolate_from_coord(float xpos, float ypos, float zpos) const;
00177 float voxel_value_from_coord_safe(float xpos, float ypos, float zpos) const;
00178 float voxel_value_interpolate_from_coord_safe(float xpos, float ypos, float zpos) const;
00179
00180
00182 const float *access_volume_gradient();
00183
00185 void set_volume_gradient(float *gradient);
00186
00188 void compute_volume_gradient(void);
00189
00190
00192 void voxel_gradient_fast(int x, int y, int z, float *grad) const {
00193 ptrdiff_t index = (z*ptrdiff_t(xsize)*ptrdiff_t(ysize) + y*ptrdiff_t(xsize) + x) * 3L;
00194 grad[0] = gradient[index ];
00195 grad[1] = gradient[index + 1];
00196 grad[2] = gradient[index + 2];
00197 }
00198
00200 void voxel_gradient_safe(int x, int y, int z, float *grad) const;
00201
00203 void voxel_gradient_interpolate(const float *voxcoord, float *gradient) const;
00204
00206 void voxel_gradient_from_coord(const float *coord, float *gradient) const;
00207 void voxel_gradient_interpolate_from_coord(const float *coord, float *gradient) const;
00208
00210 inline void voxel_coord(int x, int y, int z,
00211 float &gx, float &gy, float &gz) const {
00212 float xdelta[3], ydelta[3], zdelta[3];
00213 cell_axes(xdelta, ydelta, zdelta);
00214
00215 gx = float(origin[0] + (x * xdelta[0]) + (y * ydelta[0]) + (z * zdelta[0]));
00216 gy = float(origin[1] + (x * xdelta[1]) + (y * ydelta[1]) + (z * zdelta[1]));
00217 gz = float(origin[2] + (x * xdelta[2]) + (y * ydelta[2]) + (z * zdelta[2]));
00218 }
00219
00221 inline void voxel_coord(ptrdiff_t i, float &x, float &y, float &z) const {
00222 float xdelta[3], ydelta[3], zdelta[3];
00223 cell_axes(xdelta, ydelta, zdelta);
00224
00225 ptrdiff_t gz = i / (ptrdiff_t(ysize)*ptrdiff_t(xsize));
00226 ptrdiff_t gy = (i / xsize) % ysize;
00227 ptrdiff_t gx = i % xsize;
00228
00229 x = float(origin[0] + (gx * xdelta[0]) + (gy * ydelta[0]) + (gz * zdelta[0]));
00230 y = float(origin[1] + (gx * xdelta[1]) + (gy * ydelta[1]) + (gz * zdelta[1]));
00231 z = float(origin[2] + (gx * xdelta[2]) + (gy * ydelta[2]) + (gz * zdelta[2]));
00232 }
00233
00234
00235
00236
00237
00239 void pad(int padxm, int padxp, int padym, int padyp, int padzm, int padzp);
00240
00242 void crop(double crop_minx, double crop_miny, double crop_minz, double crop_maxx, double crop_maxy, double crop_maxz);
00243
00245 void clamp(float min_value, float max_value);
00246
00248 void scale_by(float ff);
00249
00251 void scalar_add(float ff);
00252
00254 void rescale_voxel_value_range(float min_value, float max_value);
00255
00257 void downsample();
00258
00260 void supersample();
00261
00264 void sigma_scale();
00265
00268 void binmask(float threshold=0.0f);
00269
00271 void gaussian_blur(double sigma);
00272
00274 void mdff_potential(float threshold);
00275
00276 private:
00277 float *gradient;
00278 bool gradient_isvalid;
00279 void invalidate_gradient();
00280
00281 bool minmax_isvalid;
00282 float cached_min;
00283 float cached_max;
00284
00285 bool mean_isvalid;
00286 float cached_mean;
00287
00288 bool sigma_isvalid;
00289 float cached_sigma;
00290
00291 void compute_minmaxmean();
00292 void invalidate_minmax();
00293 void compute_minmax();
00294
00295 void invalidate_mean();
00296 void compute_mean();
00297
00298 void invalidate_sigma();
00299 void compute_sigma();
00300
00301
00303 inline float cubic_interp(float y0, float y1, float y2, float y3, float mu) const {
00304 float mu2 = mu*mu;
00305 float a0 = y3 - y2 - y0 + y1;
00306 float a1 = y0 - y1 - a0;
00307 float a2 = y2 - y0;
00308 float a3 = y1;
00309
00310 return (a0*mu*mu2+a1*mu2+a2*mu+a3);
00311 }
00312
00313 };
00314
00315
00316
00317
00318
00319
00321 #define VOXEL_GRADIENT_FAST_IDX(gradientmap, index, newgrad) \
00322 { (newgrad)[0] = (gradientmap)[index ]; \
00323 (newgrad)[1] = (gradientmap)[index + 1]; \
00324 (newgrad)[2] = (gradientmap)[index + 2]; \
00325 }
00326
00328 #define VOXEL_GRADIENT_FAST(gradientmap, planesz, rowsz, x, y, z, newgrad) \
00329 { ptrdiff_t index = ((z)*(planesz) + (y)*(rowsz) + (x)) * 3L; \
00330 (newgrad)[0] = (gradientmap)[index ]; \
00331 (newgrad)[1] = (gradientmap)[index + 1]; \
00332 (newgrad)[2] = (gradientmap)[index + 2]; \
00333 }
00334
00335 #endif // VOLUMETRICDATA_H