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 itkLevelSetEquationTermContainer_h 20 #define itkLevelSetEquationTermContainer_h 21 22 #include "itkLevelSetEquationTermBase.h" 23 #include "itkObject.h" 24 25 #include <unordered_map> 26 27 #include <map> 28 #include <string> 29 30 namespace itk 31 { 32 /** 33 * \class LevelSetEquationTermContainer 34 * \brief Class for container holding the terms of a given level set update equation 35 * 36 * \tparam TInputImage Input image or speed image or feature image for segmentation 37 * \tparam TLevelSetContainer Container holding the all the level set functions 38 * 39 * \ingroup ITKLevelSetsv4 40 */ 41 template< typename TInputImage, 42 typename TLevelSetContainer > 43 class ITK_TEMPLATE_EXPORT LevelSetEquationTermContainer : public Object 44 { 45 public: 46 ITK_DISALLOW_COPY_AND_ASSIGN(LevelSetEquationTermContainer); 47 48 using Self = LevelSetEquationTermContainer; 49 using Pointer = SmartPointer< Self >; 50 using ConstPointer = SmartPointer< const Self >; 51 using Superclass = Object; 52 53 /** Method for creation through object factory */ 54 itkNewMacro( Self ); 55 56 /** Run-time type information */ 57 itkTypeMacro( LevelSetEquationTermContainer, 58 Object ); 59 60 using TermIdType = unsigned int; 61 62 using InputImageType = TInputImage; 63 using InputImagePointer = typename InputImageType::Pointer; 64 65 using LevelSetContainerType = TLevelSetContainer; 66 using LevelSetContainerPointer = typename LevelSetContainerType::Pointer; 67 68 using LevelSetType = typename LevelSetContainerType::LevelSetType; 69 using LevelSetPointer = typename LevelSetContainerType::LevelSetPointer; 70 71 using LevelSetIdentifierType = typename LevelSetContainerType::LevelSetIdentifierType; 72 using LevelSetOutputPixelType = typename LevelSetContainerType::OutputType; 73 using LevelSetOutputRealType = typename LevelSetContainerType::OutputRealType; 74 using LevelSetDataType = typename LevelSetContainerType::LevelSetDataType; 75 using LevelSetInputIndexType = typename LevelSetContainerType::InputIndexType; 76 using LevelSetGradientType = typename LevelSetContainerType::GradientType; 77 using LevelSetHessianType = typename LevelSetContainerType::HessianType; 78 79 using TermType = 80 LevelSetEquationTermBase< InputImageType, LevelSetContainerType >; 81 using TermPointer = typename TermType::Pointer; 82 83 /** Set/Get the input image to be segmented. */ 84 itkSetObjectMacro( Input, InputImageType ); 85 itkGetModifiableObjectMacro(Input, InputImageType ); 86 87 itkSetMacro( CurrentLevelSetId, LevelSetIdentifierType ); 88 itkGetMacro( CurrentLevelSetId, LevelSetIdentifierType ); 89 90 itkSetObjectMacro( LevelSetContainer, LevelSetContainerType ); 91 itkGetModifiableObjectMacro(LevelSetContainer, LevelSetContainerType ); 92 93 /** Add a term to the end of the container */ 94 void PushTerm( TermType* iTerm ); 95 96 /** Replace the pointer to the term with the given id */ 97 void AddTerm( const TermIdType& iId, TermType* iTerm ); 98 99 /** Get the term with the given id */ 100 TermType* GetTerm( const TermIdType& iId ); 101 102 /** Get the term with the given name */ 103 TermType* GetTerm( const std::string& iName ); 104 105 /** \todo */ 106 void Initialize( const LevelSetInputIndexType& iP ); 107 108 /** Supply the update at a given pixel location to update the term parameters */ 109 void UpdatePixel( const LevelSetInputIndexType& iP, 110 const LevelSetOutputRealType & oldValue, 111 const LevelSetOutputRealType & newValue ); 112 113 /** Initialize the term parameters prior to the start of an iteration */ 114 void InitializeParameters(); 115 116 /** Evaluate the term at a given pixel location */ 117 LevelSetOutputRealType Evaluate( const LevelSetInputIndexType& iP ); 118 119 LevelSetOutputRealType Evaluate( const LevelSetInputIndexType& iP, 120 const LevelSetDataType& iData ); 121 122 /** Update the term parameters at end of iteration */ 123 void Update(); 124 125 /** Return the CFL contribution of the current term */ 126 LevelSetOutputRealType ComputeCFLContribution() const; 127 128 void ComputeRequiredData( const LevelSetInputIndexType& iP, 129 LevelSetDataType& ioData ); 130 131 protected: 132 133 using MapTermContainerType = std::map< TermIdType, TermPointer >; 134 using MapTermContainerIteratorType = typename MapTermContainerType::iterator; 135 using MapTermContainerConstIteratorType = typename MapTermContainerType::const_iterator; 136 137 public: 138 class Iterator; 139 friend class Iterator; 140 141 class ConstIterator 142 { 143 public: 144 ConstIterator() = default; ConstIterator(const MapTermContainerConstIteratorType & it)145 ConstIterator( const MapTermContainerConstIteratorType& it ) : m_Iterator( it ) {} 146 ~ConstIterator() = default; ConstIterator(const Iterator & it)147 ConstIterator( const Iterator& it ) : m_Iterator( it.m_Iterator ) {} 148 ConstIterator & operator * () { return *this; } 149 ConstIterator * operator->() { return this; } 150 ConstIterator & operator++() 151 { 152 ++m_Iterator; 153 return *this; 154 } 155 ConstIterator operator++(int) 156 { 157 ConstIterator tmp( *this ); 158 ++(*this); 159 return tmp; 160 } 161 ConstIterator & operator--() 162 { 163 --m_Iterator; 164 return *this; 165 } 166 ConstIterator operator--(int) 167 { 168 ConstIterator tmp( *this ); 169 --(*this); 170 return tmp; 171 } 172 bool operator == (const Iterator& it) const 173 { 174 return (m_Iterator == it.m_Iterator); 175 } 176 bool operator != (const Iterator& it) const 177 { 178 return (m_Iterator != it.m_Iterator); 179 } 180 bool operator == (const ConstIterator& it) const 181 { 182 return (m_Iterator == it.m_Iterator); 183 } 184 bool operator != (const ConstIterator& it) const 185 { 186 return (m_Iterator != it.m_Iterator); 187 } GetIdentifier()188 TermIdType GetIdentifier() const 189 { 190 return m_Iterator->first; 191 } 192 GetTerm()193 TermType * GetTerm() const 194 { 195 return m_Iterator->second; 196 } 197 private: 198 MapTermContainerConstIteratorType m_Iterator; 199 friend class Iterator; 200 }; 201 202 class Iterator 203 { 204 public: 205 Iterator() = default; Iterator(const MapTermContainerIteratorType & it)206 Iterator( const MapTermContainerIteratorType& it ) : m_Iterator( it ) {} Iterator(const ConstIterator & it)207 Iterator( const ConstIterator& it ) : m_Iterator( it.m_Iterator ) {} 208 ~Iterator() = default; 209 210 Iterator & operator * () { return *this; } 211 Iterator * operator ->() { return this; } 212 213 Iterator & operator++() 214 { 215 ++m_Iterator; 216 return *this; 217 } 218 Iterator operator++(int) 219 { 220 Iterator tmp( *this ); 221 ++(*this); 222 return tmp; 223 } 224 Iterator & operator--() 225 { 226 --m_Iterator; 227 return *this; 228 } 229 Iterator operator--(int) 230 { 231 Iterator tmp( *this ); 232 --(*this); 233 return tmp; 234 } 235 236 bool operator==(const Iterator& it) const 237 { 238 return (m_Iterator==it.m_Iterator); 239 } 240 bool operator!=(const Iterator& it) const 241 { 242 return (m_Iterator!=it.m_Iterator); 243 } 244 bool operator==(const ConstIterator& it)const 245 { 246 return (m_Iterator == it.m_Iterator); 247 } 248 bool operator!=(const ConstIterator& it)const 249 { 250 return (m_Iterator != it.m_Iterator); 251 } GetIdentifier()252 TermIdType GetIdentifier() const 253 { 254 return m_Iterator->first; 255 } 256 GetTerm()257 TermType * GetTerm() const 258 { 259 return m_Iterator->second; 260 } 261 private: 262 MapTermContainerIteratorType m_Iterator; 263 friend class ConstIterator; 264 }; 265 266 Iterator Begin(); 267 Iterator End(); 268 269 ConstIterator Begin() const; 270 ConstIterator End() const; 271 272 protected: 273 LevelSetEquationTermContainer(); 274 275 ~LevelSetEquationTermContainer() override = default; 276 277 LevelSetIdentifierType m_CurrentLevelSetId; 278 LevelSetContainerPointer m_LevelSetContainer; 279 280 InputImagePointer m_Input; 281 282 using HashMapStringTermContainerType = std::unordered_map< std::string, TermPointer >; 283 284 HashMapStringTermContainerType m_NameContainer; 285 286 using RequiredDataType = typename TermType::RequiredDataType; 287 RequiredDataType m_RequiredData; 288 289 MapTermContainerType m_Container; 290 291 using MapCFLContainerType = std::map< TermIdType, LevelSetOutputRealType >; 292 using MapCFLContainerIterator = typename MapCFLContainerType::iterator; 293 using MapCFLContainerConstIterator = typename MapCFLContainerType::const_iterator; 294 295 MapCFLContainerType m_TermContribution; 296 }; 297 298 } 299 #ifndef ITK_MANUAL_INSTANTIATION 300 #include "itkLevelSetEquationTermContainer.hxx" 301 #endif 302 303 #endif // itkLevelSetEquationTermContainer_h 304