From a452bc6f1c450a7174ec257d052dfe3ce25b1623 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Tue, 3 Mar 2015 18:22:23 +0100 Subject: created parallel_vec geometry class --- src/ParallelVecProjectionGeometry2D.cpp | 239 ++++++++++++++++++++++++++++++++ src/Projector2D.cpp | 5 + 2 files changed, 244 insertions(+) create mode 100644 src/ParallelVecProjectionGeometry2D.cpp (limited to 'src') diff --git a/src/ParallelVecProjectionGeometry2D.cpp b/src/ParallelVecProjectionGeometry2D.cpp new file mode 100644 index 0000000..c1ed1c4 --- /dev/null +++ b/src/ParallelVecProjectionGeometry2D.cpp @@ -0,0 +1,239 @@ +/* +----------------------------------------------------------------------- +Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp + 2014-2015, CWI, Amsterdam + +Contact: astra@uantwerpen.be +Website: http://sf.net/projects/astra-toolbox + +This file is part of the ASTRA Toolbox. + + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see . + +----------------------------------------------------------------------- +$Id$ +*/ + +#include "astra/ParallelVecProjectionGeometry2D.h" + +#include +#include +#include + +using namespace std; + +namespace astra +{ + +//---------------------------------------------------------------------------------------- +// Default constructor. Sets all variables to zero. +CParallelVecProjectionGeometry2D::CParallelVecProjectionGeometry2D() +{ + _clear(); + m_pProjectionAngles = 0; +} + +//---------------------------------------------------------------------------------------- +// Constructor. +CParallelVecProjectionGeometry2D::CParallelVecProjectionGeometry2D(int _iProjectionAngleCount, + int _iDetectorCount, + const SParProjection* _pProjectionAngles) +{ + this->initialize(_iProjectionAngleCount, + _iDetectorCount, + _pProjectionAngles); +} + +//---------------------------------------------------------------------------------------- +// Copy Constructor +CParallelVecProjectionGeometry2D::CParallelVecProjectionGeometry2D(const CParallelVecProjectionGeometry2D& _projGeom) +{ + _clear(); + this->initialize(_projGeom.m_iProjectionAngleCount, + _projGeom.m_iDetectorCount, + _projGeom.m_pProjectionAngles); +} + +//---------------------------------------------------------------------------------------- +// Destructor. +CParallelVecProjectionGeometry2D::~CParallelVecProjectionGeometry2D() +{ + // TODO + delete[] m_pProjectionAngles; +} + + +//---------------------------------------------------------------------------------------- +// Initialization. +bool CParallelVecProjectionGeometry2D::initialize(int _iProjectionAngleCount, + int _iDetectorCount, + const SParProjection* _pProjectionAngles) +{ + m_iProjectionAngleCount = _iProjectionAngleCount; + m_iDetectorCount = _iDetectorCount; + m_pProjectionAngles = new SParProjection[m_iProjectionAngleCount]; + for (int i = 0; i < m_iProjectionAngleCount; ++i) + m_pProjectionAngles[i] = _pProjectionAngles[i]; + + // TODO: check? + + // success + m_bInitialized = _check(); + return m_bInitialized; +} + +//---------------------------------------------------------------------------------------- +// Initialization with a Config object +bool CParallelVecProjectionGeometry2D::initialize(const Config& _cfg) +{ + ASTRA_ASSERT(_cfg.self); + ConfigStackCheck CC("ParallelVecProjectionGeometry2D", this, _cfg); + + XMLNode* node; + + // TODO: Fix up class hierarchy... this class doesn't fit very well. + // initialization of parent class + //CProjectionGeometry2D::initialize(_cfg); + + // Required: DetectorCount + node = _cfg.self->getSingleNode("DetectorCount"); + ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry2D", "No DetectorRowCount tag specified."); + m_iDetectorCount = boost::lexical_cast(node->getContent()); + ASTRA_DELETE(node); + CC.markNodeParsed("DetectorCount"); + + // Required: Vectors + node = _cfg.self->getSingleNode("Vectors"); + ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry2D", "No Vectors tag specified."); + vector data = node->getContentNumericalArray(); + CC.markNodeParsed("Vectors"); + ASTRA_DELETE(node); + ASTRA_CONFIG_CHECK(data.size() % 6 == 0, "ParallelVecProjectionGeometry2D", "Vectors doesn't consist of 6-tuples."); + m_iProjectionAngleCount = data.size() / 6; + m_pProjectionAngles = new SParProjection[m_iProjectionAngleCount]; + + for (int i = 0; i < m_iProjectionAngleCount; ++i) { + SParProjection& p = m_pProjectionAngles[i]; + p.fRayX = data[6*i + 0]; + p.fRayY = data[6*i + 1]; + p.fDetUX = data[6*i + 4]; + p.fDetUY = data[6*i + 5]; + + // The backend code currently expects the corner of the detector, while + // the matlab interface supplies the center + p.fDetSX = data[6*i + 2] - 0.5f * m_iDetectorCount * p.fDetUX; + p.fDetSY = data[6*i + 3] - 0.5f * m_iDetectorCount * p.fDetUY; + } + + + + // success + m_bInitialized = _check(); + return m_bInitialized; +} + +//---------------------------------------------------------------------------------------- +// Clone +CProjectionGeometry2D* CParallelVecProjectionGeometry2D::clone() +{ + return new CParallelVecProjectionGeometry2D(*this); +} + +//---------------------------------------------------------------------------------------- +// is equal +bool CParallelVecProjectionGeometry2D::isEqual(CProjectionGeometry2D* _pGeom2) const +{ + if (_pGeom2 == NULL) return false; + + // try to cast argument to CParallelVecProjectionGeometry2D + CParallelVecProjectionGeometry2D* pGeom2 = dynamic_cast(_pGeom2); + if (pGeom2 == NULL) return false; + + // both objects must be initialized + if (!m_bInitialized || !pGeom2->m_bInitialized) return false; + + // check all values + if (m_iProjectionAngleCount != pGeom2->m_iProjectionAngleCount) return false; + if (m_iDetectorCount != pGeom2->m_iDetectorCount) return false; + + for (int i = 0; i < m_iProjectionAngleCount; ++i) { + if (memcmp(&m_pProjectionAngles[i], &pGeom2->m_pProjectionAngles[i], sizeof(m_pProjectionAngles[i])) != 0) return false; + } + + return true; +} + +//---------------------------------------------------------------------------------------- +// Is of type +bool CParallelVecProjectionGeometry2D::isOfType(const std::string& _sType) +{ + return (_sType == "parallel_vec"); +} + +//---------------------------------------------------------------------------------------- + +CVector3D CParallelVecProjectionGeometry2D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex /* = 0 */) +{ + CVector3D vOutput(0.0f, 0.0f, 0.0f); + + // not implemented + ASTRA_ASSERT(false); + + return vOutput; +} + +//---------------------------------------------------------------------------------------- + +void CParallelVecProjectionGeometry2D::getRayParams(int _iRow, int _iColumn, float32& _fT, float32& _fTheta) const +{ + // not implemented + ASTRA_ASSERT(false); +} + +//---------------------------------------------------------------------------------------- + +bool CParallelVecProjectionGeometry2D::_check() +{ + // TODO + return true; +} + + +//---------------------------------------------------------------------------------------- +// Get the configuration object +Config* CParallelVecProjectionGeometry2D::getConfiguration() const +{ + Config* cfg = new Config(); + cfg->initialize("ProjectionGeometry2D"); + cfg->self->addAttribute("type", "parallel_vec"); + cfg->self->addChildNode("DetectorCount", getDetectorCount()); + std::string vectors = ""; + for (int i = 0; i < m_iProjectionAngleCount; ++i) { + SParProjection& p = m_pProjectionAngles[i]; + vectors += boost::lexical_cast(p.fRayX) + ","; + vectors += boost::lexical_cast(p.fRayY) + ","; + vectors += boost::lexical_cast(p.fDetSX + 0.5f * m_iDetectorCount * p.fDetUX) + ","; + vectors += boost::lexical_cast(p.fDetSY + 0.5f * m_iDetectorCount * p.fDetUY) + ","; + vectors += boost::lexical_cast(p.fDetUX) + ","; + vectors += boost::lexical_cast(p.fDetUY); + if (i < m_iProjectionAngleCount-1) vectors += ';'; + } + cfg->self->addChildNode("Vectors", vectors); + return cfg; +} +//---------------------------------------------------------------------------------------- + + +} // namespace astra diff --git a/src/Projector2D.cpp b/src/Projector2D.cpp index 32a2956..b0ace92 100644 --- a/src/Projector2D.cpp +++ b/src/Projector2D.cpp @@ -28,6 +28,7 @@ $Id$ #include "astra/Projector2D.h" +#include "astra/ParallelVecProjectionGeometry2D.h" #include "astra/FanFlatProjectionGeometry2D.h" #include "astra/FanFlatVecProjectionGeometry2D.h" #include "astra/SparseMatrixProjectionGeometry2D.h" @@ -131,6 +132,10 @@ bool CProjector2D::initialize(const Config& _cfg) CFanFlatVecProjectionGeometry2D* pFanFlatVecProjectionGeometry = new CFanFlatVecProjectionGeometry2D(); pFanFlatVecProjectionGeometry->initialize(Config(node)); m_pProjectionGeometry = pFanFlatVecProjectionGeometry; + } else if (type == "parallel_vec") { + CParallelVecProjectionGeometry2D* pParallelVecProjectionGeometry = new CParallelVecProjectionGeometry2D(); + pParallelVecProjectionGeometry->initialize(Config(node)); + m_pProjectionGeometry = pParallelVecProjectionGeometry; } else { m_pProjectionGeometry = new CParallelProjectionGeometry2D(); m_pProjectionGeometry->initialize(Config(node)); -- cgit v1.2.3 From a215ef4fb4ce341885aa74db65a5873c16637e69 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Thu, 5 Mar 2015 16:29:07 +0100 Subject: updated 'line' kernel projector --- src/ParallelBeamLineKernelProjector2D.cpp | 108 +++++++++++++++--------------- 1 file changed, 55 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/ParallelBeamLineKernelProjector2D.cpp b/src/ParallelBeamLineKernelProjector2D.cpp index 5a23413..c94c024 100644 --- a/src/ParallelBeamLineKernelProjector2D.cpp +++ b/src/ParallelBeamLineKernelProjector2D.cpp @@ -88,7 +88,7 @@ bool CParallelBeamLineKernelProjector2D::_check() // check base class ASTRA_CONFIG_CHECK(CProjector2D::_check(), "ParallelBeamLineKernelProjector2D", "Error in Projector2D initialization"); - ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry), "ParallelBeamLineKernelProjector2D", "Unsupported projection geometry"); + ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(m_pProjectionGeometry), "ParallelBeamLineKernelProjector2D", "Unsupported projection geometry"); ASTRA_CONFIG_CHECK(m_pVolumeGeometry->getPixelLengthX() == m_pVolumeGeometry->getPixelLengthY(), "ParallelBeamLineKernelProjector2D", "Pixel height must equal pixel width."); @@ -162,61 +162,63 @@ void CParallelBeamLineKernelProjector2D::computeSingleRayWeights(int _iProjectio // Project Point std::vector CParallelBeamLineKernelProjector2D::projectPoint(int _iRow, int _iCol) { - float32 xUL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yUL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; - float32 xUR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yUR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; - float32 xLL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yLL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; - float32 xLR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yLR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; - std::vector res; - // loop projectors and detectors - for (int iProjection = 0; iProjection < m_pProjectionGeometry->getProjectionAngleCount(); ++iProjection) { - - // get projection angle - float32 theta = m_pProjectionGeometry->getProjectionAngle(iProjection); - if (theta >= 7*PIdiv4) theta -= 2*PI; - bool inverse = false; - if (theta >= 3*PIdiv4) { - theta -= PI; - inverse = true; - } - - // calculate distance from the center of the voxel to the ray though the origin - float32 tUL = xUL * cos(theta) + yUL * sin(theta); - float32 tUR = xUR * cos(theta) + yUR * sin(theta); - float32 tLL = xLL * cos(theta) + yLL * sin(theta); - float32 tLR = xLR * cos(theta) + yLR * sin(theta); - if (inverse) { - tUL *= -1.0f; - tUR *= -1.0f; - tLL *= -1.0f; - tLR *= -1.0f; - } - float32 tMin = min(tUL, min(tUR, min(tLL,tLR))); - float32 tMax = max(tUL, max(tUR, max(tLL,tLR))); - - // calculate the offset on the detectorarray (in indices) - int dmin = (int)floor(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMin)); - int dmax = (int)ceil(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMax)); - - // add affected detectors to the list - for (int i = dmin; i <= dmax; ++i) { - if (i >= 0 && i < m_pProjectionGeometry->getDetectorCount()) { - SDetector2D det; - det.m_iAngleIndex = iProjection; - det.m_iDetectorIndex = i; - det.m_iIndex = iProjection * getProjectionGeometry()->getDetectorCount() + i; - res.push_back(det); - } - } - } - - // return result vector return res; + // float32 xUL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yUL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; + // float32 xUR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yUR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; + // float32 xLL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yLL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; + // float32 xLR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yLR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; + + // std::vector res; + // // loop projectors and detectors + // for (int iProjection = 0; iProjection < m_pProjectionGeometry->getProjectionAngleCount(); ++iProjection) { + + // // get projection angle + // float32 theta = m_pProjectionGeometry->getProjectionAngle(iProjection); + // if (theta >= 7*PIdiv4) theta -= 2*PI; + // bool inverse = false; + // if (theta >= 3*PIdiv4) { + // theta -= PI; + // inverse = true; + // } + + // // calculate distance from the center of the voxel to the ray though the origin + // float32 tUL = xUL * cos(theta) + yUL * sin(theta); + // float32 tUR = xUR * cos(theta) + yUR * sin(theta); + // float32 tLL = xLL * cos(theta) + yLL * sin(theta); + // float32 tLR = xLR * cos(theta) + yLR * sin(theta); + // if (inverse) { + // tUL *= -1.0f; + // tUR *= -1.0f; + // tLL *= -1.0f; + // tLR *= -1.0f; + // } + // float32 tMin = min(tUL, min(tUR, min(tLL,tLR))); + // float32 tMax = max(tUL, max(tUR, max(tLL,tLR))); + + // // calculate the offset on the detectorarray (in indices) + // int dmin = (int)floor(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMin)); + // int dmax = (int)ceil(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMax)); + + // // add affected detectors to the list + // for (int i = dmin; i <= dmax; ++i) { + // if (i >= 0 && i < m_pProjectionGeometry->getDetectorCount()) { + // SDetector2D det; + // det.m_iAngleIndex = iProjection; + // det.m_iDetectorIndex = i; + // det.m_iIndex = iProjection * getProjectionGeometry()->getDetectorCount() + i; + // res.push_back(det); + // } + // } + // } + + // // return result vector + // return res; } //---------------------------------------------------------------------------------------- -- cgit v1.2.3 From 6f3217fc80380c02e69b363338941a91d721d47c Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Fri, 6 Mar 2015 17:20:02 +0100 Subject: updated 'linear' kernal projector --- src/ParallelBeamLinearKernelProjector2D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') 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(m_pProjectionGeometry), "ParallelBeamLinearKernelProjector2D", "Unsupported projection geometry"); + ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(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."); -- cgit v1.2.3 From 043005e280194ab529bae7863ba50d33f34daa42 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Wed, 11 Mar 2015 14:12:39 +0100 Subject: updated 'strip' kernel projector --- src/ParallelBeamStripKernelProjector2D.cpp | 100 ++++++++++++++--------------- 1 file changed, 50 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/ParallelBeamStripKernelProjector2D.cpp b/src/ParallelBeamStripKernelProjector2D.cpp index 44c6fec..bb693a2 100644 --- a/src/ParallelBeamStripKernelProjector2D.cpp +++ b/src/ParallelBeamStripKernelProjector2D.cpp @@ -88,7 +88,7 @@ bool CParallelBeamStripKernelProjector2D::_check() // check base class ASTRA_CONFIG_CHECK(CProjector2D::_check(), "ParallelBeamStripKernelProjector2D", "Error in Projector2D initialization"); - ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry), "ParallelBeamStripKernelProjector2D", "Unsupported projection geometry"); + ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(m_pProjectionGeometry), "ParallelBeamStripKernelProjector2D", "Unsupported projection geometry"); ASTRA_CONFIG_CHECK(m_pVolumeGeometry->getPixelLengthX() == m_pVolumeGeometry->getPixelLengthY(), "ParallelBeamStripKernelProjector2D", "Pixel height must equal pixel width."); @@ -164,57 +164,57 @@ void CParallelBeamStripKernelProjector2D::computeSingleRayWeights(int _iProjecti // Splat a single point std::vector CParallelBeamStripKernelProjector2D::projectPoint(int _iRow, int _iCol) { - float32 xUL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yUL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; - float32 xUR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yUR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; - float32 xLL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yLL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; - float32 xLR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; - float32 yLR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; + // float32 xUL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yUL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; + // float32 xUR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yUR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) - m_pVolumeGeometry->getPixelLengthY() * 0.5f; + // float32 xLL = m_pVolumeGeometry->pixelColToCenterX(_iCol) - m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yLL = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; + // float32 xLR = m_pVolumeGeometry->pixelColToCenterX(_iCol) + m_pVolumeGeometry->getPixelLengthX() * 0.5f; + // float32 yLR = m_pVolumeGeometry->pixelRowToCenterY(_iRow) + m_pVolumeGeometry->getPixelLengthY() * 0.5f; std::vector res; - // loop projectors and detectors - for (int iProjection = 0; iProjection < m_pProjectionGeometry->getProjectionAngleCount(); ++iProjection) { - - // get projection angle - float32 theta = m_pProjectionGeometry->getProjectionAngle(iProjection); - if (theta >= 7*PIdiv4) theta -= 2*PI; - bool inverse = false; - if (theta >= 3*PIdiv4) { - theta -= PI; - inverse = true; - } - - // calculate distance from the center of the voxel to the ray though the origin - float32 tUL = xUL * cos(theta) + yUL * sin(theta); - float32 tUR = xUR * cos(theta) + yUR * sin(theta); - float32 tLL = xLL * cos(theta) + yLL * sin(theta); - float32 tLR = xLR * cos(theta) + yLR * sin(theta); - if (inverse) { - tUL *= -1.0f; - tUR *= -1.0f; - tLL *= -1.0f; - tLR *= -1.0f; - } - float32 tMin = min(tUL, min(tUR, min(tLL,tLR))); - float32 tMax = max(tUL, max(tUR, max(tLL,tLR))); - - // calculate the offset on the detectorarray (in indices) - int dmin = (int)floor(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMin)); - int dmax = (int)ceil(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMax)); - - // add affected detectors to the list - for (int i = dmin; i <= dmax; ++i) { - if (i >= 0 && i < m_pProjectionGeometry->getDetectorCount()) { - SDetector2D det; - det.m_iAngleIndex = iProjection; - det.m_iDetectorIndex = i; - det.m_iIndex = iProjection * getProjectionGeometry()->getDetectorCount() + i; - res.push_back(det); - } - } - } + // // loop projectors and detectors + // for (int iProjection = 0; iProjection < m_pProjectionGeometry->getProjectionAngleCount(); ++iProjection) { + + // // get projection angle + // float32 theta = m_pProjectionGeometry->getProjectionAngle(iProjection); + // if (theta >= 7*PIdiv4) theta -= 2*PI; + // bool inverse = false; + // if (theta >= 3*PIdiv4) { + // theta -= PI; + // inverse = true; + // } + + // // calculate distance from the center of the voxel to the ray though the origin + // float32 tUL = xUL * cos(theta) + yUL * sin(theta); + // float32 tUR = xUR * cos(theta) + yUR * sin(theta); + // float32 tLL = xLL * cos(theta) + yLL * sin(theta); + // float32 tLR = xLR * cos(theta) + yLR * sin(theta); + // if (inverse) { + // tUL *= -1.0f; + // tUR *= -1.0f; + // tLL *= -1.0f; + // tLR *= -1.0f; + // } + // float32 tMin = min(tUL, min(tUR, min(tLL,tLR))); + // float32 tMax = max(tUL, max(tUR, max(tLL,tLR))); + + // // calculate the offset on the detectorarray (in indices) + // int dmin = (int)floor(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMin)); + // int dmax = (int)ceil(m_pProjectionGeometry->detectorOffsetToIndexFloat(tMax)); + + // // add affected detectors to the list + // for (int i = dmin; i <= dmax; ++i) { + // if (i >= 0 && i < m_pProjectionGeometry->getDetectorCount()) { + // SDetector2D det; + // det.m_iAngleIndex = iProjection; + // det.m_iDetectorIndex = i; + // det.m_iIndex = iProjection * getProjectionGeometry()->getDetectorCount() + i; + // res.push_back(det); + // } + // } + // } // return result vector return res; -- cgit v1.2.3 From 2c1999b1bbfb7ef2ca1ae22b43e2a0ab8108073f Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Thu, 12 Mar 2015 11:40:56 +0100 Subject: parallel projectors now always use vector geometries internally --- src/ParallelProjectionGeometry2D.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp index cac8f30..64fc0b9 100644 --- a/src/ParallelProjectionGeometry2D.cpp +++ b/src/ParallelProjectionGeometry2D.cpp @@ -182,8 +182,8 @@ Config* CParallelProjectionGeometry2D::getConfiguration() const cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); return cfg; } -//---------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------- CVector3D CParallelProjectionGeometry2D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex /* = 0 */) { CVector3D vOutput; @@ -197,4 +197,24 @@ CVector3D CParallelProjectionGeometry2D::getProjectionDirection(int _iProjection return vOutput; } +//---------------------------------------------------------------------------------------- +CParallelVecProjectionGeometry2D* CParallelProjectionGeometry2D::toVectorGeometry() +{ + SParProjection* vectors = new SParProjection[m_iProjectionAngleCount]; + for (int i = 0; i < m_iProjectionAngleCount; ++i) + { + vectors[i].fRayX = sinf(m_pfProjectionAngles[i]); + vectors[i].fRayY = -cosf(m_pfProjectionAngles[i]); + vectors[i].fDetUX = cosf(m_pfProjectionAngles[i]) * m_fDetectorWidth; + vectors[i].fDetUY = sinf(m_pfProjectionAngles[i]) * m_fDetectorWidth; + vectors[i].fDetSX = -0.5f * m_iDetectorCount * vectors[i].fDetUX; + vectors[i].fDetSY = -0.5f * m_iDetectorCount * vectors[i].fDetUY; + } + + CParallelVecProjectionGeometry2D* vecGeom = new CParallelVecProjectionGeometry2D(); + vecGeom->initialize(m_iProjectionAngleCount, m_iDetectorCount, vectors); + delete[] vectors; + return vecGeom; +} + } // end namespace astra -- cgit v1.2.3 From 424c97dcdcf4604ffcf6dd0d3a5cda93e332c7e4 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Thu, 12 Mar 2015 11:41:11 +0100 Subject: updated 'blob' kernel projector --- src/ParallelBeamBlobKernelProjector2D.cpp | 92 ++++++++++++++----------------- 1 file changed, 41 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/ParallelBeamBlobKernelProjector2D.cpp b/src/ParallelBeamBlobKernelProjector2D.cpp index 3253f88..d030576 100644 --- a/src/ParallelBeamBlobKernelProjector2D.cpp +++ b/src/ParallelBeamBlobKernelProjector2D.cpp @@ -102,7 +102,7 @@ bool CParallelBeamBlobKernelProjector2D::_check() // check base class ASTRA_CONFIG_CHECK(CProjector2D::_check(), "ParallelBeamBlobKernelProjector2D", "Error in Projector2D initialization"); - ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry), "ParallelBeamBlobKernelProjector2D", "Unsupported projection geometry"); + ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(m_pProjectionGeometry), "ParallelBeamBlobKernelProjector2D", "Unsupported projection geometry"); ASTRA_CONFIG_CHECK(m_iBlobSampleCount > 0, "ParallelBeamBlobKernelProjector2D", "m_iBlobSampleCount should be strictly positive."); ASTRA_CONFIG_CHECK(m_pfBlobValues, "ParallelBeamBlobKernelProjector2D", "Invalid Volume Geometry Object."); @@ -156,16 +156,6 @@ bool CParallelBeamBlobKernelProjector2D::initialize(const Config& _cfg) m_pfBlobValues[i] = values[i]; } - // Required: KernelValues - node2 = node->getSingleNode("KernelValuesNeg"); - ASTRA_CONFIG_CHECK(node2, "BlobProjector", "No Kernel/KernelValuesNeg tag specified."); - vector values2 = node2->getContentNumericalArray(); - ASTRA_CONFIG_CHECK(values2.size() == (unsigned int)m_iBlobSampleCount, "BlobProjector", "Number of specified values doesn't match SampleCount."); - m_pfBlobValuesNeg = new float32[m_iBlobSampleCount]; - for (int i = 0; i < m_iBlobSampleCount; i++) { - m_pfBlobValuesNeg[i] = values2[i]; - } - } // success @@ -228,44 +218,44 @@ void CParallelBeamBlobKernelProjector2D::computeSingleRayWeights(int _iProjectio // Splat a single point std::vector CParallelBeamBlobKernelProjector2D::projectPoint(int _iRow, int _iCol) { - float32 x = m_pVolumeGeometry->pixelColToCenterX(_iCol); - float32 y = m_pVolumeGeometry->pixelRowToCenterY(_iRow); - - std::vector res; - // loop projectors and detectors - for (int iProjection = 0; iProjection < m_pProjectionGeometry->getProjectionAngleCount(); ++iProjection) { - - // get projection angle - float32 theta = m_pProjectionGeometry->getProjectionAngle(iProjection); - if (theta >= 7*PIdiv4) theta -= 2*PI; - bool inverse = false; - if (theta >= 3*PIdiv4) { - theta -= PI; - inverse = true; - } - - // calculate distance from the center of the voxel to the ray though the origin - float32 t = x * cos(theta) + y * sin(theta); - if (inverse) t *= -1.0f; - - // calculate the offset on the detectorarray (in indices) - float32 d = m_pProjectionGeometry->detectorOffsetToIndexFloat(t); - int dmin = (int)ceil(d - m_fBlobSize); - int dmax = (int)floor(d + m_fBlobSize); - - // add affected detectors to the list - for (int i = dmin; i <= dmax; ++i) { - if (d >= 0 && d < m_pProjectionGeometry->getDetectorCount()) { - SDetector2D det; - det.m_iAngleIndex = iProjection; - det.m_iDetectorIndex = i; - det.m_iIndex = iProjection * getProjectionGeometry()->getDetectorCount() + i; - res.push_back(det); - } - } - } - - // return result vector - return res; - + // float32 x = m_pVolumeGeometry->pixelColToCenterX(_iCol); + // float32 y = m_pVolumeGeometry->pixelRowToCenterY(_iRow); + + // std::vector res; + // // loop projectors and detectors + // for (int iProjection = 0; iProjection < m_pProjectionGeometry->getProjectionAngleCount(); ++iProjection) { + + // // get projection angle + // float32 theta = m_pProjectionGeometry->getProjectionAngle(iProjection); + // if (theta >= 7*PIdiv4) theta -= 2*PI; + // bool inverse = false; + // if (theta >= 3*PIdiv4) { + // theta -= PI; + // inverse = true; + // } + + // // calculate distance from the center of the voxel to the ray though the origin + // float32 t = x * cos(theta) + y * sin(theta); + // if (inverse) t *= -1.0f; + + // // calculate the offset on the detectorarray (in indices) + // float32 d = m_pProjectionGeometry->detectorOffsetToIndexFloat(t); + // int dmin = (int)ceil(d - m_fBlobSize); + // int dmax = (int)floor(d + m_fBlobSize); + + // // add affected detectors to the list + // for (int i = dmin; i <= dmax; ++i) { + // if (d >= 0 && d < m_pProjectionGeometry->getDetectorCount()) { + // SDetector2D det; + // det.m_iAngleIndex = iProjection; + // det.m_iDetectorIndex = i; + // det.m_iIndex = iProjection * getProjectionGeometry()->getDetectorCount() + i; + // res.push_back(det); + // } + // } + // } + + // // return result vector + // return res; + return std::vector(); } -- cgit v1.2.3 From c0b6862d75edcde6beacf811ce97200776d13b62 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Thu, 12 Mar 2015 15:16:10 +0100 Subject: updated 'line_fanflat' projector --- src/FanFlatProjectionGeometry2D.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src') diff --git a/src/FanFlatProjectionGeometry2D.cpp b/src/FanFlatProjectionGeometry2D.cpp index d757f18..9851d40 100644 --- a/src/FanFlatProjectionGeometry2D.cpp +++ b/src/FanFlatProjectionGeometry2D.cpp @@ -217,7 +217,25 @@ Config* CFanFlatProjectionGeometry2D::getConfiguration() const cfg->self->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); return cfg; } + //---------------------------------------------------------------------------------------- +CFanFlatVecProjectionGeometry2D* CFanFlatProjectionGeometry2D::toVectorGeometry() +{ + SFanProjection* vectors = new SFanProjection[m_iProjectionAngleCount]; + for (int i = 0; i < m_iProjectionAngleCount; ++i) + { + vectors[i].fSrcX = sinf(m_pfProjectionAngles[i]) * m_fOriginSourceDistance; + vectors[i].fSrcY = -cosf(m_pfProjectionAngles[i]) * m_fOriginSourceDistance; + vectors[i].fDetUX = cosf(m_pfProjectionAngles[i]) * m_fDetectorWidth; + vectors[i].fDetUY = sinf(m_pfProjectionAngles[i]) * m_fDetectorWidth; + vectors[i].fDetSX = -sinf(m_pfProjectionAngles[i]) * m_fOriginDetectorDistance - 0.5f * m_iDetectorCount * vectors[i].fDetUX; + vectors[i].fDetSY = cosf(m_pfProjectionAngles[i]) * m_fOriginDetectorDistance - 0.5f * m_iDetectorCount * vectors[i].fDetUY; + } + CFanFlatVecProjectionGeometry2D* vecGeom = new CFanFlatVecProjectionGeometry2D(); + vecGeom->initialize(m_iProjectionAngleCount, m_iDetectorCount, vectors); + delete[] vectors; + return vecGeom; +} } // namespace astra -- cgit v1.2.3 From d53185395827980e101629c633653cb4284edb06 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Fri, 13 Mar 2015 10:22:22 +0100 Subject: removed extraDetectorOffset --- src/ParallelProjectionGeometry2D.cpp | 3 +-- src/ProjectionGeometry2D.cpp | 18 ------------------ 2 files changed, 1 insertion(+), 20 deletions(-) (limited to 'src') diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp index 64fc0b9..42ed0a0 100644 --- a/src/ParallelProjectionGeometry2D.cpp +++ b/src/ParallelProjectionGeometry2D.cpp @@ -67,8 +67,7 @@ CParallelProjectionGeometry2D::CParallelProjectionGeometry2D(const CParallelProj initialize(_projGeom.m_iProjectionAngleCount, _projGeom.m_iDetectorCount, _projGeom.m_fDetectorWidth, - _projGeom.m_pfProjectionAngles, - _projGeom.m_pfExtraDetectorOffset); + _projGeom.m_pfProjectionAngles); } //---------------------------------------------------------------------------------------- diff --git a/src/ProjectionGeometry2D.cpp b/src/ProjectionGeometry2D.cpp index 89b5fe0..a51d86b 100644 --- a/src/ProjectionGeometry2D.cpp +++ b/src/ProjectionGeometry2D.cpp @@ -72,7 +72,6 @@ void CProjectionGeometry2D::_clear() m_iDetectorCount = 0; m_fDetectorWidth = 0.0f; m_pfProjectionAngles = NULL; - m_pfExtraDetectorOffset = NULL; m_bInitialized = false; } @@ -85,10 +84,8 @@ void CProjectionGeometry2D::clear() m_fDetectorWidth = 0.0f; if (m_bInitialized){ delete[] m_pfProjectionAngles; - delete[] m_pfExtraDetectorOffset; } m_pfProjectionAngles = NULL; - m_pfExtraDetectorOffset = NULL; m_bInitialized = false; } @@ -150,19 +147,6 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg) } CC.markNodeParsed("ProjectionAngles"); - vector offset = _cfg.self->getOptionNumericalArray("ExtraDetectorOffset"); - m_pfExtraDetectorOffset = new float32[m_iProjectionAngleCount]; - if (offset.size() == (size_t)m_iProjectionAngleCount) { - for (int i = 0; i < m_iProjectionAngleCount; i++) { - m_pfExtraDetectorOffset[i] = offset[i]; - } - } else { - for (int i = 0; i < m_iProjectionAngleCount; i++) { - m_pfExtraDetectorOffset[i] = 0.0f; - } - } - CC.markOptionParsed("ExtraDetectorOffset"); - // some checks ASTRA_CONFIG_CHECK(m_iDetectorCount > 0, "ProjectionGeometry2D", "DetectorCount should be positive."); ASTRA_CONFIG_CHECK(m_fDetectorWidth > 0.0f, "ProjectionGeometry2D", "DetectorWidth should be positive."); @@ -189,10 +173,8 @@ bool CProjectionGeometry2D::_initialize(int _iProjectionAngleCount, m_iDetectorCount = _iDetectorCount; m_fDetectorWidth = _fDetectorWidth; m_pfProjectionAngles = new float32[m_iProjectionAngleCount]; - m_pfExtraDetectorOffset = new float32[m_iProjectionAngleCount]; for (int i = 0; i < m_iProjectionAngleCount; i++) { m_pfProjectionAngles[i] = _pfProjectionAngles[i]; - m_pfExtraDetectorOffset[i] = _pfExtraDetectorOffsets ? _pfExtraDetectorOffsets[i]:0; } // Interface class, so don't set m_bInitialized to true -- cgit v1.2.3 From 9e884e760b71be354c08892f6bce2efe723917b3 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Wed, 18 Mar 2015 11:09:32 +0100 Subject: corrected geometry names --- src/ConeVecProjectionGeometry3D.cpp | 8 ++++---- src/ParallelVecProjectionGeometry3D.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ConeVecProjectionGeometry3D.cpp b/src/ConeVecProjectionGeometry3D.cpp index a4bd22d..9dc273d 100644 --- a/src/ConeVecProjectionGeometry3D.cpp +++ b/src/ConeVecProjectionGeometry3D.cpp @@ -208,7 +208,7 @@ Config* CConeVecProjectionGeometry3D::getConfiguration() const Config* cfg = new Config(); cfg->initialize("ProjectionGeometry3D"); - cfg->self->addAttribute("type", "cone"); + cfg->self->addAttribute("type", "cone_vec"); cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); @@ -218,9 +218,9 @@ Config* CConeVecProjectionGeometry3D::getConfiguration() const vectors += boost::lexical_cast(p.fSrcX) + ","; vectors += boost::lexical_cast(p.fSrcY) + ","; vectors += boost::lexical_cast(p.fSrcZ) + ","; - vectors += boost::lexical_cast(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetUX + 0.5f*m_iDetectorColCount*p.fDetVX) + ","; - vectors += boost::lexical_cast(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetUY + 0.5f*m_iDetectorColCount*p.fDetVY) + ","; - vectors += boost::lexical_cast(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetUZ + 0.5f*m_iDetectorColCount*p.fDetVZ) + ","; + vectors += boost::lexical_cast(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetVX + 0.5f*m_iDetectorColCount*p.fDetUX) + ","; + vectors += boost::lexical_cast(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetVY + 0.5f*m_iDetectorColCount*p.fDetUY) + ","; + vectors += boost::lexical_cast(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetVZ + 0.5f*m_iDetectorColCount*p.fDetUZ) + ","; vectors += boost::lexical_cast(p.fDetUX) + ","; vectors += boost::lexical_cast(p.fDetUY) + ","; vectors += boost::lexical_cast(p.fDetUZ) + ","; diff --git a/src/ParallelVecProjectionGeometry3D.cpp b/src/ParallelVecProjectionGeometry3D.cpp index cfac485..dc325e9 100644 --- a/src/ParallelVecProjectionGeometry3D.cpp +++ b/src/ParallelVecProjectionGeometry3D.cpp @@ -208,7 +208,7 @@ Config* CParallelVecProjectionGeometry3D::getConfiguration() const Config* cfg = new Config(); cfg->initialize("ProjectionGeometry3D"); - cfg->self->addAttribute("type", "parallel3d"); + cfg->self->addAttribute("type", "parallel3d_vec"); cfg->self->addChildNode("DetectorRowCount", m_iDetectorRowCount); cfg->self->addChildNode("DetectorColCount", m_iDetectorColCount); @@ -218,9 +218,9 @@ Config* CParallelVecProjectionGeometry3D::getConfiguration() const vectors += boost::lexical_cast(p.fRayX) + ","; vectors += boost::lexical_cast(p.fRayY) + ","; vectors += boost::lexical_cast(p.fRayZ) + ","; - vectors += boost::lexical_cast(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetUX + 0.5f*m_iDetectorColCount*p.fDetVX) + ","; - vectors += boost::lexical_cast(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetUY + 0.5f*m_iDetectorColCount*p.fDetVY) + ","; - vectors += boost::lexical_cast(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetUZ + 0.5f*m_iDetectorColCount*p.fDetVZ) + ","; + vectors += boost::lexical_cast(p.fDetSX + 0.5f*m_iDetectorRowCount*p.fDetVX + 0.5f*m_iDetectorColCount*p.fDetUX) + ","; + vectors += boost::lexical_cast(p.fDetSY + 0.5f*m_iDetectorRowCount*p.fDetVY + 0.5f*m_iDetectorColCount*p.fDetUY) + ","; + vectors += boost::lexical_cast(p.fDetSZ + 0.5f*m_iDetectorRowCount*p.fDetVZ + 0.5f*m_iDetectorColCount*p.fDetUZ) + ","; vectors += boost::lexical_cast(p.fDetUX) + ","; vectors += boost::lexical_cast(p.fDetUY) + ","; vectors += boost::lexical_cast(p.fDetUZ) + ","; -- cgit v1.2.3 From fe9bba178fdae86ab47fa0428ed38dc04f6ac0a2 Mon Sep 17 00:00:00 2001 From: Wim van Aarle Date: Tue, 26 May 2015 16:07:10 +0200 Subject: updated configuration of ParallelVecProjectionGeometry --- src/ParallelVecProjectionGeometry2D.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/ParallelVecProjectionGeometry2D.cpp b/src/ParallelVecProjectionGeometry2D.cpp index c1ed1c4..1503076 100644 --- a/src/ParallelVecProjectionGeometry2D.cpp +++ b/src/ParallelVecProjectionGeometry2D.cpp @@ -101,25 +101,21 @@ bool CParallelVecProjectionGeometry2D::initialize(const Config& _cfg) ASTRA_ASSERT(_cfg.self); ConfigStackCheck CC("ParallelVecProjectionGeometry2D", this, _cfg); - XMLNode* node; - // TODO: Fix up class hierarchy... this class doesn't fit very well. // initialization of parent class //CProjectionGeometry2D::initialize(_cfg); // Required: DetectorCount - node = _cfg.self->getSingleNode("DetectorCount"); + XMLNode node = _cfg.self.getSingleNode("DetectorCount"); ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry2D", "No DetectorRowCount tag specified."); - m_iDetectorCount = boost::lexical_cast(node->getContent()); - ASTRA_DELETE(node); + m_iDetectorCount = boost::lexical_cast(node.getContent()); CC.markNodeParsed("DetectorCount"); // Required: Vectors - node = _cfg.self->getSingleNode("Vectors"); + node = _cfg.self.getSingleNode("Vectors"); ASTRA_CONFIG_CHECK(node, "ParallelVecProjectionGeometry2D", "No Vectors tag specified."); - vector data = node->getContentNumericalArray(); + vector data = node.getContentNumericalArray(); CC.markNodeParsed("Vectors"); - ASTRA_DELETE(node); ASTRA_CONFIG_CHECK(data.size() % 6 == 0, "ParallelVecProjectionGeometry2D", "Vectors doesn't consist of 6-tuples."); m_iProjectionAngleCount = data.size() / 6; m_pProjectionAngles = new SParProjection[m_iProjectionAngleCount]; @@ -137,8 +133,6 @@ bool CParallelVecProjectionGeometry2D::initialize(const Config& _cfg) p.fDetSY = data[6*i + 3] - 0.5f * m_iDetectorCount * p.fDetUY; } - - // success m_bInitialized = _check(); return m_bInitialized; @@ -217,8 +211,8 @@ Config* CParallelVecProjectionGeometry2D::getConfiguration() const { Config* cfg = new Config(); cfg->initialize("ProjectionGeometry2D"); - cfg->self->addAttribute("type", "parallel_vec"); - cfg->self->addChildNode("DetectorCount", getDetectorCount()); + cfg->self.addAttribute("type", "parallel_vec"); + cfg->self.addChildNode("DetectorCount", getDetectorCount()); std::string vectors = ""; for (int i = 0; i < m_iProjectionAngleCount; ++i) { SParProjection& p = m_pProjectionAngles[i]; @@ -230,7 +224,7 @@ Config* CParallelVecProjectionGeometry2D::getConfiguration() const vectors += boost::lexical_cast(p.fDetUY); if (i < m_iProjectionAngleCount-1) vectors += ';'; } - cfg->self->addChildNode("Vectors", vectors); + cfg->self.addChildNode("Vectors", vectors); return cfg; } //---------------------------------------------------------------------------------------- -- cgit v1.2.3 From b1ffc11d930c19bd73af9837a08bc8dde9fe8e72 Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Fri, 29 Jul 2016 12:03:38 +0200 Subject: Add CUDA parvec support --- src/CudaFilteredBackProjectionAlgorithm.cpp | 217 ++++------------------------ src/CudaForwardProjectionAlgorithm.cpp | 66 ++++----- src/CudaReconstructionAlgorithm2D.cpp | 63 +------- src/FanFlatProjectionGeometry2D.cpp | 18 +-- src/GeometryUtil2D.cpp | 161 +++++++++++++++++++++ src/ParallelProjectionGeometry2D.cpp | 35 ++--- src/ProjectionGeometry2D.cpp | 8 +- 7 files changed, 242 insertions(+), 326 deletions(-) create mode 100644 src/GeometryUtil2D.cpp (limited to 'src') diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp index aa97eec..9d23253 100644 --- a/src/CudaFilteredBackProjectionAlgorithm.cpp +++ b/src/CudaFilteredBackProjectionAlgorithm.cpp @@ -33,6 +33,7 @@ $Id$ #include "astra/AstraObjectManager.h" #include "astra/CudaProjector2D.h" #include "../cuda/2d/astra.h" +#include "../cuda/2d/fbp.h" #include "astra/Logging.h" @@ -44,8 +45,7 @@ string CCudaFilteredBackProjectionAlgorithm::type = "FBP_CUDA"; CCudaFilteredBackProjectionAlgorithm::CCudaFilteredBackProjectionAlgorithm() { m_bIsInitialized = false; - CReconstructionAlgorithm2D::_clear(); - m_pFBP = 0; + CCudaReconstructionAlgorithm2D::_clear(); m_pfFilter = NULL; m_fFilterParameter = -1.0f; m_fFilterD = 1.0f; @@ -53,35 +53,8 @@ CCudaFilteredBackProjectionAlgorithm::CCudaFilteredBackProjectionAlgorithm() CCudaFilteredBackProjectionAlgorithm::~CCudaFilteredBackProjectionAlgorithm() { - if(m_pfFilter != NULL) - { - delete [] m_pfFilter; - m_pfFilter = NULL; - } - - if(m_pFBP != NULL) - { - delete m_pFBP; - m_pFBP = NULL; - } -} - -void CCudaFilteredBackProjectionAlgorithm::initializeFromProjector() -{ - m_iPixelSuperSampling = 1; - m_iGPUIndex = -1; - - // Projector - CCudaProjector2D* pCudaProjector = dynamic_cast(m_pProjector); - if (!pCudaProjector) { - if (m_pProjector) { - ASTRA_WARN("non-CUDA Projector2D passed to FBP_CUDA"); - } - } else { - m_iPixelSuperSampling = pCudaProjector->getVoxelSuperSampling(); - m_iGPUIndex = pCudaProjector->getGPUIndex(); - } - + delete[] m_pfFilter; + m_pfFilter = NULL; } bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) @@ -92,54 +65,28 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) // if already initialized, clear first if (m_bIsInitialized) { +#warning FIXME Necessary? clear(); } - // Projector - XMLNode node = _cfg.self.getSingleNode("ProjectorId"); - CCudaProjector2D* pCudaProjector = 0; - if (node) { - int id = node.getContentInt(); - CProjector2D *projector = CProjector2DManager::getSingleton().get(id); - pCudaProjector = dynamic_cast(projector); - if (!pCudaProjector) { - ASTRA_WARN("non-CUDA Projector2D passed"); - } - } - CC.markNodeParsed("ProjectorId"); - - - // sinogram data - node = _cfg.self.getSingleNode("ProjectionDataId"); - ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ProjectionDataId tag specified."); - int id = node.getContentInt(); - m_pSinogram = dynamic_cast(CData2DManager::getSingleton().get(id)); - CC.markNodeParsed("ProjectionDataId"); + m_bIsInitialized = CCudaReconstructionAlgorithm2D::initialize(_cfg); + if (!m_bIsInitialized) + return false; - // reconstruction data - node = _cfg.self.getSingleNode("ReconstructionDataId"); - ASTRA_CONFIG_CHECK(node, "CudaFBP", "No ReconstructionDataId tag specified."); - id = node.getContentInt(); - m_pReconstruction = dynamic_cast(CData2DManager::getSingleton().get(id)); - CC.markNodeParsed("ReconstructionDataId"); // filter type - node = _cfg.self.getSingleNode("FilterType"); + XMLNode node = _cfg.self.getSingleNode("FilterType"); if (node) - { m_eFilter = _convertStringToFilter(node.getContent().c_str()); - } else - { m_eFilter = FILTER_RAMLAK; - } CC.markNodeParsed("FilterType"); // filter node = _cfg.self.getSingleNode("FilterSinogramId"); if (node) { - id = node.getContentInt(); + int id = node.getContentInt(); const CFloat32ProjectionData2D * pFilterData = dynamic_cast(CData2DManager::getSingleton().get(id)); m_iFilterWidth = pFilterData->getGeometry()->getDetectorCount(); int iFilterProjectionCount = pFilterData->getGeometry()->getProjectionAngleCount(); @@ -188,20 +135,9 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) initializeFromProjector(); - // Deprecated options - m_iPixelSuperSampling = (int)_cfg.self.getOptionNumerical("PixelSuperSampling", m_iPixelSuperSampling); - CC.markOptionParsed("PixelSuperSampling"); - // GPU number - m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUindex", -1); - m_iGPUIndex = (int)_cfg.self.getOptionNumerical("GPUIndex", m_iGPUIndex); - CC.markOptionParsed("GPUIndex"); - if (!_cfg.self.hasOption("GPUIndex")) - CC.markOptionParsed("GPUindex"); - - - m_pFBP = new AstraFBP; - m_bAstraFBPInit = false; + m_pAlgo = new astraCUDA::FBP(); + m_bAlgoInit = false; return check(); } @@ -226,9 +162,8 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(CFloat32ProjectionData2D * // success m_bIsInitialized = true; - m_pFBP = new AstraFBP; - - m_bAstraFBPInit = false; + m_pAlgo = new astraCUDA::FBP(); + m_bAlgoInit = false; if(_pfFilter != NULL) { @@ -256,107 +191,26 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(CFloat32ProjectionData2D * return check(); } -void CCudaFilteredBackProjectionAlgorithm::run(int _iNrIterations /* = 0 */) -{ - // check initialized - ASTRA_ASSERT(m_bIsInitialized); - - if (!m_bAstraFBPInit) { - - const CVolumeGeometry2D& volgeom = *m_pReconstruction->getGeometry(); - const CParallelProjectionGeometry2D* parprojgeom = dynamic_cast(m_pSinogram->getGeometry()); - const CFanFlatProjectionGeometry2D* fanprojgeom = dynamic_cast(m_pSinogram->getGeometry()); - - bool ok = true; - - // TODO: non-square pixels? - ok &= m_pFBP->setReconstructionGeometry(volgeom.getGridColCount(), - volgeom.getGridRowCount(), - volgeom.getPixelLengthX()); - int iDetectorCount; - if (parprojgeom) { - - float *offsets, *angles, detSize, outputScale; - - ok = convertAstraGeometry(&volgeom, parprojgeom, offsets, angles, detSize, outputScale); - - - ok &= m_pFBP->setProjectionGeometry(parprojgeom->getProjectionAngleCount(), - parprojgeom->getDetectorCount(), - angles, - parprojgeom->getDetectorWidth()); - iDetectorCount = parprojgeom->getDetectorCount(); - // TODO: Are detSize and outputScale handled correctly? - - if (offsets) - ok &= m_pFBP->setTOffsets(offsets); - ASTRA_ASSERT(ok); - - delete[] offsets; - delete[] angles; - - } else if (fanprojgeom) { - - astraCUDA::SFanProjection* projs; - float outputScale; - - // FIXME: Implement this, and clean up the interface to AstraFBP. - if (abs(volgeom.getWindowMinX() + volgeom.getWindowMaxX()) > 0.00001 * volgeom.getPixelLengthX()) { - // Off-center volume geometry isn't supported yet - ASTRA_ASSERT(false); - } - if (abs(volgeom.getWindowMinY() + volgeom.getWindowMaxY()) > 0.00001 * volgeom.getPixelLengthY()) { - // Off-center volume geometry isn't supported yet - ASTRA_ASSERT(false); - } - - ok = convertAstraGeometry(&volgeom, fanprojgeom, projs, outputScale); - - // CHECKME: outputScale? - - ok &= m_pFBP->setFanGeometry(fanprojgeom->getProjectionAngleCount(), - fanprojgeom->getDetectorCount(), - projs, - fanprojgeom->getProjectionAngles(), - fanprojgeom->getOriginSourceDistance(), - fanprojgeom->getOriginDetectorDistance(), - - fanprojgeom->getDetectorWidth(), - m_bShortScan); - - iDetectorCount = fanprojgeom->getDetectorCount(); - - delete[] projs; - } else { - assert(false); - } - - ok &= m_pFBP->setPixelSuperSampling(m_iPixelSuperSampling); - - ASTRA_ASSERT(ok); +void CCudaFilteredBackProjectionAlgorithm::initCUDAAlgorithm() +{ + CCudaReconstructionAlgorithm2D::initCUDAAlgorithm(); - ok &= m_pFBP->init(m_iGPUIndex); - ASTRA_ASSERT(ok); + astraCUDA::FBP* pFBP = dynamic_cast(m_pAlgo); - ok &= m_pFBP->setSinogram(m_pSinogram->getDataConst(), iDetectorCount); + bool ok = pFBP->setFilter(m_eFilter, m_pfFilter, m_iFilterWidth, m_fFilterD, m_fFilterParameter); + if (!ok) { + ASTRA_ERROR("CCudaFilteredBackProjectionAlgorithm: Failed to set filter"); ASTRA_ASSERT(ok); - - ok &= m_pFBP->setFilter(m_eFilter, m_pfFilter, m_iFilterWidth, m_fFilterD, m_fFilterParameter); - ASTRA_ASSERT(ok); - - m_bAstraFBPInit = true; } - bool ok = m_pFBP->run(); - ASTRA_ASSERT(ok); - - const CVolumeGeometry2D& volgeom = *m_pReconstruction->getGeometry(); - ok &= m_pFBP->getReconstruction(m_pReconstruction->getData(), volgeom.getGridColCount()); - - ASTRA_ASSERT(ok); + ok &= pFBP->setShortScan(m_bShortScan); + if (!ok) { + ASTRA_ERROR("CCudaFilteredBackProjectionAlgorithm: Failed to set short-scan mode"); + } } + bool CCudaFilteredBackProjectionAlgorithm::check() { // check pointers @@ -395,16 +249,6 @@ static int calcNextPowerOfTwo(int _iValue) return iOutput; } -int CCudaFilteredBackProjectionAlgorithm::calcIdealRealFilterWidth(int _iDetectorCount) -{ - return calcNextPowerOfTwo(_iDetectorCount); -} - -int CCudaFilteredBackProjectionAlgorithm::calcIdealFourierFilterWidth(int _iDetectorCount) -{ - return (calcNextPowerOfTwo(_iDetectorCount) / 2 + 1); -} - static bool stringCompareLowerCase(const char * _stringA, const char * _stringB) { int iCmpReturn = 0; @@ -518,12 +362,3 @@ E_FBPFILTER CCudaFilteredBackProjectionAlgorithm::_convertStringToFilter(const c return output; } -void CCudaFilteredBackProjectionAlgorithm::testGenFilter(E_FBPFILTER _eFilter, float _fD, int _iProjectionCount, cufftComplex * _pFilter, int _iFFTRealDetectorCount, int _iFFTFourierDetectorCount) -{ - genFilter(_eFilter, _fD, _iProjectionCount, _pFilter, _iFFTRealDetectorCount, _iFFTFourierDetectorCount); -} - -int CCudaFilteredBackProjectionAlgorithm::getGPUCount() -{ - return 0; -} diff --git a/src/CudaForwardProjectionAlgorithm.cpp b/src/CudaForwardProjectionAlgorithm.cpp index 80f2e02..bdd7dd0 100644 --- a/src/CudaForwardProjectionAlgorithm.cpp +++ b/src/CudaForwardProjectionAlgorithm.cpp @@ -221,56 +221,48 @@ void CCudaForwardProjectionAlgorithm::run(int) // check initialized assert(m_bIsInitialized); - CVolumeGeometry2D* pVolGeom = m_pVolume->getGeometry(); - const CParallelProjectionGeometry2D* parProjGeom = dynamic_cast(m_pSinogram->getGeometry()); - const CFanFlatProjectionGeometry2D* fanProjGeom = dynamic_cast(m_pSinogram->getGeometry()); - const CFanFlatVecProjectionGeometry2D* fanVecProjGeom = dynamic_cast(m_pSinogram->getGeometry()); + bool ok; - bool ok = false; - if (parProjGeom) { + const CVolumeGeometry2D* pVolGeom = m_pVolume->getGeometry(); + const CProjectionGeometry2D* pProjGeom = m_pSinogram->getGeometry(); + astraCUDA::SDimensions dims; - float *offsets, *angles, detSize, outputScale; - ok = convertAstraGeometry(pVolGeom, parProjGeom, offsets, angles, detSize, outputScale); + ok = convertAstraGeometry_dims(pVolGeom, pProjGeom, dims); - ASTRA_ASSERT(ok); // FIXME + if (!ok) + return; - // FIXME: Output scaling + astraCUDA::SParProjection* pParProjs = 0; + astraCUDA::SFanProjection* pFanProjs = 0; + float fOutputScale = 1.0f; - ok = astraCudaFP(m_pVolume->getDataConst(), m_pSinogram->getData(), - pVolGeom->getGridColCount(), pVolGeom->getGridRowCount(), - parProjGeom->getProjectionAngleCount(), - parProjGeom->getDetectorCount(), - angles, offsets, detSize, - m_iDetectorSuperSampling, 1.0f * outputScale, m_iGPUIndex); - - delete[] offsets; - delete[] angles; + ok = convertAstraGeometry(pVolGeom, pProjGeom, pParProjs, pFanProjs, fOutputScale); + if (!ok) + return; - } else if (fanProjGeom || fanVecProjGeom) { + if (pParProjs) { + assert(!pFanProjs); - astraCUDA::SFanProjection* projs; - float outputScale; + ok = astraCudaFP(m_pVolume->getDataConst(), m_pSinogram->getData(), + pVolGeom->getGridColCount(), pVolGeom->getGridRowCount(), + pProjGeom->getProjectionAngleCount(), + pProjGeom->getDetectorCount(), + pParProjs, + m_iDetectorSuperSampling, 1.0f * fOutputScale, m_iGPUIndex); - if (fanProjGeom) { - ok = convertAstraGeometry(pVolGeom, fanProjGeom, projs, outputScale); - } else { - ok = convertAstraGeometry(pVolGeom, fanVecProjGeom, projs, outputScale); - } + delete[] pParProjs; - ASTRA_ASSERT(ok); + } else { + assert(pFanProjs); ok = astraCudaFanFP(m_pVolume->getDataConst(), m_pSinogram->getData(), pVolGeom->getGridColCount(), pVolGeom->getGridRowCount(), - m_pSinogram->getGeometry()->getProjectionAngleCount(), - m_pSinogram->getGeometry()->getDetectorCount(), - projs, - m_iDetectorSuperSampling, outputScale, m_iGPUIndex); - - delete[] projs; - - } else { + pProjGeom->getProjectionAngleCount(), + pProjGeom->getDetectorCount(), + pFanProjs, + m_iDetectorSuperSampling, fOutputScale, m_iGPUIndex); - ASTRA_ASSERT(false); + delete[] pFanProjs; } diff --git a/src/CudaReconstructionAlgorithm2D.cpp b/src/CudaReconstructionAlgorithm2D.cpp index 2798434..326ef1e 100644 --- a/src/CudaReconstructionAlgorithm2D.cpp +++ b/src/CudaReconstructionAlgorithm2D.cpp @@ -250,69 +250,14 @@ bool CCudaReconstructionAlgorithm2D::setupGeometry() ok = m_pAlgo->setGPUIndex(m_iGPUIndex); if (!ok) return false; - astraCUDA::SDimensions dims; - const CVolumeGeometry2D& volgeom = *m_pReconstruction->getGeometry(); + const CProjectionGeometry2D& projgeom = *m_pSinogram->getGeometry(); - // TODO: non-square pixels? - dims.iVolWidth = volgeom.getGridColCount(); - dims.iVolHeight = volgeom.getGridRowCount(); - float fPixelSize = volgeom.getPixelLengthX(); - - dims.iRaysPerDet = m_iDetectorSuperSampling; - dims.iRaysPerPixelDim = m_iPixelSuperSampling; - - - const CParallelProjectionGeometry2D* parProjGeom = dynamic_cast(m_pSinogram->getGeometry()); - const CFanFlatProjectionGeometry2D* fanProjGeom = dynamic_cast(m_pSinogram->getGeometry()); - const CFanFlatVecProjectionGeometry2D* fanVecProjGeom = dynamic_cast(m_pSinogram->getGeometry()); - - if (parProjGeom) { - - float *offsets, *angles, detSize, outputScale; - - ok = convertAstraGeometry(&volgeom, parProjGeom, offsets, angles, detSize, outputScale); - - dims.iProjAngles = parProjGeom->getProjectionAngleCount(); - dims.iProjDets = parProjGeom->getDetectorCount(); - dims.fDetScale = parProjGeom->getDetectorWidth() / fPixelSize; - - ok = m_pAlgo->setGeometry(dims, parProjGeom->getProjectionAngles()); - ok &= m_pAlgo->setTOffsets(offsets); - - // CHECKME: outputScale? detSize? - - delete[] offsets; - delete[] angles; - - } else if (fanProjGeom || fanVecProjGeom) { - - astraCUDA::SFanProjection* projs; - float outputScale; - - if (fanProjGeom) { - ok = convertAstraGeometry(&volgeom, fanProjGeom, projs, outputScale); - } else { - ok = convertAstraGeometry(&volgeom, fanVecProjGeom, projs, outputScale); - } - - dims.iProjAngles = m_pSinogram->getGeometry()->getProjectionAngleCount(); - dims.iProjDets = m_pSinogram->getGeometry()->getDetectorCount(); - dims.fDetScale = m_pSinogram->getGeometry()->getDetectorWidth() / fPixelSize; - - ok = m_pAlgo->setFanGeometry(dims, projs); - - // CHECKME: outputScale? - - delete[] projs; - - } else { - - ASTRA_ASSERT(false); - - } + ok = m_pAlgo->setGeometry(&volgeom, &projgeom); if (!ok) return false; + ok = m_pAlgo->setSuperSampling(m_iDetectorSuperSampling, m_iPixelSuperSampling); + if (!ok) return false; if (m_bUseReconstructionMask) ok &= m_pAlgo->enableVolumeMask(); diff --git a/src/FanFlatProjectionGeometry2D.cpp b/src/FanFlatProjectionGeometry2D.cpp index 3aab582..4eec9c4 100644 --- a/src/FanFlatProjectionGeometry2D.cpp +++ b/src/FanFlatProjectionGeometry2D.cpp @@ -28,6 +28,8 @@ $Id$ #include "astra/FanFlatProjectionGeometry2D.h" +#include "astra/GeometryUtil2D.h" + #include #include @@ -218,16 +220,12 @@ Config* CFanFlatProjectionGeometry2D::getConfiguration() const //---------------------------------------------------------------------------------------- CFanFlatVecProjectionGeometry2D* CFanFlatProjectionGeometry2D::toVectorGeometry() { - SFanProjection* vectors = new SFanProjection[m_iProjectionAngleCount]; - for (int i = 0; i < m_iProjectionAngleCount; ++i) - { - vectors[i].fSrcX = sinf(m_pfProjectionAngles[i]) * m_fOriginSourceDistance; - vectors[i].fSrcY = -cosf(m_pfProjectionAngles[i]) * m_fOriginSourceDistance; - vectors[i].fDetUX = cosf(m_pfProjectionAngles[i]) * m_fDetectorWidth; - vectors[i].fDetUY = sinf(m_pfProjectionAngles[i]) * m_fDetectorWidth; - vectors[i].fDetSX = -sinf(m_pfProjectionAngles[i]) * m_fOriginDetectorDistance - 0.5f * m_iDetectorCount * vectors[i].fDetUX; - vectors[i].fDetSY = cosf(m_pfProjectionAngles[i]) * m_fOriginDetectorDistance - 0.5f * m_iDetectorCount * vectors[i].fDetUY; - } + SFanProjection* vectors = genFanProjections(m_iProjectionAngleCount, + m_iDetectorCount, + m_fOriginSourceDistance, + m_fOriginDetectorDistance, + m_fDetectorWidth, + m_pfProjectionAngles); CFanFlatVecProjectionGeometry2D* vecGeom = new CFanFlatVecProjectionGeometry2D(); vecGeom->initialize(m_iProjectionAngleCount, m_iDetectorCount, vectors); diff --git a/src/GeometryUtil2D.cpp b/src/GeometryUtil2D.cpp new file mode 100644 index 0000000..1bca2bc --- /dev/null +++ b/src/GeometryUtil2D.cpp @@ -0,0 +1,161 @@ +/* +----------------------------------------------------------------------- +Copyright: 2010-2015, iMinds-Vision Lab, University of Antwerp + 2014-2015, CWI, Amsterdam + +Contact: astra@uantwerpen.be +Website: http://sf.net/projects/astra-toolbox + +This file is part of the ASTRA Toolbox. + + +The ASTRA Toolbox is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The ASTRA Toolbox is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the ASTRA Toolbox. If not, see . + +----------------------------------------------------------------------- +$Id$ +*/ + +#include "astra/GeometryUtil2D.h" + +#include + +namespace astra { + +SParProjection* genParProjections(unsigned int iProjAngles, + unsigned int iProjDets, + double fDetSize, + const float *pfAngles, + const float *pfExtraOffsets) +{ + SParProjection base; + base.fRayX = 0.0f; + base.fRayY = 1.0f; + + base.fDetSX = iProjDets * fDetSize * -0.5f; + base.fDetSY = 0.0f; + + base.fDetUX = fDetSize; + base.fDetUY = 0.0f; + + SParProjection* p = new SParProjection[iProjAngles]; + +#define ROTATE0(name,i,alpha) do { p[i].f##name##X = base.f##name##X * cos(alpha) - base.f##name##Y * sin(alpha); p[i].f##name##Y = base.f##name##X * sin(alpha) + base.f##name##Y * cos(alpha); } while(0) + + for (unsigned int i = 0; i < iProjAngles; ++i) { + if (pfExtraOffsets) { + // TODO + } + + ROTATE0(Ray, i, pfAngles[i]); + ROTATE0(DetS, i, pfAngles[i]); + ROTATE0(DetU, i, pfAngles[i]); + + if (pfExtraOffsets) { + float d = pfExtraOffsets[i]; + p[i].fDetSX -= d * p[i].fDetUX; + p[i].fDetSY -= d * p[i].fDetUY; + } + } + +#undef ROTATE0 + + return p; +} + + +SFanProjection* genFanProjections(unsigned int iProjAngles, + unsigned int iProjDets, + double fOriginSource, double fOriginDetector, + double fDetSize, + const float *pfAngles) +// const float *pfExtraOffsets) +{ + SFanProjection *pProjs = new SFanProjection[iProjAngles]; + + float fSrcX0 = 0.0f; + float fSrcY0 = -fOriginSource; + float fDetUX0 = fDetSize; + float fDetUY0 = 0.0f; + float fDetSX0 = iProjDets * fDetUX0 / -2.0f; + float fDetSY0 = fOriginDetector; + +#define ROTATE0(name,i,alpha) do { pProjs[i].f##name##X = f##name##X0 * cos(alpha) - f##name##Y0 * sin(alpha); pProjs[i].f##name##Y = f##name##X0 * sin(alpha) + f##name##Y0 * cos(alpha); } while(0) + for (unsigned int i = 0; i < iProjAngles; ++i) { + ROTATE0(Src, i, pfAngles[i]); + ROTATE0(DetS, i, pfAngles[i]); + ROTATE0(DetU, i, pfAngles[i]); + } + +#undef ROTATE0 + + return pProjs; +} + +// Convert a SParProjection back into its set of "standard" circular parallel +// beam parameters. This is always possible. +bool getParParameters(const SParProjection &proj /* , ... */) +{ + // angle + // det size + // offset + + // (see convertAndUploadAngles in par_fp.cu) + + return true; +} + +// Convert a SFanProjection back into its set of "standard" circular fan beam +// parameters. This will return false if it can not be represented in this way. +bool getFanParameters(const SFanProjection &proj, unsigned int iProjDets, float &fAngle, float &fOriginSource, float &fOriginDetector, float &fDetSize, float &fOffset) +{ + // angle + // det size + // offset + // origin-source + // origin-detector + + // Need to check if line source-origin is orthogonal to vector ux,uy + // (including the case source==origin) + + // (equivalent: source and origin project to same point on detector) + + double dp = proj.fSrcX * proj.fDetUX + proj.fSrcY * proj.fDetUY; + + double rel = (proj.fSrcX*proj.fSrcX + proj.fSrcY*proj.fSrcY) * (proj.fDetUX*proj.fDetUX + proj.fDetUY*proj.fDetUY); + rel = sqrt(rel); + + if (std::abs(dp) > rel * 0.0001) + return false; + + fOriginSource = sqrt(proj.fSrcX*proj.fSrcX + proj.fSrcY*proj.fSrcY); + + fDetSize = sqrt(proj.fDetUX*proj.fDetUX + proj.fDetUY*proj.fDetUY); + + // project origin on detector line ( == project source on detector line) + + double t = (- proj.fDetSX) * proj.fDetUX + (- proj.fDetSY) * proj.fDetUY; + + fOffset = (float)t - 0.5*iProjDets; + + // TODO: CHECKME + fOriginDetector = sqrt((proj.fDetSX + t * proj.fDetUX)*(proj.fDetSX + t * proj.fDetUX) + (proj.fDetSY + t * proj.fDetUY)*(proj.fDetSY + t * proj.fDetUY)); + + //float fAngle = atan2(proj.fDetSX + t * proj.fDetUX - proj.fSrcX, proj.fDetSY + t * proj.fDetUY); // TODO: Fix order + sign + fAngle = atan2(proj.fDetUY, proj.fDetUX); // TODO: Check order + sign + + return true; +} + + +} diff --git a/src/ParallelProjectionGeometry2D.cpp b/src/ParallelProjectionGeometry2D.cpp index 105e24b..e1f93aa 100644 --- a/src/ParallelProjectionGeometry2D.cpp +++ b/src/ParallelProjectionGeometry2D.cpp @@ -28,6 +28,8 @@ $Id$ #include "astra/ParallelProjectionGeometry2D.h" +#include "astra/GeometryUtil2D.h" + #include using namespace std; @@ -48,15 +50,13 @@ CParallelProjectionGeometry2D::CParallelProjectionGeometry2D() : CParallelProjectionGeometry2D::CParallelProjectionGeometry2D(int _iProjectionAngleCount, int _iDetectorCount, float32 _fDetectorWidth, - const float32* _pfProjectionAngles, - const float32* _pfExtraDetectorOffsets) + const float32* _pfProjectionAngles) { _clear(); initialize(_iProjectionAngleCount, _iDetectorCount, _fDetectorWidth, - _pfProjectionAngles, - _pfExtraDetectorOffsets); + _pfProjectionAngles); } //---------------------------------------------------------------------------------------- @@ -115,14 +115,12 @@ bool CParallelProjectionGeometry2D::initialize(const Config& _cfg) bool CParallelProjectionGeometry2D::initialize(int _iProjectionAngleCount, int _iDetectorCount, float32 _fDetectorWidth, - const float32* _pfProjectionAngles, - const float32* _pfExtraDetectorOffsets) + const float32* _pfProjectionAngles) { _initialize(_iProjectionAngleCount, _iDetectorCount, _fDetectorWidth, - _pfProjectionAngles, - _pfExtraDetectorOffsets); + _pfProjectionAngles); // success m_bInitialized = _check(); @@ -178,11 +176,6 @@ Config* CParallelProjectionGeometry2D::getConfiguration() const cfg->self.addChildNode("DetectorCount", getDetectorCount()); cfg->self.addChildNode("DetectorWidth", getDetectorWidth()); cfg->self.addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount); - if(m_pfExtraDetectorOffset!=NULL){ - XMLNode opt = cfg->self.addChildNode("Option"); - opt.addAttribute("key","ExtraDetectorOffset"); - opt.setContent(m_pfExtraDetectorOffset, m_iProjectionAngleCount); - } return cfg; } @@ -203,17 +196,11 @@ CVector3D CParallelProjectionGeometry2D::getProjectionDirection(int _iProjection //---------------------------------------------------------------------------------------- CParallelVecProjectionGeometry2D* CParallelProjectionGeometry2D::toVectorGeometry() { - SParProjection* vectors = new SParProjection[m_iProjectionAngleCount]; - for (int i = 0; i < m_iProjectionAngleCount; ++i) - { - vectors[i].fRayX = sinf(m_pfProjectionAngles[i]); - vectors[i].fRayY = -cosf(m_pfProjectionAngles[i]); - vectors[i].fDetUX = cosf(m_pfProjectionAngles[i]) * m_fDetectorWidth; - vectors[i].fDetUY = sinf(m_pfProjectionAngles[i]) * m_fDetectorWidth; - vectors[i].fDetSX = -0.5f * m_iDetectorCount * vectors[i].fDetUX; - vectors[i].fDetSY = -0.5f * m_iDetectorCount * vectors[i].fDetUY; - } - + SParProjection* vectors = genParProjections(m_iProjectionAngleCount, + m_iDetectorCount, + m_fDetectorWidth, + m_pfProjectionAngles, 0); + // TODO: ExtraOffsets? CParallelVecProjectionGeometry2D* vecGeom = new CParallelVecProjectionGeometry2D(); vecGeom->initialize(m_iProjectionAngleCount, m_iDetectorCount, vectors); delete[] vectors; diff --git a/src/ProjectionGeometry2D.cpp b/src/ProjectionGeometry2D.cpp index 03fbd22..a306b48 100644 --- a/src/ProjectionGeometry2D.cpp +++ b/src/ProjectionGeometry2D.cpp @@ -45,11 +45,10 @@ CProjectionGeometry2D::CProjectionGeometry2D() : configCheckData(0) CProjectionGeometry2D::CProjectionGeometry2D(int _iAngleCount, int _iDetectorCount, float32 _fDetectorWidth, - const float32* _pfProjectionAngles, - const float32* _pfExtraDetectorOffsets) : configCheckData(0) + const float32* _pfProjectionAngles) : configCheckData(0) { _clear(); - _initialize(_iAngleCount, _iDetectorCount, _fDetectorWidth, _pfProjectionAngles,_pfExtraDetectorOffsets); + _initialize(_iAngleCount, _iDetectorCount, _fDetectorWidth, _pfProjectionAngles); } //---------------------------------------------------------------------------------------- @@ -156,8 +155,7 @@ bool CProjectionGeometry2D::initialize(const Config& _cfg) bool CProjectionGeometry2D::_initialize(int _iProjectionAngleCount, int _iDetectorCount, float32 _fDetectorWidth, - const float32* _pfProjectionAngles, - const float32* _pfExtraDetectorOffsets) + const float32* _pfProjectionAngles) { if (m_bInitialized) { clear(); -- cgit v1.2.3 From 1a8243ed0311c3074a79b97e1730bf3409774b8d Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 27 Sep 2017 13:57:04 +0200 Subject: Unify some parallel_vec parameter computations --- src/GeometryUtil2D.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/GeometryUtil2D.cpp b/src/GeometryUtil2D.cpp index 1bca2bc..2ee6185 100644 --- a/src/GeometryUtil2D.cpp +++ b/src/GeometryUtil2D.cpp @@ -104,13 +104,27 @@ SFanProjection* genFanProjections(unsigned int iProjAngles, // Convert a SParProjection back into its set of "standard" circular parallel // beam parameters. This is always possible. -bool getParParameters(const SParProjection &proj /* , ... */) +bool getParParameters(const SParProjection &proj, unsigned int iProjDets, float &fAngle, float &fDetSize, float &fOffset) { - // angle - // det size - // offset + // Take part of DetU orthogonal to Ray + double ux = proj.fDetUX; + double uy = proj.fDetUY; + + double t = (ux * proj.fRayX + uy * proj.fRayY) / (proj.fRayX * proj.fRayX + proj.fRayY * proj.fRayY); + + ux -= t * proj.fRayX; + uy -= t * proj.fRayY; + + double angle = atan2(uy, ux); + + fAngle = (float)angle; + + double norm2 = uy * uy + ux * ux; + + fDetSize = (float)sqrt(norm2); - // (see convertAndUploadAngles in par_fp.cu) + // CHECKME: SIGNS? + fOffset = (float)(-0.5*iProjDets - (proj.fDetSY*uy + proj.fDetSX*ux) / norm2); return true; } -- cgit v1.2.3 From f87ca86a994cdc3205a294e9bbbeddde312ea53b Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Wed, 11 Oct 2017 11:32:28 +0200 Subject: Make geometry config checks slightly less numerically strict --- src/FanFlatBeamLineKernelProjector2D.cpp | 2 +- src/FanFlatBeamStripKernelProjector2D.cpp | 2 +- src/ParallelBeamLineKernelProjector2D.cpp | 2 +- src/ParallelBeamLinearKernelProjector2D.cpp | 2 +- src/ParallelBeamStripKernelProjector2D.cpp | 2 +- src/VolumeGeometry2D.cpp | 20 ++++++++++---------- 6 files changed, 15 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/FanFlatBeamLineKernelProjector2D.cpp b/src/FanFlatBeamLineKernelProjector2D.cpp index 4bfff58..7bec351 100644 --- a/src/FanFlatBeamLineKernelProjector2D.cpp +++ b/src/FanFlatBeamLineKernelProjector2D.cpp @@ -91,7 +91,7 @@ bool CFanFlatBeamLineKernelProjector2D::_check() ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(m_pProjectionGeometry), "FanFlatBeamLineKernelProjector2D", "Unsupported projection geometry"); - ASTRA_CONFIG_CHECK(m_pVolumeGeometry->getPixelLengthX() == m_pVolumeGeometry->getPixelLengthY(), "FanFlatBeamLineKernelProjector2D", "Pixel height must equal pixel width."); + ASTRA_CONFIG_CHECK(abs(m_pVolumeGeometry->getPixelLengthX() / m_pVolumeGeometry->getPixelLengthY()) - 1 < eps, "FanFlatBeamLineKernelProjector2D", "Pixel height must equal pixel width."); // success return true; diff --git a/src/FanFlatBeamStripKernelProjector2D.cpp b/src/FanFlatBeamStripKernelProjector2D.cpp index 198c0ea..de12d49 100644 --- a/src/FanFlatBeamStripKernelProjector2D.cpp +++ b/src/FanFlatBeamStripKernelProjector2D.cpp @@ -89,7 +89,7 @@ bool CFanFlatBeamStripKernelProjector2D::_check() ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry), "FanFlatBeamLineKernelProjector2D", "Unsupported projection geometry"); - ASTRA_CONFIG_CHECK(m_pVolumeGeometry->getPixelLengthX() == m_pVolumeGeometry->getPixelLengthY(), "FanFlatBeamStripKernelProjector2D", "Pixel height must equal pixel width."); + ASTRA_CONFIG_CHECK(abs(m_pVolumeGeometry->getPixelLengthX() / m_pVolumeGeometry->getPixelLengthY()) - 1 < eps, "FanFlatBeamStripKernelProjector2D", "Pixel height must equal pixel width."); // success return true; diff --git a/src/ParallelBeamLineKernelProjector2D.cpp b/src/ParallelBeamLineKernelProjector2D.cpp index d11be3d..a7d72d4 100644 --- a/src/ParallelBeamLineKernelProjector2D.cpp +++ b/src/ParallelBeamLineKernelProjector2D.cpp @@ -89,7 +89,7 @@ bool CParallelBeamLineKernelProjector2D::_check() ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(m_pProjectionGeometry), "ParallelBeamLineKernelProjector2D", "Unsupported projection geometry"); - ASTRA_CONFIG_CHECK(m_pVolumeGeometry->getPixelLengthX() == m_pVolumeGeometry->getPixelLengthY(), "ParallelBeamLineKernelProjector2D", "Pixel height must equal pixel width."); + ASTRA_CONFIG_CHECK(abs(m_pVolumeGeometry->getPixelLengthX() / m_pVolumeGeometry->getPixelLengthY()) - 1 < eps, "ParallelBeamLineKernelProjector2D", "Pixel height must equal pixel width."); // success return true; diff --git a/src/ParallelBeamLinearKernelProjector2D.cpp b/src/ParallelBeamLinearKernelProjector2D.cpp index 137046b..98946a8 100644 --- a/src/ParallelBeamLinearKernelProjector2D.cpp +++ b/src/ParallelBeamLinearKernelProjector2D.cpp @@ -91,7 +91,7 @@ bool CParallelBeamLinearKernelProjector2D::_check() ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(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."); + ASTRA_CONFIG_CHECK(abs(m_pVolumeGeometry->getPixelLengthX() / m_pVolumeGeometry->getPixelLengthY()) - 1 < eps, "ParallelBeamLinearKernelProjector2D", "Pixel height must equal pixel width."); // success return true; diff --git a/src/ParallelBeamStripKernelProjector2D.cpp b/src/ParallelBeamStripKernelProjector2D.cpp index 6ed6ab0..5a0767b 100644 --- a/src/ParallelBeamStripKernelProjector2D.cpp +++ b/src/ParallelBeamStripKernelProjector2D.cpp @@ -89,7 +89,7 @@ bool CParallelBeamStripKernelProjector2D::_check() ASTRA_CONFIG_CHECK(dynamic_cast(m_pProjectionGeometry) || dynamic_cast(m_pProjectionGeometry), "ParallelBeamStripKernelProjector2D", "Unsupported projection geometry"); - ASTRA_CONFIG_CHECK(m_pVolumeGeometry->getPixelLengthX() == m_pVolumeGeometry->getPixelLengthY(), "ParallelBeamStripKernelProjector2D", "Pixel height must equal pixel width."); + ASTRA_CONFIG_CHECK(abs(m_pVolumeGeometry->getPixelLengthX() / m_pVolumeGeometry->getPixelLengthY()) - 1 < eps, "ParallelBeamStripKernelProjector2D", "Pixel height must equal pixel width."); // success return true; diff --git a/src/VolumeGeometry2D.cpp b/src/VolumeGeometry2D.cpp index dd056ae..75d0dfc 100644 --- a/src/VolumeGeometry2D.cpp +++ b/src/VolumeGeometry2D.cpp @@ -41,16 +41,16 @@ bool CVolumeGeometry2D::_check() ASTRA_CONFIG_CHECK(m_fWindowMinX < m_fWindowMaxX, "VolumeGeometry2D", "WindowMinX should be lower than WindowMaxX."); ASTRA_CONFIG_CHECK(m_fWindowMinY < m_fWindowMaxY, "VolumeGeometry2D", "WindowMinY should be lower than WindowMaxY."); - ASTRA_CONFIG_CHECK(m_iGridTotCount == (m_iGridColCount * m_iGridRowCount), "VolumeGeometry2D", "Internal configuration error."); - ASTRA_CONFIG_CHECK(m_fWindowLengthX == (m_fWindowMaxX - m_fWindowMinX), "VolumeGeometry2D", "Internal configuration error."); - ASTRA_CONFIG_CHECK(m_fWindowLengthY == (m_fWindowMaxY - m_fWindowMinY), "VolumeGeometry2D", "Internal configuration error."); - ASTRA_CONFIG_CHECK(m_fWindowArea == (m_fWindowLengthX * m_fWindowLengthY), "VolumeGeometry2D", "Internal configuration error."); - ASTRA_CONFIG_CHECK(m_fPixelLengthX == (m_fWindowLengthX / (float32)m_iGridColCount), "VolumeGeometry2D", "Internal configuration error."); - ASTRA_CONFIG_CHECK(m_fPixelLengthY == (m_fWindowLengthY / (float32)m_iGridRowCount), "VolumeGeometry2D", "Internal configuration error."); - - ASTRA_CONFIG_CHECK(m_fPixelArea == (m_fPixelLengthX * m_fPixelLengthY), "VolumeGeometry2D", "Internal configuration error."); - ASTRA_CONFIG_CHECK(fabsf(m_fDivPixelLengthX * m_fPixelLengthX - 1.0f) < eps, "VolumeGeometry2D", "Internal configuration error."); - ASTRA_CONFIG_CHECK(fabsf(m_fDivPixelLengthY * m_fPixelLengthY - 1.0f) < eps, "VolumeGeometry2D", "Internal configuration error."); + ASTRA_CONFIG_CHECK(fabsf(m_iGridTotCount - (m_iGridColCount * m_iGridRowCount)) < eps, "VolumeGeometry2D", "Internal configuration error (m_iGridTotCount)."); + ASTRA_CONFIG_CHECK(fabsf(m_fWindowLengthX - (m_fWindowMaxX - m_fWindowMinX)) < eps, "VolumeGeometry2D", "Internal configuration error (m_fWindowLengthX)."); + ASTRA_CONFIG_CHECK(fabsf(m_fWindowLengthY - (m_fWindowMaxY - m_fWindowMinY)) < eps, "VolumeGeometry2D", "Internal configuration error (m_fWindowLengthY)."); + ASTRA_CONFIG_CHECK(fabsf(m_fWindowArea - (m_fWindowLengthX * m_fWindowLengthY)) < eps, "VolumeGeometry2D", "Internal configuration error (m_fWindowArea)."); + ASTRA_CONFIG_CHECK(fabsf(m_fPixelLengthX - (m_fWindowLengthX / (float32)m_iGridColCount)) < eps, "VolumeGeometry2D", "Internal configuration error (m_fPixelLengthX)."); + ASTRA_CONFIG_CHECK(fabsf(m_fPixelLengthY - (m_fWindowLengthY / (float32)m_iGridRowCount)) < eps, "VolumeGeometry2D", "Internal configuration error (m_fPixelLengthY)."); + + ASTRA_CONFIG_CHECK(fabsf(m_fPixelArea - (m_fPixelLengthX * m_fPixelLengthY)) < eps, "VolumeGeometry2D", "Internal configuration error (m_fPixelArea)."); + ASTRA_CONFIG_CHECK(fabsf(m_fDivPixelLengthX * m_fPixelLengthX - 1.0f) < eps, "VolumeGeometry2D", "Internal configuration error (m_fDivPixelLengthX)."); + ASTRA_CONFIG_CHECK(fabsf(m_fDivPixelLengthY * m_fPixelLengthY - 1.0f) < eps, "VolumeGeometry2D", "Internal configuration error (m_fDivPixelLengthY)."); return true; } -- cgit v1.2.3 From 08df6c4167118e0a3b5f128078f9c13f206a171a Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 12 Oct 2017 15:17:10 +0200 Subject: Fix some warnings --- src/CudaFilteredBackProjectionAlgorithm.cpp | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'src') diff --git a/src/CudaFilteredBackProjectionAlgorithm.cpp b/src/CudaFilteredBackProjectionAlgorithm.cpp index 2829b7d..f3cca12 100644 --- a/src/CudaFilteredBackProjectionAlgorithm.cpp +++ b/src/CudaFilteredBackProjectionAlgorithm.cpp @@ -64,7 +64,6 @@ bool CCudaFilteredBackProjectionAlgorithm::initialize(const Config& _cfg) // if already initialized, clear first if (m_bIsInitialized) { -#warning FIXME Necessary? clear(); } @@ -236,18 +235,6 @@ bool CCudaFilteredBackProjectionAlgorithm::check() return true; } -static int calcNextPowerOfTwo(int _iValue) -{ - int iOutput = 1; - - while(iOutput < _iValue) - { - iOutput *= 2; - } - - return iOutput; -} - static bool stringCompareLowerCase(const char * _stringA, const char * _stringB) { int iCmpReturn = 0; -- cgit v1.2.3 From 85e3fd19f7ed594395e795f2b9fd0b6b42231a3a Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Thu, 12 Oct 2017 16:17:47 +0200 Subject: Fix geometry computation in unused function --- src/ConeProjectionGeometry3D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp index 217a916..e8b95f1 100644 --- a/src/ConeProjectionGeometry3D.cpp +++ b/src/ConeProjectionGeometry3D.cpp @@ -225,7 +225,7 @@ CVector3D CConeProjectionGeometry3D::getProjectionDirection(int _iProjectionInde #undef ROTATE - CVector3D ret(fDetX - fSrcX, fDetY - fSrcY, fDetZ - fDetZ); + CVector3D ret(fDetX - fSrcX, fDetY - fSrcY, fDetZ - fSrcZ); return ret; } -- cgit v1.2.3 From 6a7b605102f1c22224b516906cb4a848cda50a3b Mon Sep 17 00:00:00 2001 From: Willem Jan Palenstijn Date: Mon, 16 Oct 2017 19:03:52 +0200 Subject: Fix warning --- src/Float32Data2D.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Float32Data2D.cpp b/src/Float32Data2D.cpp index 56ea7cc..c5d2cc8 100644 --- a/src/Float32Data2D.cpp +++ b/src/Float32Data2D.cpp @@ -286,7 +286,7 @@ void CFloat32Data2D::_allocateData() ASTRA_ASSERT(!m_bInitialized); ASTRA_ASSERT(m_iSize > 0); - ASTRA_ASSERT(m_iSize == (size_t)m_iWidth * m_iHeight); + ASTRA_ASSERT((size_t)m_iSize == (size_t)m_iWidth * m_iHeight); ASTRA_ASSERT(m_pfData == NULL); ASTRA_ASSERT(m_ppfData2D == NULL); -- cgit v1.2.3