Line data Source code
1 : #pragma once 2 : 3 : #include "LinearOperator.h" 4 : #include "BlockDescriptor.h" 5 : #include "FiniteDifferences.h" 6 : #include "IdenticalBlocksDescriptor.h" 7 : 8 : #include <vector> 9 : 10 : namespace elsa 11 : { 12 : /** 13 : * @brief Operator to compute symmetrized derivative, represents second derivative term for 14 : * total generalized variation 15 : * 16 : * Domain of this operator should always contain two blocks 17 : * 18 : * Applied on a container @f$x@f$, it returns the following 3-block container: 19 : * 20 : * @f[ 21 : * \left[\begin{array}{c} 22 : * D_1^{+} x_1 \\ 23 : * D_2^{+} x_2 \\ 24 : * \frac{1}{2}\left(D_2^{+} x^1+D_1^{+} x^2\right) 25 : * \end{array}\right] 26 : * @f] 27 : * 28 : * where @f$D_1^{+}@f$ stays for forward finite differences operator along x dimension. 29 : * 30 : * Adjoing on @f$y@f$: 31 : * 32 : * @f[ 33 : * \left[\begin{array}{l} 34 : * -D_1^{-} y^1 - \D_2^{-} y^3 \\ 35 : * -D_1^{-} y^3 - \D_2^{-} y^2 36 : * \end{array}\right] 37 : * @f] 38 : * 39 : * where @f$D_1^{-}@f$ is backwards finite differences operator along x dimension. 40 : * 41 : * References: 42 : * - Mei, Jin-Jin, et al. "Second order total generalized variation for speckle reduction in 43 : * ultrasound images." Journal of the Franklin Institute 355.1 (2018): 574-595, p.577 44 : * 45 : * - Bredies, Kristian, and Hong Peng Sun. "Preconditioned Douglas–Rachford algorithms for 46 : * TV-and TGV-regularized variational imaging problems." Journal of Mathematical Imaging and 47 : * Vision 52.3 (2015): 317-344. 48 : */ 49 : template <typename data_t = real_t> 50 : class SymmetrizedDerivative : public LinearOperator<data_t> 51 : { 52 : public: 53 : SymmetrizedDerivative(const DataDescriptor& domainDescriptor); 54 : 55 10 : ~SymmetrizedDerivative() override = default; 56 : 57 : protected: 58 : /// default copy constructor, hidden from non-derived classes to prevent potential slicing 59 : SymmetrizedDerivative(const SymmetrizedDerivative<data_t>&) = default; 60 : 61 : /// apply the symmetrized derivative operator 62 : void applyImpl(const DataContainer<data_t>& x, DataContainer<data_t>& Ax) const override; 63 : 64 : /// apply the adjoint of the symmetrized derivative operator 65 : void applyAdjointImpl(const DataContainer<data_t>& y, 66 : DataContainer<data_t>& Aty) const override; 67 : 68 : /// implement the polymorphic clone operation 69 : SymmetrizedDerivative<data_t>* cloneImpl() const override; 70 : 71 : /// implement the polymorphic comparison operation 72 : bool isEqual(const LinearOperator<data_t>& other) const override; 73 : 74 : private: 75 : static LinearOperator<data_t> createBase(const DataDescriptor& domainDescriptor); 76 : void precomputeHelpers(); 77 : 78 : std::unique_ptr<FiniteDifferences<data_t>> forwardX_; 79 : std::unique_ptr<FiniteDifferences<data_t>> forwardY_; 80 : std::unique_ptr<FiniteDifferences<data_t>> backwardX_; 81 : std::unique_ptr<FiniteDifferences<data_t>> backwardY_; 82 : }; 83 : } // namespace elsa