summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWim van Aarle <wimvanaarle@gmail.com>2015-03-06 17:20:02 +0100
committerWim van Aarle <wimvanaarle@gmail.com>2015-03-06 17:20:02 +0100
commit6f3217fc80380c02e69b363338941a91d721d47c (patch)
treee231dca419e7d3a1b868b1a7b603e2acbbc213d7
parent1af118ebea7bffe4eba070dca35127234d39b426 (diff)
downloadastra-6f3217fc80380c02e69b363338941a91d721d47c.tar.gz
astra-6f3217fc80380c02e69b363338941a91d721d47c.tar.bz2
astra-6f3217fc80380c02e69b363338941a91d721d47c.tar.xz
astra-6f3217fc80380c02e69b363338941a91d721d47c.zip
updated 'linear' kernal projector
-rw-r--r--include/astra/ParallelBeamLinearKernelProjector2D.h4
-rw-r--r--include/astra/ParallelBeamLinearKernelProjector2D.inl139
-rw-r--r--src/ParallelBeamLinearKernelProjector2D.cpp2
3 files changed, 139 insertions, 6 deletions
diff --git a/include/astra/ParallelBeamLinearKernelProjector2D.h b/include/astra/ParallelBeamLinearKernelProjector2D.h
index 855093a..3b84380 100644
--- a/include/astra/ParallelBeamLinearKernelProjector2D.h
+++ b/include/astra/ParallelBeamLinearKernelProjector2D.h
@@ -30,6 +30,7 @@ $Id$
#define _INC_ASTRA_PARALLELLINEARKERNELPROJECTOR
#include "ParallelProjectionGeometry2D.h"
+#include "ParallelVecProjectionGeometry2D.h"
#include "Float32Data2D.h"
#include "Projector2D.h"
@@ -185,6 +186,9 @@ protected:
void projectBlock_internal(int _iProjFrom, int _iProjTo,
int _iDetFrom, int _iDetTo, Policy& _policy);
+ template <typename Policy>
+ void projectBlock_internal_vector(int _iProjFrom, int _iProjTo,
+ int _iDetFrom, int _iDetTo, Policy& _policy);
};
diff --git a/include/astra/ParallelBeamLinearKernelProjector2D.inl b/include/astra/ParallelBeamLinearKernelProjector2D.inl
index 67e0d58..04577de 100644
--- a/include/astra/ParallelBeamLinearKernelProjector2D.inl
+++ b/include/astra/ParallelBeamLinearKernelProjector2D.inl
@@ -30,22 +30,37 @@ $Id$
template <typename Policy>
void CParallelBeamLinearKernelProjector2D::project(Policy& p)
{
- projectBlock_internal(0, m_pProjectionGeometry->getProjectionAngleCount(),
- 0, m_pProjectionGeometry->getDetectorCount(), p);
+ if (dynamic_cast<CParallelProjectionGeometry2D*>(m_pProjectionGeometry)) {
+ projectBlock_internal(0, m_pProjectionGeometry->getProjectionAngleCount(),
+ 0, m_pProjectionGeometry->getDetectorCount(), p);
+ } else if (dynamic_cast<CParallelVecProjectionGeometry2D*>(m_pProjectionGeometry)) {
+ projectBlock_internal_vector(0, m_pProjectionGeometry->getProjectionAngleCount(),
+ 0, m_pProjectionGeometry->getDetectorCount(), p);
+ }
}
template <typename Policy>
void CParallelBeamLinearKernelProjector2D::projectSingleProjection(int _iProjection, Policy& p)
{
- projectBlock_internal(_iProjection, _iProjection + 1,
- 0, m_pProjectionGeometry->getDetectorCount(), p);
+ if (dynamic_cast<CParallelProjectionGeometry2D*>(m_pProjectionGeometry)) {
+ projectBlock_internal(_iProjection, _iProjection + 1,
+ 0, m_pProjectionGeometry->getDetectorCount(), p);
+ } else if (dynamic_cast<CParallelVecProjectionGeometry2D*>(m_pProjectionGeometry)) {
+ projectBlock_internal_vector(_iProjection, _iProjection + 1,
+ 0, m_pProjectionGeometry->getDetectorCount(), p);
+ }
}
template <typename Policy>
void CParallelBeamLinearKernelProjector2D::projectSingleRay(int _iProjection, int _iDetector, Policy& p)
{
- projectBlock_internal(_iProjection, _iProjection + 1,
+ if (dynamic_cast<CParallelProjectionGeometry2D*>(m_pProjectionGeometry)) {
+ projectBlock_internal(_iProjection, _iProjection + 1,
_iDetector, _iDetector + 1, p);
+ } else if (dynamic_cast<CParallelVecProjectionGeometry2D*>(m_pProjectionGeometry)) {
+ projectBlock_internal_vector(_iProjection, _iProjection + 1,
+ _iDetector, _iDetector + 1, p);
+ }
}
//----------------------------------------------------------------------------------------
@@ -182,3 +197,117 @@ void CParallelBeamLinearKernelProjector2D::projectBlock_internal(int _iProjFrom,
}
+//----------------------------------------------------------------------------------------
+// PROJECT BLOCK - vector projection geometry
+template <typename Policy>
+void CParallelBeamLinearKernelProjector2D::projectBlock_internal_vector(int _iProjFrom, int _iProjTo, int _iDetFrom, int _iDetTo, Policy& p)
+{
+ // variables
+ float32 detX, detY, x, y, c, r, update_c, update_r, offset;
+ float32 lengthPerRow, lengthPerCol, inv_pixelLengthX, inv_pixelLengthY;
+ int iVolumeIndex, iRayIndex, row, col, iAngle, iDetector;
+
+ const SParProjection * proj = 0;
+ const CParallelVecProjectionGeometry2D* pVecProjectionGeometry = dynamic_cast<CParallelVecProjectionGeometry2D*>(m_pProjectionGeometry);
+
+ inv_pixelLengthX = 1.0f / m_pVolumeGeometry->getPixelLengthX();
+ inv_pixelLengthY = 1.0f / m_pVolumeGeometry->getPixelLengthY();
+
+ int colCount = m_pVolumeGeometry->getGridColCount();
+ int rowCount = m_pVolumeGeometry->getGridRowCount();
+
+ // loop angles
+ for (iAngle = _iProjFrom; iAngle < _iProjTo; ++iAngle) {
+
+ proj = &pVecProjectionGeometry->getProjectionVectors()[iAngle];
+
+ bool vertical = fabs(proj->fRayX) < fabs(proj->fRayY);
+ if (vertical) {
+ lengthPerRow = m_pVolumeGeometry->getPixelLengthX() * sqrt(proj->fRayY*proj->fRayY + proj->fRayX*proj->fRayX) / abs(proj->fRayY);
+ update_c = -m_pVolumeGeometry->getPixelLengthY() * (proj->fRayX/proj->fRayY) * inv_pixelLengthX;
+ } else {
+ lengthPerCol = m_pVolumeGeometry->getPixelLengthY() * sqrt(proj->fRayY*proj->fRayY + proj->fRayX*proj->fRayX) / abs(proj->fRayX);
+ update_r = -m_pVolumeGeometry->getPixelLengthX() * (proj->fRayY/proj->fRayX) * inv_pixelLengthY;
+ }
+
+ // loop detectors
+ for (iDetector = _iDetFrom; iDetector < _iDetTo; ++iDetector) {
+
+ iRayIndex = iAngle * m_pProjectionGeometry->getDetectorCount() + iDetector;
+
+ // POLICY: RAY PRIOR
+ if (!p.rayPrior(iRayIndex)) continue;
+
+ detX = proj->fDetSX + (iDetector+0.5f) * proj->fDetUX;
+ detY = proj->fDetSY + (iDetector+0.5f) * proj->fDetUY;
+
+ // vertically
+ if (vertical) {
+
+ // calculate x for row 0
+ x = detX + (proj->fRayX/proj->fRayY)*(m_pVolumeGeometry->pixelRowToCenterY(0)-detY);
+ c = (x - m_pVolumeGeometry->getWindowMinX()) * inv_pixelLengthX - 0.5f;
+
+ // for each row
+ for (row = 0; row < rowCount; ++row, c += update_c) {
+
+ col = int(c);
+ offset = c - float32(col);
+
+ if (col <= 0 || col >= colCount-1) continue;
+
+ iVolumeIndex = row * colCount + col;
+ // POLICY: PIXEL PRIOR + ADD + POSTERIOR
+ if (p.pixelPrior(iVolumeIndex)) {
+ p.addWeight(iRayIndex, iVolumeIndex, (1.0f - offset) * lengthPerRow);
+ p.pixelPosterior(iVolumeIndex);
+ }
+
+ iVolumeIndex++;
+ // POLICY: PIXEL PRIOR + ADD + POSTERIOR
+ if (p.pixelPrior(iVolumeIndex)) {
+ p.addWeight(iRayIndex, iVolumeIndex, offset * lengthPerRow);
+ p.pixelPosterior(iVolumeIndex);
+ }
+
+ }
+ }
+
+ // horizontally
+ else {
+
+ // calculate y for col 0
+ y = detY + (proj->fRayY/proj->fRayX)*(m_pVolumeGeometry->pixelColToCenterX(0)-detX);
+ r = (m_pVolumeGeometry->getWindowMaxY() - y) * inv_pixelLengthY - 0.5f;
+
+ // for each col
+ for (col = 0; col < colCount; ++col, r += update_r) {
+
+ int row = int(r);
+ offset = r - float32(row);
+
+ if (row <= 0 || row >= rowCount-1) continue;
+
+ iVolumeIndex = row * colCount + col;
+ // POLICY: PIXEL PRIOR + ADD + POSTERIOR
+ if (p.pixelPrior(iVolumeIndex)) {
+ p.addWeight(iRayIndex, iVolumeIndex, (1.0f - offset) * lengthPerCol);
+ p.pixelPosterior(iVolumeIndex);
+ }
+
+ iVolumeIndex += colCount;
+ // POLICY: PIXEL PRIOR + ADD + POSTERIOR
+ if (p.pixelPrior(iVolumeIndex)) {
+ p.addWeight(iRayIndex, iVolumeIndex, offset * lengthPerCol);
+ p.pixelPosterior(iVolumeIndex);
+ }
+
+ }
+ }
+
+ // POLICY: RAY POSTERIOR
+ p.rayPosterior(iRayIndex);
+
+ } // end loop detector
+ } // end loop angles
+} \ No newline at end of file
diff --git a/src/ParallelBeamLinearKernelProjector2D.cpp b/src/ParallelBeamLinearKernelProjector2D.cpp
index a710664..043db71 100644
--- a/src/ParallelBeamLinearKernelProjector2D.cpp
+++ b/src/ParallelBeamLinearKernelProjector2D.cpp
@@ -89,7 +89,7 @@ bool CParallelBeamLinearKernelProjector2D::_check()
// check base class
ASTRA_CONFIG_CHECK(CProjector2D::_check(), "ParallelBeamLinearKernelProjector2D", "Error in Projector2D initialization");
- ASTRA_CONFIG_CHECK(dynamic_cast<CParallelProjectionGeometry2D*>(m_pProjectionGeometry), "ParallelBeamLinearKernelProjector2D", "Unsupported projection geometry");
+ ASTRA_CONFIG_CHECK(dynamic_cast<CParallelProjectionGeometry2D*>(m_pProjectionGeometry) || dynamic_cast<CParallelVecProjectionGeometry2D*>(m_pProjectionGeometry), "ParallelBeamLinearKernelProjector2D", "Unsupported projection geometry");
/// TODO: ADD PIXEL H/W LIMITATIONS
ASTRA_CONFIG_CHECK(m_pVolumeGeometry->getPixelLengthX() == m_pVolumeGeometry->getPixelLengthY(), "ParallelBeamLinearKernelProjector2D", "Pixel height must equal pixel width.");