summaryrefslogtreecommitdiffstats
path: root/cuda/2d/sirt.cu
diff options
context:
space:
mode:
authorWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2014-10-02 13:50:59 +0200
committerWillem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl>2015-01-19 11:15:56 +0100
commit3eb6f61e48f7ab6ddaa0e78d9140a4322dbb92fb (patch)
tree0e247879bc97dfc8427fd965aa7c3d3d47f7c935 /cuda/2d/sirt.cu
parent9715fadb1511277add807fc033c32d417fa6ffe0 (diff)
downloadastra-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.cu45
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)
{