diff --git a/public/fbp.js b/public/fbp.js index e9412f9..94904e0 100644 --- a/public/fbp.js +++ b/public/fbp.js @@ -90,3 +90,57 @@ export function applyRampFilter(projection) { ifft1D(re, im); return Array.from(re.slice(0, projection.length)); } + +export function applyFilter(projection, type = "ramp") { + const N = nextPow2(projection.length); + const re = new Float32Array(N); + const im = new Float32Array(N); + for (let i = 0; i < projection.length; i++) { + re[i] = projection[i]; + } + + fft1D(re, im); + + for (let i = 0; i < N / 2; i++) { + const normFreq = i / N; + const ramp = normFreq; + + let filter = 1; + + switch (type) { + case "ramp": + filter = ramp; + break; + case "shepp-logan": + const sinc = + normFreq === 0 + ? 1 + : Math.sin(Math.PI * normFreq) / (Math.PI * normFreq); + filter = ramp * sinc; + break; + case "hann": + filter = ramp * (0.5 + 0.5 * Math.cos(Math.PI * normFreq)); + break; + case "hamming": + filter = ramp * (0.54 + 0.46 * Math.cos(Math.PI * normFreq)); + break; + case "cosine": + filter = ramp * Math.cos((Math.PI * normFreq) / 2); + break; + case "none": + filter = 1; + break; + default: + console.warn(`Unknown filter type: ${type}. Defaulting to ramp.`); + filter = ramp; + } + + re[i] *= filter; + im[i] *= filter; + re[N - i - 1] *= filter; + im[N - i - 1] *= filter; + } + + ifft1D(re, im); + return Array.from(re.slice(0, projection.length)); +}