LCOV - code coverage report
Current view: top level - elsa/projectors - BSplines.h (source / functions) Hit Total Coverage
Test: coverage-all.lcov Lines: 20 27 74.1 %
Date: 2022-08-25 03:05:39 Functions: 4 6 66.7 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "elsaDefines.h"
       4             : #include "Assertions.h"
       5             : #include "Math.hpp"
       6             : 
       7             : #include <cmath>
       8             : #include "spdlog/fmt/bundled/core.h"
       9             : #include "spdlog/fmt/fmt.h"
      10             : 
      11             : namespace elsa
      12             : {
      13             :     namespace bspline
      14             :     {
      15             :         /// @brief Evaluate the 1-dimensional B-Spline of degree m, with m + 2 equally spaced knots
      16             :         ///
      17             :         /// This is based on the implementation given as in e.g.:
      18             :         /// Fast B-spline transforms for continuous image representation and interpolation, Unser
      19             :         /// et. al. (1991), equation 2.2
      20             :         ///
      21             :         /// @param x coordinate to evaluate 1-dimensional B-Spline at
      22             :         /// @param m order of B-Spline
      23             :         template <typename data_t>
      24             :         constexpr data_t bspline1d_evaluate(data_t x, index_t m) noexcept
      25        6126 :         {
      26        6126 :             const auto xs = x + (m + 1) / data_t{2};
      27        6126 :             data_t res = 0;
      28             : 
      29       27630 :             for (int n = 0; n <= m + 1; ++n) {
      30       21504 :                 const auto tmp1 = math::heaviside<data_t>(xs - n, 0);
      31       21504 :                 const auto tmp2 = std::pow<data_t>(xs - n, m);
      32       21504 :                 const auto tmp3 = math::binom(m + 1, n);
      33       21504 :                 const auto tmp4 = std::pow<data_t>(-1, n) / math::factorial(m);
      34       21504 :                 res += tmp1 * tmp2 * tmp3 * tmp4;
      35       21504 :             }
      36             : 
      37        6126 :             return res;
      38        6126 :         }
      39             : 
      40             :         /// @brief Evaluate n-dimensional B-Spline of degree m. As B-Splines are separable, this is
      41             :         /// just the product of 1-dimensional B-Splines.
      42             :         ///
      43             :         /// @param x n-dimensional coordinate to evaluate B-Spline at
      44             :         /// @param m order of B-Spline
      45             :         template <typename data_t>
      46             :         constexpr data_t nd_bspline_evaluate(const Vector_t<data_t>& x, index_t m) noexcept
      47           0 :         {
      48           0 :             data_t res = bspline1d_evaluate(x[0], m);
      49           0 :             for (int i = 1; i < x.size(); ++i) {
      50           0 :                 res *= bspline1d_evaluate(x[i], m);
      51           0 :             }
      52           0 :             return res;
      53           0 :         }
      54             : 
      55             :         /// @brief Evaluate n-dimensional B-Spline at a given coordinate for the first dimension,
      56             :         /// and at the center (i.e. `0`) at all the other dimensions. This is particular useful as
      57             :         /// an approximation during the calculation of the line integral
      58             :         ///
      59             :         /// @param x 1-dimensional coordinate to evaluate B-Spline at
      60             :         /// @param m order of B-Spline
      61             :         /// @param dim dimension of B-Spline
      62             :         template <typename data_t>
      63             :         constexpr data_t nd_bspline_centered(data_t x, int m, int dim) noexcept
      64        4042 :         {
      65        4042 :             data_t res = bspline1d_evaluate<data_t>(x, m);
      66        6063 :             for (int i = 1; i < dim; ++i) {
      67        2021 :                 const auto inc = bspline1d_evaluate<data_t>(0., m);
      68        2021 :                 res *= inc;
      69        2021 :             }
      70        4042 :             return res;
      71        4042 :         }
      72             :     } // namespace bspline
      73             : 
      74             :     /// @brief Represent a B-Spline basis function of a given dimension and order
      75             :     template <typename data_t>
      76             :     class BSpline
      77             :     {
      78             :     public:
      79             :         BSpline(index_t dim, index_t order);
      80             : 
      81             :         data_t operator()(Vector_t<data_t> x);
      82             : 
      83             :         index_t order() const;
      84             : 
      85             :         index_t dim() const;
      86             : 
      87             :     private:
      88             :         /// Dimension of B-Spline
      89             :         index_t dim_;
      90             : 
      91             :         /// Order of B-Spline
      92             :         index_t order_;
      93             :     };
      94             : 
      95             :     /// @brief Represent a projected B-Spline basis function of a given dimension and order.
      96             :     /// Projected B-Splines are again B-Spline of n-1 dimensions. Using the fact, that B-Splines
      97             :     /// are close to symmetrical, we can approximate the projection only based on distance.
      98             :     template <typename data_t>
      99             :     class ProjectedBSpline
     100             :     {
     101             :     public:
     102             :         ProjectedBSpline(index_t dim, index_t order);
     103             : 
     104             :         data_t operator()(data_t s);
     105             : 
     106             :         index_t order() const;
     107             : 
     108             :         index_t dim() const;
     109             : 
     110             :     private:
     111             :         /// Dimension of B-Spline
     112             :         index_t dim_;
     113             : 
     114             :         /// Order of B-Spline
     115             :         index_t order_;
     116             :     };
     117             : } // namespace elsa

Generated by: LCOV version 1.14