Line data Source code
1 : #pragma once 2 : 3 : #include "LinearOperator.h" 4 : #include "Geometry.h" 5 : #include "BoundingBox.h" 6 : #include "VolumeDescriptor.h" 7 : #include "DetectorDescriptor.h" 8 : #include "XrayProjector.h" 9 : 10 : #include <vector> 11 : #include <utility> 12 : 13 : #include <Eigen/Geometry> 14 : 15 : namespace elsa 16 : { 17 : template <typename data_t = real_t> 18 : class JosephsMethod; 19 : 20 : template <typename data_t> 21 : struct XrayProjectorInnerTypes<JosephsMethod<data_t>> { 22 : using value_type = data_t; 23 : using forward_tag = any_projection_tag; 24 : using backward_tag = any_projection_tag; 25 : }; 26 : 27 : /** 28 : * @brief Operator representing the discretized X-ray transform in 2d/3d using Joseph's method. 29 : * 30 : * @author Christoph Hahn - initial implementation 31 : * @author Maximilian Hornung - modularization 32 : * @author Nikola Dinev - fixes 33 : * 34 : * @tparam data_t data type for the domain and range of the operator, defaulting to real_t 35 : * 36 : * The volume is traversed along the rays as specified by the Geometry. For interior voxels 37 : * the sampling point is located in the middle of the two planes orthogonal to the main 38 : * direction of the ray. For boundary voxels the sampling point is located at the center of the 39 : * ray intersection with the voxel. 40 : * 41 : * The geometry is represented as a list of projection matrices (see class Geometry), one for 42 : * each acquisition pose. 43 : * 44 : * Two modes of interpolation are available: 45 : * NN (NearestNeighbours) takes the value of the pixel/voxel containing the point 46 : * LINEAR performs linear interpolation for the nearest 2 pixels (in 2D) 47 : * or the nearest 4 voxels (in 3D). 48 : * 49 : * Forward projection is accomplished using apply(), backward projection using applyAdjoint(). 50 : * This projector is matched. 51 : */ 52 : template <typename data_t> 53 : class JosephsMethod : public XrayProjector<JosephsMethod<data_t>> 54 : { 55 : public: 56 : using self_type = JosephsMethod<data_t>; 57 : using base_type = XrayProjector<self_type>; 58 : using value_type = typename base_type::value_type; 59 : using forward_tag = typename base_type::forward_tag; 60 : using backward_tag = typename base_type::backward_tag; 61 : 62 : /** 63 : * @brief Constructor for Joseph's traversal method. 64 : * 65 : * @param[in] domainDescriptor describing the domain of the operator (the volume) 66 : * @param[in] rangeDescriptor describing the range of the operator (the sinogram) 67 : * @param[in] interpolation enum specifying the interpolation mode 68 : * 69 : * The domain is expected to be 2 or 3 dimensional (volSizeX, volSizeY, [volSizeZ]), 70 : * the range is expected to be matching the domain (detSizeX, [detSizeY], acqPoses). 71 : */ 72 : JosephsMethod(const VolumeDescriptor& domainDescriptor, 73 : const DetectorDescriptor& rangeDescriptor); 74 : 75 : /// default destructor 76 62 : ~JosephsMethod() = default; 77 : 78 : protected: 79 : /// default copy constructor, hidden from non-derived classes to prevent potential slicing 80 : JosephsMethod(const JosephsMethod<data_t>&) = default; 81 : 82 : private: 83 : /// apply Joseph's method (i.e. forward projection) 84 : void forward(const BoundingBox& aabb, const DataContainer<data_t>& x, 85 : DataContainer<data_t>& Ax) const; 86 : 87 : /// apply the adjoint of Joseph's method (i.e. backward projection) 88 : void backward(const BoundingBox& aabb, const DataContainer<data_t>& y, 89 : DataContainer<data_t>& Aty) const; 90 : 91 : /// implement the polymorphic clone operation 92 : JosephsMethod<data_t>* _cloneImpl() const; 93 : 94 : /// implement the polymorphic comparison operation 95 : bool _isEqual(const LinearOperator<data_t>& other) const; 96 : 97 : /// the traversal routine (for both apply/applyAdjoint) 98 : template <bool adjoint, int dim> 99 : void traverseVolume(const BoundingBox& aabb, const DataContainer<data_t>& vector, 100 : DataContainer<data_t>& result) const; 101 : 102 : friend class XrayProjector<self_type>; 103 : }; 104 : } // namespace elsa