1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 19 #ifndef itkLevelSetEquationContainer_h 20 #define itkLevelSetEquationContainer_h 21 22 #include "itkObject.h" 23 #include "itkObjectFactory.h" 24 25 namespace itk 26 { 27 /** 28 * \class LevelSetEquationContainer 29 * \brief Class for holding a set of level set equations (PDEs). 30 * 31 * \tparam TTermContainer Container holding the terms in a level set equation 32 * 33 * Evolving level-set functions \f$\left\{ \phi_j \right\}_{j=1}^{M}\f$ 34 * can be expressed as follows: 35 * \f{eqnarray*}{ 36 * \frac{\partial \phi_1(p)}{\partial \tau} &=& \sum\limits_{i=1}^{N_1} \alpha_{i1} 37 * \cdot \omega_{i1}(p) \\ 38 * \frac{\partial \phi_2(p)}{\partial \tau} &=& \sum\limits_{i=1}^{N_2} \alpha_{i2} 39 * \cdot \omega_{i2}(p) \\ 40 * & \vdots & \\ 41 * \frac{\partial \phi_M(p)}{\partial \tau} &=& \sum\limits_{i=1}^{N_M} \alpha_{iM} 42 * \cdot \omega_{iM}(p) 43 * \f} 44 * where \f$\omega_{iM}\f$ is a term which could depend on any of the level-set 45 * functions \f$\left\{ \phi_j \right\}_{j=1}^{M}\f$ , the input image, 46 * and \f$\alpha_{iM}\f$ is a weight to balance the contribution of each term 47 * in the PDE. 48 * 49 * Each equation of this system of equation (PDE) is referred as an equation in 50 * the level-set framework. Each equation \f$ equation_{j} \f$ contributes to the 51 * evolution of the level-set function \f$ \phi_j \f$. 52 * 53 * \sa LevelSetEquationTerm 54 * 55 * \ingroup ITKLevelSetsv4 56 */ 57 template< typename TTermContainer > 58 class ITK_TEMPLATE_EXPORT LevelSetEquationContainer : public Object 59 { 60 public: 61 ITK_DISALLOW_COPY_AND_ASSIGN(LevelSetEquationContainer); 62 63 using Self = LevelSetEquationContainer; 64 using Pointer = SmartPointer< Self >; 65 using ConstPointer = SmartPointer< const Self >; 66 using Superclass = Object; 67 68 /** Method for creation through object factory */ 69 itkNewMacro( Self ); 70 71 /** Run-time type information */ 72 itkTypeMacro( LevelSetEquationContainer, Object ); 73 74 using TermContainerType = TTermContainer; 75 using TermContainerPointer = typename TermContainerType::Pointer; 76 77 using InputImageType = typename TermContainerType::InputImageType; 78 using InputImagePointer = typename TermContainerType::InputImagePointer; 79 80 using LevelSetOutputRealType = typename TermContainerType::LevelSetOutputRealType; 81 using LevelSetInputIndexType = typename TermContainerType::LevelSetInputIndexType; 82 83 using LevelSetIdentifierType = typename TermContainerType::LevelSetIdentifierType; 84 using LevelSetContainerType = typename TermContainerType::LevelSetContainerType; 85 using LevelSetContainerPointer = typename TermContainerType::LevelSetContainerPointer; 86 87 /** Add a equation to the system of equations in the EquationContainer map */ 88 void AddEquation( const LevelSetIdentifierType& iId, TermContainerType * iEquation ); 89 90 /** Return a pointer to the equation of given id */ 91 TermContainerType * GetEquation( const LevelSetIdentifierType& iId ) const; 92 93 /** Update the equation container recursively by calling update on individual equations */ 94 void UpdateInternalEquationTerms(); 95 96 /** Supply the update at a given pixel index to update the terms */ 97 void UpdatePixel( const LevelSetInputIndexType & iP, 98 const LevelSetOutputRealType & oldValue, 99 const LevelSetOutputRealType & newValue ); 100 101 /** Initialize parameters in the terms of all the equations */ 102 void InitializeParameters(); 103 104 /** Returns the Courant-Friedrichs-Lewy (CFL) contribution 105 * for all the equations */ 106 LevelSetOutputRealType ComputeCFLContribution() const; 107 108 /** Set/Get the input speed or feature image */ 109 itkSetObjectMacro( Input, InputImageType ); 110 itkGetModifiableObjectMacro(Input, InputImageType ); 111 112 itkSetObjectMacro( LevelSetContainer, LevelSetContainerType ); 113 itkGetModifiableObjectMacro(LevelSetContainer, LevelSetContainerType ); 114 115 protected: 116 using MapContainerType = std::map< LevelSetIdentifierType, TermContainerPointer >; 117 using MapContainerIterator = typename MapContainerType::iterator; 118 using MapContainerConstIterator = typename MapContainerType::const_iterator; 119 120 public: 121 class Iterator; 122 friend class Iterator; 123 124 class ConstIterator 125 { 126 public: 127 ConstIterator() = default; ConstIterator(const MapContainerConstIterator & it)128 ConstIterator( const MapContainerConstIterator& it ) : m_Iterator( it ) {} 129 ~ConstIterator() = default; ConstIterator(const Iterator & it)130 ConstIterator( const Iterator& it ) : m_Iterator( it.m_Iterator ) {} 131 ConstIterator & operator * () { return *this; } 132 ConstIterator * operator->() { return this; } 133 ConstIterator & operator++() 134 { 135 ++m_Iterator; 136 return *this; 137 } 138 ConstIterator operator++(int) 139 { 140 ConstIterator tmp( *this ); 141 ++(*this); 142 return tmp; 143 } 144 ConstIterator & operator--() 145 { 146 --m_Iterator; 147 return *this; 148 } 149 ConstIterator operator--(int) 150 { 151 ConstIterator tmp( *this ); 152 --(*this); 153 return tmp; 154 } 155 bool operator == (const Iterator& it) const 156 { 157 return (m_Iterator == it.m_Iterator); 158 } 159 bool operator != (const Iterator& it) const 160 { 161 return (m_Iterator != it.m_Iterator); 162 } 163 bool operator == (const ConstIterator& it) const 164 { 165 return (m_Iterator == it.m_Iterator); 166 } 167 bool operator != (const ConstIterator& it) const 168 { 169 return (m_Iterator != it.m_Iterator); 170 } GetIdentifier()171 LevelSetIdentifierType GetIdentifier() const 172 { 173 return m_Iterator->first; 174 } 175 GetEquation()176 TermContainerType * GetEquation() const 177 { 178 return m_Iterator->second; 179 } 180 private: 181 MapContainerConstIterator m_Iterator; 182 friend class Iterator; 183 }; 184 185 class Iterator 186 { 187 public: 188 Iterator() = default; Iterator(const MapContainerIterator & it)189 Iterator( const MapContainerIterator& it ) : m_Iterator( it ) {} Iterator(const ConstIterator & it)190 Iterator( const ConstIterator& it ) : m_Iterator( it.m_Iterator ) {} 191 ~Iterator() = default; 192 193 Iterator & operator * () { return *this; } 194 Iterator * operator ->() { return this; } 195 196 Iterator & operator++() 197 { 198 ++m_Iterator; 199 return *this; 200 } 201 Iterator operator++(int) 202 { 203 Iterator tmp( *this ); 204 ++(*this); 205 return tmp; 206 } 207 Iterator & operator--() 208 { 209 --m_Iterator; 210 return *this; 211 } 212 Iterator operator--(int) 213 { 214 Iterator tmp( *this ); 215 --(*this); 216 return tmp; 217 } 218 219 bool operator==(const Iterator& it) const 220 { 221 return (m_Iterator==it.m_Iterator); 222 } 223 bool operator!=(const Iterator& it) const 224 { 225 return (m_Iterator!=it.m_Iterator); 226 } 227 bool operator==(const ConstIterator& it)const 228 { 229 return (m_Iterator == it.m_Iterator); 230 } 231 bool operator!=(const ConstIterator& it)const 232 { 233 return (m_Iterator != it.m_Iterator); 234 } GetIdentifier()235 LevelSetIdentifierType GetIdentifier() const 236 { 237 return m_Iterator->first; 238 } 239 GetEquation()240 TermContainerType * GetEquation() const 241 { 242 return m_Iterator->second; 243 } 244 private: 245 MapContainerIterator m_Iterator; 246 friend class ConstIterator; 247 }; 248 249 Iterator Begin(); 250 Iterator End(); 251 252 ConstIterator Begin() const; 253 ConstIterator End() const; 254 255 protected: 256 257 LevelSetEquationContainer() = default; 258 ~LevelSetEquationContainer() override = default; 259 260 LevelSetContainerPointer m_LevelSetContainer; 261 MapContainerType m_Container; 262 InputImagePointer m_Input; 263 }; 264 } 265 266 #ifndef ITK_MANUAL_INSTANTIATION 267 #include "itkLevelSetEquationContainer.hxx" 268 #endif 269 270 #endif // itkLevelSetEquationContainer_h 271