summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/astra/ParallelBeamDistanceDrivenProjector2D.inl9
-rw-r--r--tests/python/test_line2d.py15
2 files changed, 17 insertions, 7 deletions
diff --git a/include/astra/ParallelBeamDistanceDrivenProjector2D.inl b/include/astra/ParallelBeamDistanceDrivenProjector2D.inl
index aedcee9..3a18c6f 100644
--- a/include/astra/ParallelBeamDistanceDrivenProjector2D.inl
+++ b/include/astra/ParallelBeamDistanceDrivenProjector2D.inl
@@ -72,7 +72,7 @@ void CParallelBeamDistanceDrivenProjector2D::projectBlock_internal(int _iProjFro
const int rowCount = m_pVolumeGeometry->getGridRowCount();
// Performance note:
- // This is not a very well optimizated version of the distance driven
+ // This is not a very well optimized version of the distance driven
// projector. The CPU projector model in ASTRA requires ray-driven iteration,
// which limits re-use of intermediate computations.
@@ -86,6 +86,9 @@ void CParallelBeamDistanceDrivenProjector2D::projectBlock_internal(int _iProjFro
const float32 Ex = m_pVolumeGeometry->getWindowMinX() + pixelLengthX*0.5f;
const float32 Ey = m_pVolumeGeometry->getWindowMaxY() - pixelLengthY*0.5f;
+ const float32 rayWidth = fabs(proj->fDetUX * proj->fRayY - proj->fDetUY * proj->fRayX) /
+ sqrt(proj->fRayX * proj->fRayX + proj->fRayY * proj->fRayY);
+
// loop detectors
for (int iDetector = _iDetFrom; iDetector < _iDetTo; ++iDetector) {
@@ -100,7 +103,7 @@ void CParallelBeamDistanceDrivenProjector2D::projectBlock_internal(int _iProjFro
if (vertical) {
const float32 RxOverRy = proj->fRayX/proj->fRayY;
- const float32 lengthPerRow = m_pVolumeGeometry->getPixelLengthX() * m_pVolumeGeometry->getPixelLengthY();
+ const float32 lengthPerRow = m_pVolumeGeometry->getPixelLengthX() * m_pVolumeGeometry->getPixelLengthY() / rayWidth;
const float32 deltac = -pixelLengthY * RxOverRy * inv_pixelLengthX;
const float32 deltad = 0.5f * fabs((proj->fDetUX - proj->fDetUY * RxOverRy) * inv_pixelLengthX);
@@ -157,7 +160,7 @@ void CParallelBeamDistanceDrivenProjector2D::projectBlock_internal(int _iProjFro
} else {
const float32 RyOverRx = proj->fRayY/proj->fRayX;
- const float32 lengthPerCol = m_pVolumeGeometry->getPixelLengthX() * m_pVolumeGeometry->getPixelLengthY();
+ const float32 lengthPerCol = m_pVolumeGeometry->getPixelLengthX() * m_pVolumeGeometry->getPixelLengthY() / rayWidth;
const float32 deltar = -pixelLengthX * RyOverRx * inv_pixelLengthY;
const float32 deltad = 0.5f * fabs((proj->fDetUY - proj->fDetUX * RyOverRx) * inv_pixelLengthY);
diff --git a/tests/python/test_line2d.py b/tests/python/test_line2d.py
index 5647053..3019277 100644
--- a/tests/python/test_line2d.py
+++ b/tests/python/test_line2d.py
@@ -516,21 +516,26 @@ class Test2DKernel(unittest.TestCase):
if DISPLAY and x > TOL:
display_mismatch(data, sinogram, a)
self.assertFalse(x > TOL)
- elif proj_type == 'distance_driven':
+ elif proj_type == 'distance_driven' and 'par' in type:
a = np.zeros(np.prod(astra.functions.geom_size(pg)), dtype=np.float32)
for i, (center, edge1, edge2) in enumerate(gen_lines(pg)):
- (xd, yd) = center[1] - center[0]
+ (src, det) = center
+ try:
+ detweight = pg['DetectorWidth']
+ except KeyError:
+ detweight = effective_detweight(src, det, pg['Vectors'][i//pg['DetectorCount'],4:6])
+ (xd, yd) = det - src
l = 0.0
if np.abs(xd) > np.abs(yd): # horizontal ray
y_seg = (ymin, ymax)
for j in range(rect_min[0], rect_max[0]):
x = origin[0] + (-0.5 * shape[0] + j + 0.5) * pixsize[0]
- l += intersect_ray_vertical_segment(edge1, edge2, x, y_seg) * pixsize[0]
+ l += intersect_ray_vertical_segment(edge1, edge2, x, y_seg) * pixsize[0] / detweight
else:
x_seg = (xmin, xmax)
for j in range(rect_min[1], rect_max[1]):
y = origin[1] + (+0.5 * shape[1] - j - 0.5) * pixsize[1]
- l += intersect_ray_horizontal_segment(edge1, edge2, y, x_seg) * pixsize[1]
+ l += intersect_ray_horizontal_segment(edge1, edge2, y, x_seg) * pixsize[1] / detweight
a[i] = l
a = a.reshape(astra.functions.geom_size(pg))
if not np.all(np.isfinite(a)):
@@ -578,6 +583,8 @@ class Test2DKernel(unittest.TestCase):
if DISPLAY and x > TOL:
display_mismatch(data, sinogram, a)
self.assertFalse(x > TOL)
+ else:
+ raise RuntimeError("Unsupported projector")
def multi_test(self, type, proj_type):
np.random.seed(seed)