Line data Source code
1 : #include "PlanarDetectorDescriptor.h" 2 : #include <iostream> 3 : 4 : namespace elsa 5 : { 6 : PlanarDetectorDescriptor::PlanarDetectorDescriptor(const IndexVector_t& numOfCoeffsPerDim, 7 : const std::vector<Geometry>& geometryList) 8 : : DetectorDescriptor(numOfCoeffsPerDim, geometryList) 9 1068 : { 10 1068 : } 11 : PlanarDetectorDescriptor::PlanarDetectorDescriptor(const IndexVector_t& numOfCoeffsPerDim, 12 : const RealVector_t& spacingPerDim, 13 : const std::vector<Geometry>& geometryList) 14 : : DetectorDescriptor(numOfCoeffsPerDim, spacingPerDim, geometryList) 15 3081 : { 16 3081 : } 17 : 18 : RealRay_t 19 : PlanarDetectorDescriptor::computeRayFromDetectorCoord(const RealVector_t& detectorCoord, 20 : const index_t poseIndex) const 21 299907 : { 22 : // Assert that for all dimension of detectorCoord is in bounds and poseIndex can 23 : // be index in the _geometry. If not the calculation will not be correct, but 24 : // as this is the hot path, I don't want exceptions and unpacking everything 25 : // We'll just have to ensure, that we don't mess up in our hot path! :-) 26 299907 : assert((detectorCoord.block(0, 0, getNumberOfDimensions() - 1, 0).array() 27 299907 : < getNumberOfCoefficientsPerDimension() 28 299907 : .block(0, 0, getNumberOfDimensions() - 1, 0) 29 299907 : .template cast<real_t>() 30 299907 : .array()) 31 299907 : .all() 32 299907 : && "PlanarDetectorDescriptor::computeRayToDetector: Assumption detectorCoord in " 33 299907 : "bounds, wrong"); 34 299907 : assert(asUnsigned(poseIndex) < _geometry.size() 35 299907 : && "PlanarDetectorDescriptor::computeRayToDetector: Assumption poseIndex smaller " 36 299907 : "than number of poses, wrong"); 37 : 38 299907 : auto dim = getNumberOfDimensions(); 39 : 40 : // get the pose of trajectory 41 299907 : auto geometry = _geometry[asUnsigned(poseIndex)]; 42 : 43 299907 : auto projInvMatrix = geometry.getInverseProjectionMatrix(); 44 : 45 : // homogeneous coordinates [p;1], with p in detector space 46 299907 : RealVector_t homogeneousPixelCoord(dim); 47 299907 : homogeneousPixelCoord << detectorCoord, 1; 48 : 49 : // Camera center is always the ray origin 50 299907 : auto ro = geometry.getCameraCenter(); 51 : 52 299907 : auto rd = (projInvMatrix * homogeneousPixelCoord) // Matrix-Vector multiplication 53 299907 : .head(dim) // Transform to non-homogeneous 54 299907 : .normalized(); // normalize vector 55 : 56 299907 : return RealRay_t(ro, rd); 57 299907 : } 58 : 59 : RealVector_t 60 : PlanarDetectorDescriptor::computeDetectorCoordFromRay(const RealRay_t& ray, 61 : const index_t poseIndex) const 62 3 : { 63 3 : auto dim = getNumberOfDimensions(); 64 3 : auto geometry = _geometry[static_cast<std::size_t>(poseIndex)]; 65 : 66 3 : auto projMatrix = geometry.getProjectionMatrix(); 67 : 68 : // Only take the square matrix part 69 3 : auto pixel = (projMatrix.block(0, 0, dim, dim) * ray.direction()).head(dim - 1); 70 : 71 3 : return pixel; 72 3 : } 73 : 74 : bool PlanarDetectorDescriptor::isEqual(const DataDescriptor& other) const 75 4 : { 76 : // PlanarDetectorDescriptor has no data, so just deligate it to base class 77 4 : return DetectorDescriptor::isEqual(other); 78 4 : } 79 : 80 : PlanarDetectorDescriptor* PlanarDetectorDescriptor::cloneImpl() const 81 3048 : { 82 3048 : return new PlanarDetectorDescriptor(getNumberOfCoefficientsPerDimension(), 83 3048 : getSpacingPerDimension(), _geometry); 84 3048 : } 85 : } // namespace elsa