diff options
author | Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl> | 2014-10-02 13:50:59 +0200 |
---|---|---|
committer | Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl> | 2015-01-19 11:15:56 +0100 |
commit | 3eb6f61e48f7ab6ddaa0e78d9140a4322dbb92fb (patch) | |
tree | 0e247879bc97dfc8427fd965aa7c3d3d47f7c935 /cuda/2d/sirt.cu | |
parent | 9715fadb1511277add807fc033c32d417fa6ffe0 (diff) | |
download | astra-3eb6f61e48f7ab6ddaa0e78d9140a4322dbb92fb.tar.gz astra-3eb6f61e48f7ab6ddaa0e78d9140a4322dbb92fb.tar.bz2 astra-3eb6f61e48f7ab6ddaa0e78d9140a4322dbb92fb.tar.xz astra-3eb6f61e48f7ab6ddaa0e78d9140a4322dbb92fb.zip |
Add CUDA SIRT::doSlabCorrections() function
This function optionally compensates for effectively infinitely large slab-like
objects of finite thickness 1.
Diffstat (limited to 'cuda/2d/sirt.cu')
-rw-r--r-- | cuda/2d/sirt.cu | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/cuda/2d/sirt.cu b/cuda/2d/sirt.cu index c7fe219..8dcd553 100644 --- a/cuda/2d/sirt.cu +++ b/cuda/2d/sirt.cu @@ -142,6 +142,51 @@ bool SIRT::precomputeWeights() return true; } +bool SIRT::doSlabCorrections() +{ + // This function compensates for effectively infinitely large slab-like + // objects of finite thickness 1. + + // Each ray through the object has an intersection of length d/cos(alpha). + // The length of the ray actually intersecting the reconstruction volume is + // given by D_lineWeight. By dividing by 1/cos(alpha) and multiplying by the + // lineweights, we correct for this missing attenuation outside of the + // reconstruction volume, assuming the object is homogeneous. + + // This effectively scales the output values by assuming the thickness d + // is 1 unit. + + + // This function in its current implementation only works if there are no masks. + // In this case, init() will also have already called precomputeWeights(), + // so we can use D_lineWeight. + if (useVolumeMask || useSinogramMask) + return false; + + // multiply by line weights + processSino<opDiv>(D_sinoData, D_lineWeight, projPitch, dims); + + SDimensions subdims = dims; + subdims.iProjAngles = 1; + + // divide by 1/cos(angle) + // ...but limit the correction to -80/+80 degrees. + float bound = cosf(1.3963f); + float* t = (float*)D_sinoData; + for (int i = 0; i < dims.iProjAngles; ++i) { + float f = fabs(cosf(angles[i])); + + if (f < bound) + f = bound; + + processSino<opMul>(t, f, sinoPitch, subdims); + t += sinoPitch; + } + + return true; +} + + bool SIRT::setMinMaxMasks(float* D_minMaskData_, float* D_maxMaskData_, unsigned int iPitch) { |