00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkMovingHistogramMorphologyImageFilter_h
00018 #define __itkMovingHistogramMorphologyImageFilter_h
00019
00020 #include "itkMovingHistogramImageFilter.h"
00021 #include <list>
00022 #include <map>
00023
00024 namespace itk {
00025
00026 namespace Function {
00027 template <class TInputPixel, class TCompare>
00028 class MorphologyHistogram
00029 {
00030 public:
00031 MorphologyHistogram()
00032 {
00033 if( useVectorBasedAlgorithm() )
00034 { initVector(); }
00035 }
00036 ~MorphologyHistogram(){}
00037
00038 MorphologyHistogram * Clone() const
00039 {
00040 MorphologyHistogram * result = new MorphologyHistogram();
00041 result->m_Map = this->m_Map;
00042 result->m_Vector = this->m_Vector;
00043 result->m_CurrentValue = this->m_CurrentValue;
00044 result->m_Compare = this->m_Compare;
00045 result->m_Direction = this->m_Direction;
00046 result->m_Boundary = this->m_Boundary;
00047 return result;
00048 }
00049
00050
00051
00052
00053 inline void AddBoundary()
00054 {
00055 if( useVectorBasedAlgorithm() )
00056 { AddBoundaryVector(); }
00057 else
00058 { AddBoundaryMap(); }
00059 }
00060
00061 inline void RemoveBoundary()
00062 {
00063 if( useVectorBasedAlgorithm() )
00064 { RemoveBoundaryVector(); }
00065 else
00066 { RemoveBoundaryMap(); }
00067 }
00068
00069 inline void AddPixel( const TInputPixel &p )
00070 {
00071 if( useVectorBasedAlgorithm() )
00072 { AddPixelVector( p ); }
00073 else
00074 { AddPixelMap( p ); }
00075 }
00076
00077 inline void RemovePixel( const TInputPixel &p )
00078 {
00079 if( useVectorBasedAlgorithm() )
00080 { RemovePixelVector( p ); }
00081 else
00082 { RemovePixelMap( p ); }
00083 }
00084
00085 inline TInputPixel GetValue( const TInputPixel & )
00086 {
00087 if( useVectorBasedAlgorithm() )
00088 { return GetValueVector(); }
00089 else
00090 { return GetValueMap(); }
00091 }
00092
00093
00094 inline static bool useVectorBasedAlgorithm()
00095 {
00096
00097
00098 return typeid(TInputPixel) == typeid(unsigned char)
00099 || typeid(TInputPixel) == typeid(signed char)
00100 || typeid(TInputPixel) == typeid(unsigned short)
00101 || typeid(TInputPixel) == typeid(signed short)
00102 || typeid(TInputPixel) == typeid(bool);
00103 }
00104
00105
00106
00107
00108
00109
00110 typedef typename std::map< TInputPixel, unsigned long, TCompare > MapType;
00111
00112 inline void AddBoundaryMap()
00113 { m_Map[ m_Boundary ]++; }
00114
00115 inline void RemoveBoundaryMap()
00116 { m_Map[ m_Boundary ]--; }
00117
00118 inline void AddPixelMap( const TInputPixel &p )
00119 { m_Map[ p ]++; }
00120
00121 inline void RemovePixelMap( const TInputPixel &p )
00122 { m_Map[ p ]--; }
00123
00124 inline TInputPixel GetValueMap()
00125 {
00126
00127 typename MapType::iterator mapIt = m_Map.begin();
00128 while( mapIt != m_Map.end() )
00129 {
00130 if( mapIt->second == 0 )
00131 {
00132
00133
00134
00135 TInputPixel toErase = mapIt->first;
00136 mapIt++;
00137 m_Map.erase( toErase );
00138 }
00139 else
00140 {
00141 mapIt++;
00142
00143
00144 break;
00145 }
00146 }
00147
00148
00149 return m_Map.begin()->first;
00150 }
00151
00152 MapType m_Map;
00153
00154
00155
00156
00157
00158
00159 inline void initVector()
00160 {
00161
00162 m_Vector.resize( static_cast<int>( NumericTraits< TInputPixel >::max() - NumericTraits< TInputPixel >::NonpositiveMin() + 1 ), 0 );
00163 if( m_Compare( NumericTraits< TInputPixel >::max(), NumericTraits< TInputPixel >::NonpositiveMin() ) )
00164 {
00165 m_CurrentValue = NumericTraits< TInputPixel >::NonpositiveMin();
00166 m_Direction = -1;
00167 }
00168 else
00169 {
00170 m_CurrentValue = NumericTraits< TInputPixel >::max();
00171 m_Direction = 1;
00172 }
00173 }
00174
00175
00176 inline void AddBoundaryVector()
00177 { AddPixelVector( m_Boundary ); }
00178
00179 inline void RemoveBoundaryVector()
00180 { RemovePixelVector( m_Boundary ); }
00181
00182 inline void AddPixelVector( const TInputPixel &p )
00183 {
00184 m_Vector[ static_cast<int>( p - NumericTraits< TInputPixel >::NonpositiveMin() ) ]++;
00185 if( m_Compare( p, m_CurrentValue ) )
00186 { m_CurrentValue = p; }
00187 }
00188
00189 inline void RemovePixelVector( const TInputPixel &p )
00190 {
00191 m_Vector[ static_cast<int>( p - NumericTraits< TInputPixel >::NonpositiveMin() ) ]--;
00192 while( m_Vector[ static_cast<int>( m_CurrentValue - NumericTraits< TInputPixel >::NonpositiveMin() ) ] == 0 )
00193 { m_CurrentValue += m_Direction; }
00194 }
00195
00196 inline TInputPixel GetValueVector()
00197 { return m_CurrentValue; }
00198
00199 std::vector<unsigned long> m_Vector;
00200 TInputPixel m_CurrentValue;
00201 TCompare m_Compare;
00202 signed int m_Direction;
00203
00204
00205
00206
00207 void SetBoundary( const TInputPixel & val )
00208 { m_Boundary = val; }
00209
00210 TInputPixel m_Boundary;
00211 };
00212 }
00213
00214
00226 template<class TInputImage, class TOutputImage, class TKernel, class THistogram>
00227 class ITK_EXPORT MovingHistogramMorphologyImageFilter :
00228 public MovingHistogramImageFilter<TInputImage, TOutputImage, TKernel, THistogram>
00229 {
00230 public:
00232 typedef MovingHistogramMorphologyImageFilter Self;
00233 typedef MovingHistogramImageFilter<TInputImage, TOutputImage, TKernel, THistogram>
00234 Superclass;
00235 typedef SmartPointer<Self> Pointer;
00236 typedef SmartPointer<const Self> ConstPointer;
00237
00239 itkNewMacro(Self);
00240
00242 itkTypeMacro(MovingHistogramMorphologyImageFilter,
00243 ImageToImageFilter);
00244
00246 typedef TInputImage InputImageType;
00247 typedef TOutputImage OutputImageType;
00248 typedef typename TInputImage::RegionType RegionType;
00249 typedef typename TInputImage::SizeType SizeType;
00250 typedef typename TInputImage::IndexType IndexType;
00251 typedef typename TInputImage::PixelType PixelType;
00252 typedef typename TInputImage::OffsetType OffsetType;
00253 typedef typename Superclass::OutputImageRegionType OutputImageRegionType;
00254 typedef typename TOutputImage::PixelType OutputPixelType;
00255
00257 itkStaticConstMacro(ImageDimension, unsigned int,
00258 TInputImage::ImageDimension);
00259
00261 typedef TKernel KernelType;
00262
00264 typedef typename KernelType::ConstIterator KernelIteratorType;
00265
00267 typedef typename KernelType::SizeType RadiusType;
00268
00269 typedef typename std::list< OffsetType > OffsetListType;
00270
00271 typedef typename std::map< OffsetType, OffsetListType, typename OffsetType::LexicographicCompare > OffsetMapType;
00272
00274 itkSetMacro(Boundary, PixelType);
00275 itkGetMacro(Boundary, PixelType);
00277
00280 static bool GetUseVectorBasedAlgorithm()
00281 { return THistogram::useVectorBasedAlgorithm(); }
00282
00283 protected:
00284 MovingHistogramMorphologyImageFilter();
00285 ~MovingHistogramMorphologyImageFilter() {};
00286 void PrintSelf(std::ostream& os, Indent indent) const;
00287
00289
00290
00291
00292
00294 virtual THistogram * NewHistogram();
00295
00296 PixelType m_Boundary;
00297
00298 private:
00299 MovingHistogramMorphologyImageFilter(const Self&);
00300 void operator=(const Self&);
00301
00302 };
00303
00304 }
00305
00306 #ifndef ITK_MANUAL_INSTANTIATION
00307 #include "itkMovingHistogramMorphologyImageFilter.txx"
00308 #endif
00309
00310 #endif
00311