diff options
Diffstat (limited to 'include/astra/ProjectionGeometry3D.h')
-rw-r--r-- | include/astra/ProjectionGeometry3D.h | 589 |
1 files changed, 589 insertions, 0 deletions
diff --git a/include/astra/ProjectionGeometry3D.h b/include/astra/ProjectionGeometry3D.h new file mode 100644 index 0000000..0deffa6 --- /dev/null +++ b/include/astra/ProjectionGeometry3D.h @@ -0,0 +1,589 @@ +/* +----------------------------------------------------------------------- +Copyright 2012 iMinds-Vision Lab, University of Antwerp + +Contact: astra@ua.ac.be +Website: http://astra.ua.ac.be + + +This file is part of the +All Scale Tomographic Reconstruction Antwerp Toolbox ("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 <http://www.gnu.org/licenses/>. + +----------------------------------------------------------------------- +$Id$ +*/ + +#ifndef _INC_ASTRA_PROJECTIONGEOMETRY3D +#define _INC_ASTRA_PROJECTIONGEOMETRY3D + +#include "Globals.h" +#include "Config.h" +#include "Vector3D.h" + +#include <string> +#include <cmath> +#include <vector> + +namespace astra +{ + +class XMLNode; + +/** + * This class defines the interface for each 3D projection geometry. + * It has a number of data fields, such as width and height of detector + * pixels, projection angles and number of rows and columns of detector pixels. + * + * \par XML Configuration + * \astra_xml_item{DetectorRowCount, int, Number of detectors for each projection.} + * \astra_xml_item{DetectorColCount, int, Number of detectors for each projection.} + * \astra_xml_item{DetectorWidth, float, Width of each detector.} + * \astra_xml_item{DetectorHeight, float, Width of each detector.} + * \astra_xml_item{ProjectionAngles, vector of float, projection angles in radians.} + */ +class _AstraExport CProjectionGeometry3D +{ + +protected: + + /** Has the object been intialized with acceptable values? + */ + bool m_bInitialized; + + /** Number of projection angles. + */ + int m_iProjectionAngleCount; + + /** Number of rows of detectors. + */ + int m_iDetectorRowCount; + + /** Number of columns of detectors. + */ + int m_iDetectorColCount; + + /** Total number of detectors. + */ + int m_iDetectorTotCount; + + /** The x-distance between projected rays on the detector plate (or width of projected strips). + */ + float32 m_fDetectorSpacingX; + + /** The y-distance between projected rays on the detector plate (or height of projected strips). + */ + float32 m_fDetectorSpacingY; + + /** Dynamically allocated array of projection angles. All angles are represented in radians and lie in + * the [0,2pi[ interval. + */ + float32* m_pfProjectionAngles; + + /** Dynamically allocated array of vectors that represents the amount by which an image has been shifted after + * projection. Each projection image has a 2 shifts associated with it, one x-translation and y-translation + */ + float32* m_pfExtraDetectorOffsetsX; + float32* m_pfExtraDetectorOffsetsY; + + /** Default constructor. Sets all numeric member variables to 0 and all pointer member variables to NULL. + * + * If an object is constructed using this default constructor, it must always be followed by a call + * to one of the initialize() methods before the object can be used. Any use before calling initialize() + * is not allowed, except calling the member function isInitialized(). + * + */ + CProjectionGeometry3D(); + + /** Constructor. Create an instance of the CProjectionGeometry3D class. + * + * @param _iProjectionAngleCount Number of projection angles. + * @param _iDetectorRowCount Number of rows of detectors. + * @param _iDetectorColCount Number of columns detectors. + * @param _fDetectorSpacingX Spacing between the detector points on the X-axis, in unit lengths. Assumed to be constant throughout the entire detector plate. + * @param _fDetectorSpacingY Spacing between the detector points on the Y-axis, in unit lengths. Assumed to be constant throughout the entire detector plate. + * @param _pfProjectionAngles Pointer to an array of projection angles. The angles will be copied from this array. All angles + * are represented in radians and lie in the [0,2pi[ interval. + */ + CProjectionGeometry3D(int _iProjectionAngleCount, + int _iDetectorRowCount, + int _iDetectorColCount, + float32 _fDetectorSpacingX, + float32 _fDetectorSpacingY, + const float32* _pfProjectionAngles, + const float32* _pfExtraDetectorOffsetsX = NULL, + const float32* _pfExtraDetectorOffsetsY = NULL); + + /** Copy constructor. + */ + CProjectionGeometry3D(const CProjectionGeometry3D& _projGeom); + + /** Check the values of this object. If everything is ok, the object can be set to the initialized state. + * The following statements are then guaranteed to hold: + * - number of rows and columns is larger than zero + * - detector spacing is larger than zero + * - number of angles is larger than zero + * - (autofix) each angle lies in [0,2pi[ + */ + bool _check(); + + /** Clear all member variables, setting all numeric variables to 0 and all pointers to NULL. + * Should only be used by constructors. Otherwise use the clear() function. + */ + void _clear(); + + /** Initialize the geometry. If the object has been initialized before, the object is reinitialized + * and memory is freed and reallocated if necessary. + * + * @param _iProjectionAngleCount Number of projection angles. + * @param _iDetectorRowCount Number of rows of detectors. + * @param _iDetectorColCount Number of columns detectors. + * @param _fDetectorSpacingX Spacing between the detector points on the X-axis, in unit lengths. Assumed to be constant throughout the entire detector plate. + * @param _fDetectorSpacingY Spacing between the detector points on the Y-axis, in unit lengths. Assumed to be constant throughout the entire detector plate. + * @param _pfProjectionAngles Pointer to an array of projection angles. The angles will be copied from this array. All angles + * are represented in radians and lie in the [0,2pi[ interval. + */ + bool _initialize(int _iProjectionAngleCount, + int _iDetectorRowCount, + int _iDetectorColCount, + float32 _fDetectorSpacingX, + float32 _fDetectorSpacingY, + const float32* _pfProjectionAngles, + const float32* _pfExtraDetectorOffsetsX = NULL, + const float32* _pfExtraDetectorOffsetsY = NULL); + +public: + + /** Destructor + */ + virtual ~CProjectionGeometry3D(); + + /** Clear all member variables, setting all numeric variables to 0 and all pointers to NULL. + */ + virtual void clear(); + + /** Create a hard copy. + */ + virtual CProjectionGeometry3D* clone() const = 0; + + /** Initialize the geometry with a config object. + * + * @param _cfg Configuration Object + * @return initialization successful? + */ + virtual bool initialize(const Config& _cfg); + + /** Get the initialization state of the object. + * + * @return true iff the object has been initialized + */ + bool isInitialized() const; + + /** Return true if this geometry instance is the same as the one specified. + * + * @return true if this geometry instance is the same as the one specified. + */ + virtual bool isEqual(const CProjectionGeometry3D *) const = 0; + + /** Get the number of projections. + * + * @return Number of projections + */ + int getProjectionCount() const; + + /** Get the number of rows of detectors. + * + * @return Number of rows of detectors. + */ + int getDetectorRowCount() const; + + /** Get the number of columns of detectors. + * + * @return Number of columns of detectors. + */ + int getDetectorColCount() const; + + /** Get the total number of detectors. + * + * @return Total number of detectors. + */ + int getDetectorTotCount() const; + + /** Get the width of a detector. + * + * @return Width of a detector, in unit lengths + */ + float32 getDetectorSpacingX() const; + + /** Get the height of a detector. + * + * @return Height of a detector, in unit lengths + */ + float32 getDetectorSpacingY() const; + + /** Get a projection angle, given by its index. The angle is represented in Radians. + * + * @return Projection angle with index _iProjectionIndex + */ + float32 getProjectionAngle(int _iProjectionIndex) const; + + /** Get a projection angle, given by its index. The angle is represented in degrees. + * + * @return Projection angle with index _iProjectionIndex + */ +// float32 getProjectionAngleDegrees(int _iProjectionIndex) const; + + /** Returns a buffer containing all projection angles. The element count of the buffer is equal + * to the number given by getProjectionAngleCount. + * + * The angles are in radians. + * + * @return Pointer to buffer containing the angles. + */ + const float32* getProjectionAngles() const; + + const float32* getExtraDetectorOffsetsX() const; + + const float32* getExtraDetectorOffsetsY() const; + + float32 getExtraDetectorOffsetX(int _iProjectionIndex) const; + + float32 getExtraDetectorOffsetY(int _iProjectionIndex) const; + + AstraError setExtraDetectorOffsetsX(float32* _pfExtraDetectorOffsetsX); + + AstraError setExtraDetectorOffsetsY(float32* _pfExtraDetectorOffsetsY); + + /** Get the column index coordinate of a point on a detector array. + * + * @param _fOffsetX Distance between the center of the detector array and a certain point (both on the X-axis). + * @return The location of the point in index X-coordinates (still float, not rounded) + */ + virtual float32 detectorOffsetXToColIndexFloat(float32 _fOffsetX) const; + + /** Get the row index coordinate of a point on a detector array. + * + * @param _fOffsetY Distance between the center of the detector array and a certain point (both on the Y-axis). + * @return The location of the point in index Y-coordinates (still float, not rounded) + */ + virtual float32 detectorOffsetYToRowIndexFloat(float32 _fOffsetY) const; + + /** Get the offset of a detector on the X-axis based on its index coordinate. + * + * @param _iIndex the index of the detector. + * @return the offset from the center of the detector array on the X-axis. + */ + virtual float32 indexToDetectorOffsetX(int _iIndex) const; + + /** Get the offset of a detector on the Y-axis based on its index coordinate. + * + * @param _iIndex the index of the detector. + * @return the offset from the center of the detector array on the Y-axis. + */ + virtual float32 indexToDetectorOffsetY(int _iIndex) const; + + /** Get the offset of a detector on the X-axis based on its column index coordinate. + * + * @param _iIndex the index of the detector. + * @return the offset from the center of the detector array on the X-axis. + */ + virtual float32 colIndexToDetectorOffsetX(int _iIndex) const; + + /** Get the offset of a detector on the Y-axis based on its row index coordinate. + * + * @param _iIndex the index of the detector. + * @return the offset from the center of the detector array on the Y-axis. + */ + virtual float32 rowIndexToDetectorOffsetY(int _iIndex) const; + + /** Get the row and column index of a detector based on its index. + * + * @param _iDetectorIndex in: the index of the detector. + * @param _iDetectorRow out: the row index of the detector. + * @param _iDetectorCol out: the column index of the detector. + */ + virtual void detectorIndexToRowCol(int _iDetectorIndex, int& _iDetectorRow, int& _iDetectorCol) const; + + /** Get the angle and detector index of a detector + * + * @param _iIndex the index of the detector. + * @param _iAngleIndex output: index of angle + * @param _iDetectorIndex output: index of dectecor + */ + virtual void indexToAngleDetectorIndex(int _iIndex, int& _iAngleIndex, int& _iDetectorIndex) const; + + /** Returns true if the type of geometry defined in this class is the one specified in _sType. + * + * @param _sType geometry type to compare to. + * @return true if the type of geometry defined in this class is the one specified in _sType. + */ + virtual bool isOfType(const std::string& _sType) const = 0; + + /** Turn this object into an XML object. + * + * @param _sNode The XML object to fill. + */ + virtual void toXML(XMLNode* _sNode) const = 0; + + /** + * Returns a vector giving the projection direction for a projection and detector index + */ + virtual CVector3D getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const = 0; + + + //< For Config unused argument checking + ConfigCheckData* configCheckData; + friend class ConfigStackCheck<CProjectionGeometry3D>; +}; + + + +//---------------------------------------------------------------------------------------- +// Inline member functions +//---------------------------------------------------------------------------------------- +// Get the initialization state. +inline bool CProjectionGeometry3D::isInitialized() const +{ + return m_bInitialized; +} + +//---------------------------------------------------------------------------------------- +// Get the number of detectors. +inline int CProjectionGeometry3D::getDetectorRowCount() const +{ + ASTRA_ASSERT(m_bInitialized); + return m_iDetectorRowCount; +} + +//---------------------------------------------------------------------------------------- +// Get the number of detectors. +inline int CProjectionGeometry3D::getDetectorColCount() const +{ + ASTRA_ASSERT(m_bInitialized); + return m_iDetectorColCount; +} + +//---------------------------------------------------------------------------------------- +// Get the number of detectors. +inline int CProjectionGeometry3D::getDetectorTotCount() const +{ + ASTRA_ASSERT(m_bInitialized); + return m_iDetectorTotCount; +} + +//---------------------------------------------------------------------------------------- +// Get the width of a single detector (in unit lengths). +inline float32 CProjectionGeometry3D::getDetectorSpacingX() const +{ + ASTRA_ASSERT(m_bInitialized); + return m_fDetectorSpacingX; +} +//---------------------------------------------------------------------------------------- +// Get the width of a single detector (in unit lengths). +inline float32 CProjectionGeometry3D::getDetectorSpacingY() const +{ + ASTRA_ASSERT(m_bInitialized); + return m_fDetectorSpacingY; +} + +//---------------------------------------------------------------------------------------- +// Get the number of projection angles. +inline int CProjectionGeometry3D::getProjectionCount() const +{ + ASTRA_ASSERT(m_bInitialized); + return m_iProjectionAngleCount; +} + +//---------------------------------------------------------------------------------------- +// Get a projection angle, represented in Radians. +inline float32 CProjectionGeometry3D::getProjectionAngle(int _iProjectionIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iProjectionIndex >= 0); + ASTRA_ASSERT(_iProjectionIndex < m_iProjectionAngleCount); + + return m_pfProjectionAngles[_iProjectionIndex]; +} + +/* +//---------------------------------------------------------------------------------------- +// Get a projection angle, represented in degrees. +inline float32 CProjectionGeometry3D::getProjectionAngleDegrees(int _iProjectionIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iProjectionIndex >= 0); + ASTRA_ASSERT(_iProjectionIndex < m_iProjectionAngleCount); + + return (m_pfProjectionAngles[_iProjectionIndex] * 180.0f / PI32); +} +*/ + + +//---------------------------------------------------------------------------------------- +// Get pointer to buffer used to store projection angles. +inline const float32* CProjectionGeometry3D::getProjectionAngles() const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + + return m_pfProjectionAngles; +} + + +//---------------------------------------------------------------------------------------- +// Get pointer to buffer used to store x-translations of the projection images. +inline const float32* CProjectionGeometry3D::getExtraDetectorOffsetsX() const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + + return m_pfExtraDetectorOffsetsX; +} + +//---------------------------------------------------------------------------------------- +// Get pointer to buffer used to store y-translations of the projection images. +inline const float32* CProjectionGeometry3D::getExtraDetectorOffsetsY() const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + + return m_pfExtraDetectorOffsetsY; +} +//---------------------------------------------------------------------------------------- +// Get the x-translation of a specific projection image. +inline float32 CProjectionGeometry3D::getExtraDetectorOffsetX(int _iProjectionIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + + return m_pfExtraDetectorOffsetsX[_iProjectionIndex]; +} + +//---------------------------------------------------------------------------------------- +// Get the y-translation of a specific projection image. +inline float32 CProjectionGeometry3D::getExtraDetectorOffsetY(int _iProjectionIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + + return m_pfExtraDetectorOffsetsX[_iProjectionIndex]; +} +//---------------------------------------------------------------------------------------- +// detector offset X -> detector column index (float) +inline float32 CProjectionGeometry3D::detectorOffsetXToColIndexFloat(float32 _fOffsetX) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + + return (_fOffsetX / m_fDetectorSpacingX) + ((m_iDetectorColCount-1.0f) / 2.0f); +} + +//---------------------------------------------------------------------------------------- +// detector offset Y -> detector row index (float) +inline float32 CProjectionGeometry3D::detectorOffsetYToRowIndexFloat(float32 _fOffsetY) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + + return (_fOffsetY / m_fDetectorSpacingY) + ((m_iDetectorRowCount-1.0f) / 2.0f); +} + +//---------------------------------------------------------------------------------------- +// detector index -> detector offset X +inline float32 CProjectionGeometry3D::indexToDetectorOffsetX(int _iIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iIndex >= 0); + ASTRA_ASSERT(_iIndex < m_iDetectorTotCount); + + _iIndex = _iIndex % m_iDetectorColCount; + return (_iIndex - (m_iDetectorColCount-1.0f) / 2.0f) * m_fDetectorSpacingX; +} + +//---------------------------------------------------------------------------------------- +// detector index -> detector offset Y +inline float32 CProjectionGeometry3D::indexToDetectorOffsetY(int _iIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iIndex >= 0); + ASTRA_ASSERT(_iIndex < m_iDetectorTotCount); + + _iIndex = _iIndex / m_iDetectorColCount; + return -(_iIndex - (m_iDetectorRowCount-1.0f) / 2.0f) * m_fDetectorSpacingY; +} + +//---------------------------------------------------------------------------------------- +// detector index -> detector offset X +inline float32 CProjectionGeometry3D::colIndexToDetectorOffsetX(int _iIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iIndex >= 0); + ASTRA_ASSERT(_iIndex < m_iDetectorColCount); + + return (_iIndex - (m_iDetectorColCount-1.0f) / 2.0f) * m_fDetectorSpacingX; +} + +//---------------------------------------------------------------------------------------- +// detector index -> detector offset Y +inline float32 CProjectionGeometry3D::rowIndexToDetectorOffsetY(int _iIndex) const +{ + // basic checks + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iIndex >= 0); + ASTRA_ASSERT(_iIndex < m_iDetectorRowCount); + + return (_iIndex - (m_iDetectorRowCount-1.0f) / 2.0f) * m_fDetectorSpacingY; +} + +//---------------------------------------------------------------------------------------- +// detector index -> row index & column index +inline void CProjectionGeometry3D::detectorIndexToRowCol(int _iDetectorIndex, int& _iDetectorRow, int& _iDetectorCol) const +{ + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iDetectorIndex >= 0); + ASTRA_ASSERT(_iDetectorIndex < m_iDetectorTotCount); + + _iDetectorRow = _iDetectorIndex / m_iDetectorColCount; + _iDetectorCol = _iDetectorIndex % m_iDetectorColCount; +} + +//---------------------------------------------------------------------------------------- +inline void CProjectionGeometry3D::indexToAngleDetectorIndex(int _iIndex, int& _iAngleIndex, int& _iDetectorIndex) const +{ + ASTRA_ASSERT(m_bInitialized); + ASTRA_ASSERT(_iIndex >= 0); + ASTRA_ASSERT(_iIndex < m_iDetectorTotCount * m_iProjectionAngleCount); + +// int det_row = _iIndex / (m_iDetectorColCount*m_iProjectionAngleCount); +// int det_col = _iIndex % m_iDetectorColCount; +// +// _iAngleIndex = _iIndex % (m_iDetectorColCount*m_iProjectionAngleCount) / m_iDetectorColCount; +// _iDetectorIndex = det_row * m_iDetectorColCount + det_col; + + _iAngleIndex = (_iIndex % (m_iDetectorColCount*m_iProjectionAngleCount)) / m_iDetectorColCount; + _iDetectorIndex = _iIndex / m_iProjectionAngleCount + (_iIndex % m_iDetectorColCount); + +} + +//---------------------------------------------------------------------------------------- + +} // end namespace astra + +#endif /* _INC_ASTRA_PROJECTIONGEOMETRY2D */ |