diff options
author | Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl> | 2019-03-29 16:01:02 +0100 |
---|---|---|
committer | Willem Jan Palenstijn <Willem.Jan.Palenstijn@cwi.nl> | 2019-09-25 14:10:08 +0200 |
commit | 15f53527e2f38e8eeb8bece79376b5e4686f3dd4 (patch) | |
tree | 70f91d342fbd6bb094ff19db05aa0e784b92bf02 | |
parent | 35957b6ef72749cdc520ded67a0eb8cdfd7ea655 (diff) | |
download | astra-15f53527e2f38e8eeb8bece79376b5e4686f3dd4.tar.gz astra-15f53527e2f38e8eeb8bece79376b5e4686f3dd4.tar.bz2 astra-15f53527e2f38e8eeb8bece79376b5e4686f3dd4.tar.xz astra-15f53527e2f38e8eeb8bece79376b5e4686f3dd4.zip |
Adjust distance driven kernels to line integral scaling
-rw-r--r-- | include/astra/ParallelBeamDistanceDrivenProjector2D.inl | 9 | ||||
-rw-r--r-- | tests/python/test_line2d.py | 15 |
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) |