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> | 2014-10-02 13:51:54 +0200 |
commit | 12fd6925502d3ead9b73498f44f9b2f9abbc9bea (patch) | |
tree | 10970caff57e8f6b127dc223f73270eb3a490dc8 /cuda/2d/sirt.cu | |
parent | 8188b0697751d7c7ec6fe3069d0fceb50ebd0c9e (diff) | |
download | astra-12fd6925502d3ead9b73498f44f9b2f9abbc9bea.tar.gz astra-12fd6925502d3ead9b73498f44f9b2f9abbc9bea.tar.bz2 astra-12fd6925502d3ead9b73498f44f9b2f9abbc9bea.tar.xz astra-12fd6925502d3ead9b73498f44f9b2f9abbc9bea.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 d34a180..98c7f09 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) { |