00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkMovingHistogramMorphologicalGradientImageFilter_h
00018 #define __itkMovingHistogramMorphologicalGradientImageFilter_h
00019
00020 #include "itkMovingHistogramImageFilter.h"
00021 #include <map>
00022
00023 namespace itk {
00024
00025 namespace Function {
00026 template <class TInputPixel>
00027 class MorphologicalGradientHistogram
00028 {
00029 public:
00030 MorphologicalGradientHistogram()
00031 {
00032 if( useVectorBasedAlgorithm() )
00033 { initVector(); }
00034 }
00035 ~MorphologicalGradientHistogram(){}
00036
00037 MorphologicalGradientHistogram * Clone() const
00038 {
00039 MorphologicalGradientHistogram * result = new MorphologicalGradientHistogram();
00040 result->m_Map = this->m_Map;
00041 result->m_Vector = this->m_Vector;
00042 result->m_Min = this->m_Min;
00043 result->m_Max = this->m_Max;
00044 result->m_Count = this->m_Count;
00045 return result;
00046 }
00047
00048 inline void AddBoundary() {}
00049
00050 inline void RemoveBoundary() {}
00051
00052 inline void AddPixel( const TInputPixel &p )
00053 {
00054 if( useVectorBasedAlgorithm() )
00055 { AddPixelVector( p ); }
00056 else
00057 { AddPixelMap( p ); }
00058 }
00059
00060 inline void RemovePixel( const TInputPixel &p )
00061 {
00062 if( useVectorBasedAlgorithm() )
00063 { RemovePixelVector( p ); }
00064 else
00065 { RemovePixelMap( p ); }
00066 }
00067
00068 inline TInputPixel GetValue( const TInputPixel & )
00069 {
00070 if( useVectorBasedAlgorithm() )
00071 { return GetValueVector(); }
00072 else
00073 { return GetValueMap(); }
00074 }
00075
00076
00077 static inline bool useVectorBasedAlgorithm()
00078 {
00079
00080
00081 return typeid(TInputPixel) == typeid(unsigned char)
00082 || typeid(TInputPixel) == typeid(signed char)
00083 || typeid(TInputPixel) == typeid(unsigned short)
00084 || typeid(TInputPixel) == typeid(signed short)
00085 || typeid(TInputPixel) == typeid(bool);
00086 }
00087
00088
00089
00090
00091
00092
00093 typedef std::map< TInputPixel, unsigned long > MapType;
00094
00095 inline void AddPixelMap( const TInputPixel &p )
00096 { m_Map[ p ]++; }
00097
00098 inline void RemovePixelMap( const TInputPixel &p )
00099 { m_Map[ p ]--; }
00100
00101 inline TInputPixel GetValueMap()
00102 {
00103
00104 typename MapType::iterator mapIt = m_Map.begin();
00105 while( mapIt != m_Map.end() )
00106 {
00107 if( mapIt->second == 0 )
00108 {
00109
00110
00111
00112 TInputPixel toErase = mapIt->first;
00113 mapIt++;
00114 m_Map.erase(toErase);
00115 }
00116 else
00117 {
00118 mapIt++;
00119 }
00120 }
00121
00122
00123 if( !m_Map.empty() )
00124 { return m_Map.rbegin()->first - m_Map.begin()->first; }
00125 return 0;
00126 }
00127
00128 MapType m_Map;
00129
00130
00131
00132
00133
00134
00135 inline void initVector()
00136 {
00137
00138 m_Vector.resize( static_cast<int>( NumericTraits< TInputPixel >::max() - NumericTraits< TInputPixel >::NonpositiveMin() + 1 ), 0 );
00139 m_Max = NumericTraits< TInputPixel >::NonpositiveMin();
00140 m_Min = NumericTraits< TInputPixel >::max();
00141 m_Count = 0;
00142 }
00143
00144 inline void AddPixelVector( const TInputPixel &p )
00145 {
00146 m_Vector[ static_cast<int>( p - NumericTraits< TInputPixel >::NonpositiveMin() ) ]++;
00147 if( p > m_Max )
00148 { m_Max = p; }
00149 if( p < m_Min )
00150 { m_Min = p; }
00151 m_Count++;
00152 }
00153
00154 inline void RemovePixelVector( const TInputPixel &p )
00155 {
00156 m_Vector[ static_cast<int>( p - NumericTraits< TInputPixel >::NonpositiveMin() ) ]--;
00157 m_Count--;
00158 if( m_Count > 0 )
00159 {
00160 while( m_Vector[ static_cast<int>( m_Max - NumericTraits< TInputPixel >::NonpositiveMin() ) ] == 0 )
00161 { m_Max--; }
00162 while( m_Vector[ static_cast<int>( m_Min - NumericTraits< TInputPixel >::NonpositiveMin() ) ] == 0 )
00163 { m_Min++; }
00164 }
00165 else
00166 {
00167 m_Max = NumericTraits< TInputPixel >::NonpositiveMin();
00168 m_Min = NumericTraits< TInputPixel >::max();
00169 }
00170 }
00171
00172 inline TInputPixel GetValueVector()
00173 {
00174 if( m_Count > 0 )
00175 { return m_Max - m_Min; }
00176 else
00177 { return NumericTraits< TInputPixel >::Zero; }
00178 }
00179
00180 std::vector<unsigned long> m_Vector;
00181 TInputPixel m_Min;
00182 TInputPixel m_Max;
00183 unsigned long m_Count;
00184
00185
00186 };
00187 }
00188
00204 template<class TInputImage, class TOutputImage, class TKernel>
00205 class ITK_EXPORT MovingHistogramMorphologicalGradientImageFilter :
00206 public MovingHistogramImageFilter<TInputImage, TOutputImage, TKernel,
00207 typename Function::MorphologicalGradientHistogram< typename TInputImage::PixelType > >
00208 {
00209 public:
00211 typedef MovingHistogramMorphologicalGradientImageFilter Self;
00212 typedef MovingHistogramImageFilter<TInputImage, TOutputImage, TKernel,
00213 typename Function::MorphologicalGradientHistogram< typename TInputImage::PixelType > > Superclass;
00214 typedef SmartPointer<Self> Pointer;
00215 typedef SmartPointer<const Self> ConstPointer;
00216
00218 itkNewMacro(Self);
00219
00221 itkTypeMacro(MovingHistogramMorphologicalGradientImageFilter,
00222 ImageToImageFilter);
00223
00225 typedef TInputImage InputImageType;
00226 typedef TOutputImage OutputImageType;
00227 typedef typename TInputImage::RegionType RegionType;
00228 typedef typename TInputImage::SizeType SizeType;
00229 typedef typename TInputImage::IndexType IndexType;
00230 typedef typename TInputImage::PixelType PixelType;
00231 typedef typename TInputImage::OffsetType OffsetType;
00232 typedef typename Superclass::OutputImageRegionType OutputImageRegionType;
00233 typedef typename TOutputImage::PixelType OutputPixelType;
00234
00235 typedef Function::MorphologicalGradientHistogram< PixelType > HistogramType;
00236
00237
00239 itkStaticConstMacro(ImageDimension, unsigned int,
00240 TInputImage::ImageDimension);
00241
00242
00245 static bool GetUseVectorBasedAlgorithm()
00246 { return Function::MorphologicalGradientHistogram< ITK_TYPENAME TInputImage::PixelType >::useVectorBasedAlgorithm(); }
00247
00248 protected:
00249 MovingHistogramMorphologicalGradientImageFilter() {};
00250 ~MovingHistogramMorphologicalGradientImageFilter() {};
00251
00252
00253 private:
00254 MovingHistogramMorphologicalGradientImageFilter(const Self&);
00255 void operator=(const Self&);
00256
00257 };
00258
00259 }
00260
00261 #endif
00262