ITK
4.1.0
Insight Segmentation and Registration Toolkit
|
00001 /*========================================================================= 00002 * 00003 * Copyright Insight Software Consortium 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0.txt 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 *=========================================================================*/ 00018 #ifndef __itkMorphologyHistogram_h 00019 #define __itkMorphologyHistogram_h 00020 00021 #include <map> 00022 #include <vector> 00023 #include "itkIntTypes.h" 00024 #include "itkNumericTraits.h" 00025 00026 namespace itk 00027 { 00028 namespace Function 00029 { 00030 template< class TInputPixel, class TCompare > 00031 class MorphologyHistogram 00032 { 00033 public: 00034 00035 typedef typename std::map< TInputPixel, IdentifierType, TCompare > MapType; 00036 00037 MorphologyHistogram(){} 00038 00039 inline void AddBoundary() 00040 { 00041 m_Map[m_Boundary]++; 00042 } 00043 00044 inline void RemoveBoundary() 00045 { 00046 m_Map[m_Boundary]--; 00047 } 00048 00049 inline void AddPixel(const TInputPixel & p) 00050 { 00051 m_Map[p]++; 00052 } 00053 00054 inline void RemovePixel(const TInputPixel & p) 00055 { 00056 m_Map[p]--; 00057 } 00058 00059 inline TInputPixel GetValue() 00060 { 00061 itkAssertInDebugAndIgnoreInReleaseMacro(!m_Map.empty()); 00062 // clean the map 00063 typename MapType::iterator mapIt = m_Map.begin(); 00064 while ( mapIt != m_Map.end() ) 00065 { 00066 if ( mapIt->second == 0 ) 00067 { 00068 // this value must be removed from the histogram 00069 // The value must be stored and the iterator updated before removing the 00070 // value 00071 // or the iterator is invalidated. 00072 TInputPixel toErase = mapIt->first; 00073 mapIt++; 00074 m_Map.erase(toErase); 00075 } 00076 else 00077 { 00078 mapIt++; 00079 // don't remove all the zero value found, just remove the one before the 00080 // current maximum value 00081 // the histogram may become quite big on real type image, but it's an 00082 // important increase of performances 00083 break; 00084 } 00085 } 00086 00087 // and return the value 00088 itkAssertInDebugAndIgnoreInReleaseMacro(!m_Map.empty()); 00089 return m_Map.begin()->first; 00090 } 00091 00092 inline TInputPixel GetValue(const TInputPixel &) 00093 { 00094 return GetValue(); 00095 } 00096 00097 void SetBoundary(const TInputPixel & val) 00098 { 00099 m_Boundary = val; 00100 } 00101 00102 static bool UseVectorBasedAlgorithm() 00103 { 00104 return false; 00105 } 00106 00107 MapType m_Map; 00108 TInputPixel m_Boundary; 00109 00110 }; 00111 00112 template< class TInputPixel, class TCompare > 00113 class VectorMorphologyHistogram 00114 { 00115 public: 00116 00117 VectorMorphologyHistogram() 00118 { 00119 // initialize members need for the vector based algorithm 00120 m_Vector.resize(NumericTraits< TInputPixel >::max() - NumericTraits< TInputPixel >::NonpositiveMin() + 1 , 0); 00121 if ( m_Compare( NumericTraits< TInputPixel >::max(), NumericTraits< TInputPixel >::NonpositiveMin() ) ) 00122 { 00123 m_InitValue = NumericTraits< TInputPixel >::NonpositiveMin(); 00124 m_CurrentValue = m_InitValue; 00125 m_Direction = -1; 00126 } 00127 else 00128 { 00129 m_InitValue = NumericTraits< TInputPixel >::max(); 00130 m_CurrentValue = m_InitValue; 00131 m_Direction = 1; 00132 } 00133 m_Boundary = 0; 00134 } 00135 00136 inline void AddBoundary() 00137 { 00138 AddPixel(m_Boundary); 00139 } 00140 00141 inline void RemoveBoundary() 00142 { 00143 RemovePixel(m_Boundary); 00144 } 00145 00146 inline void AddPixel(const TInputPixel & p) 00147 { 00148 m_Vector[p - NumericTraits < TInputPixel > ::NonpositiveMin()]++; 00149 if ( m_Compare(p, m_CurrentValue) ) 00150 { 00151 m_CurrentValue = p; 00152 } 00153 } 00154 00155 inline void RemovePixel(const TInputPixel & p) 00156 { 00157 m_Vector[p - NumericTraits < TInputPixel > ::NonpositiveMin()]--; 00158 while ( m_Vector[m_CurrentValue - NumericTraits < TInputPixel > ::NonpositiveMin()] == 0 00159 && m_CurrentValue != m_InitValue ) 00160 { 00161 m_CurrentValue += m_Direction; 00162 } 00163 } 00164 00165 inline TInputPixel GetValue() 00166 { 00167 return m_CurrentValue; 00168 } 00169 00170 inline TInputPixel GetValue(const TInputPixel &) 00171 { 00172 return GetValue(); 00173 } 00174 00175 void SetBoundary(const TInputPixel & val) 00176 { 00177 m_Boundary = val; 00178 } 00179 00180 static bool UseVectorBasedAlgorithm() 00181 { 00182 return true; 00183 } 00184 00185 std::vector< IdentifierType > m_Vector; 00186 TInputPixel m_InitValue; 00187 TInputPixel m_CurrentValue; 00188 TCompare m_Compare; 00189 signed int m_Direction; 00190 TInputPixel m_Boundary; 00191 }; 00192 00195 // now create MorphologyHistogram partial specilizations using the VectorMorphologyHistogram 00196 // as base class 00197 00198 template< class TCompare > 00199 class MorphologyHistogram<unsigned char, TCompare>: 00200 public VectorMorphologyHistogram<unsigned char, TCompare> 00201 { 00202 }; 00203 00204 template< class TCompare > 00205 class MorphologyHistogram<signed char, TCompare>: 00206 public VectorMorphologyHistogram<signed char, TCompare> 00207 { 00208 }; 00209 00210 template< class TCompare > 00211 class MorphologyHistogram<bool, TCompare>: 00212 public VectorMorphologyHistogram<bool, TCompare> 00213 { 00214 }; 00215 00218 } // end namespace Function 00219 } // end namespace itk 00220 00221 #endif 00222