in src/engine/loaders/voltools.js [49:162]
gaussSmooth(volBuffer, xDim, yDim, zDim, gaussRadius, gaussSigma) {
// eslint-disable-next-line
const side = Math.floor(gaussRadius * 2 + 1);
// check valid arguments
const ERR_SIDE = -1;
const ERR_BAD_SIGMA = -2;
const ERR_DIM_NEGATIVE = -3;
const ERR_DIM_LARGE = -4;
const ERR_VOL_BUF_NULL = -5;
const ERR_WRONG_BUF_SIZE = -6;
if (side > GAUSS_SMOOTH_MAX_SIDE) {
return ERR_SIDE;
}
const SIGMA_MIN = 0.0;
const SIGMA_MAX = 8.0;
if (gaussSigma < SIGMA_MIN || gaussSigma > SIGMA_MAX) {
return ERR_BAD_SIGMA;
}
if (xDim <= 0 || yDim <= 0 || zDim <= 0) {
return ERR_DIM_NEGATIVE;
}
if (xDim > MAX_VOLUME_SIDE_INPUT || yDim > MAX_VOLUME_SIDE_INPUT || zDim > MAX_VOLUME_SIDE_INPUT) {
return ERR_DIM_LARGE;
}
// check valid buffer size
if (volBuffer === null) {
return ERR_VOL_BUF_NULL;
}
const bufSize = volBuffer.length;
if (bufSize < xDim * yDim * zDim) {
return ERR_WRONG_BUF_SIZE;
}
const side2 = side * side;
const side3 = side2 * side;
// eslint-disable-next-line
const koefSpatial = 1.0 / (2.0 * gaussSigma * gaussSigma);
// console.log(`Start Gauss smoothing`);
const xyzDim = xDim * yDim * zDim;
const volDst = new Uint8Array(xyzDim);
// if (volDst === null) {
// return -10;
// }
// Fill gauss convolution matrix
let weightSum = 0.0;
let off = 0;
for (let z = 0; z < side; z++) {
const dz = z - gaussRadius;
for (let y = 0; y < side; y++) {
const dy = y - gaussRadius;
for (let x = 0; x < side; x++) {
const dx = x - gaussRadius;
const dist2 = dx * dx + dy * dy + dz * dz;
const w = 1.0 / Math.exp(dist2 * koefSpatial);
this.m_gaussWeights[off] = w;
weightSum += this.m_gaussWeights[off];
off += 1;
} // for (x)
} // for (y)
} // for (z)
// Normalize gauss matrix
const scale = 1.0 / weightSum;
for (let x = 0; x < side3; x++) {
this.m_gaussWeights[x] *= scale;
}
const xyDim = xDim * yDim;
// process whole image using gauss matrix
for (let z = 0; z < zDim; z++) {
for (let y = 0; y < yDim; y++) {
for (let x = 0; x < xDim; x++) {
let sum = 0.0;
let offConv = 0;
for (let dz = -gaussRadius; dz <= +gaussRadius; dz++) {
let zz = z + dz;
zz = zz < 0 ? 0 : zz;
zz = zz >= zDim ? zDim - 1 : zz;
for (let dy = -gaussRadius; dy <= +gaussRadius; dy++) {
let yy = y + dy;
yy = yy < 0 ? 0 : yy;
yy = yy >= yDim ? yDim - 1 : yy;
for (let dx = -gaussRadius; dx <= +gaussRadius; dx++) {
let xx = x + dx;
xx = xx < 0 ? 0 : xx;
xx = xx >= xDim ? xDim - 1 : xx;
const w = this.m_gaussWeights[offConv];
offConv += 1;
const offImage = zz * xyDim + yy * xDim + xx;
const val = volBuffer[offImage];
sum += val * w;
} // for (dx)
} // for (dy)
} // for (dz)
let iSum = Math.floor(sum);
const MAX_BYTE = 255;
iSum = iSum <= MAX_BYTE ? iSum : MAX_BYTE;
const offImage = z * xyDim + y * xDim + x;
volDst[offImage] = iSum;
} // for (x)
} // for (y)
} // for (z)
// copy filtered volume back to source
// volBuffer.set(volDst, 0);
for (let i = 0; i < xyzDim; i++) {
volBuffer[i] = volDst[i];
}
// console.log(`End Gauss smoothing`);
return 1;
}