ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkLabelStatisticsImageFilter.h
Go to the documentation of this file.
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 __itkLabelStatisticsImageFilter_h
00019 #define __itkLabelStatisticsImageFilter_h
00020 
00021 #include "itkImageToImageFilter.h"
00022 #include "itkNumericTraits.h"
00023 #include "itkSimpleDataObjectDecorator.h"
00024 #include "itksys/hash_map.hxx"
00025 #include "itkHistogram.h"
00026 #include "itkFastMutexLock.h"
00027 #include <vector>
00028 
00029 namespace itk
00030 {
00059 template< class TInputImage, class TLabelImage >
00060 class ITK_EXPORT LabelStatisticsImageFilter:
00061   public ImageToImageFilter< TInputImage, TInputImage >
00062 {
00063 public:
00065   typedef LabelStatisticsImageFilter                     Self;
00066   typedef ImageToImageFilter< TInputImage, TInputImage > Superclass;
00067   typedef SmartPointer< Self >                           Pointer;
00068   typedef SmartPointer< const Self >                     ConstPointer;
00069 
00071   itkNewMacro(Self);
00072 
00074   itkTypeMacro(LabelStatisticsImageFilter, ImageToImageFilter);
00075 
00077   typedef typename TInputImage::Pointer    InputImagePointer;
00078   typedef typename TInputImage::RegionType RegionType;
00079   typedef typename TInputImage::SizeType   SizeType;
00080   typedef typename TInputImage::IndexType  IndexType;
00081   typedef typename TInputImage::PixelType  PixelType;
00082 
00084   typedef TLabelImage                      LabelImageType;
00085   typedef typename TLabelImage::Pointer    LabelImagePointer;
00086   typedef typename TLabelImage::RegionType LabelRegionType;
00087   typedef typename TLabelImage::SizeType   LabelSizeType;
00088   typedef typename TLabelImage::IndexType  LabelIndexType;
00089   typedef typename TLabelImage::PixelType  LabelPixelType;
00090 
00092   itkStaticConstMacro(ImageDimension, unsigned int,
00093                       TInputImage::ImageDimension);
00094 
00096   typedef typename NumericTraits< PixelType >::RealType RealType;
00097 
00099   typedef typename DataObject::Pointer DataObjectPointer;
00100 
00102   typedef SimpleDataObjectDecorator< RealType > RealObjectType;
00103 
00105   typedef std::vector< IndexValueType > BoundingBoxType;
00106 
00108   typedef itk::Statistics::Histogram< RealType > HistogramType;
00109   typedef typename HistogramType::Pointer        HistogramPointer;
00110 
00115   class LabelStatistics
00116   {
00117 public:
00118 
00119     // default constructor
00120     LabelStatistics()
00121     {
00122       // initialized to the default values
00123       m_Count = NumericTraits< IdentifierType >::Zero;
00124       m_Sum = NumericTraits< RealType >::Zero;
00125       m_SumOfSquares = NumericTraits< RealType >::Zero;
00126 
00127       // Set such that the first pixel encountered can be compared
00128       m_Minimum = NumericTraits< RealType >::max();
00129       m_Maximum = NumericTraits< RealType >::NonpositiveMin();
00130 
00131       // Default these to zero
00132       m_Mean = NumericTraits< RealType >::Zero;
00133       m_Sigma = NumericTraits< RealType >::Zero;
00134       m_Variance = NumericTraits< RealType >::Zero;
00135 
00136       unsigned int imageDimension = itkGetStaticConstMacro(ImageDimension);
00137       m_BoundingBox.resize(imageDimension * 2);
00138       for ( unsigned int i = 0; i < imageDimension * 2; i += 2 )
00139         {
00140         m_BoundingBox[i] = NumericTraits< IndexValueType >::max();
00141         m_BoundingBox[i + 1] = NumericTraits< IndexValueType >::NonpositiveMin();
00142         }
00143       m_Histogram = 0;
00144     }
00145 
00146     // constructor with histogram enabled
00147     LabelStatistics(int size, RealType lowerBound, RealType upperBound)
00148     {
00149       // initialized to the default values
00150       m_Count = NumericTraits< IdentifierType >::Zero;
00151       m_Sum = NumericTraits< RealType >::Zero;
00152       m_SumOfSquares = NumericTraits< RealType >::Zero;
00153 
00154       // Set such that the first pixel encountered can be compared
00155       m_Minimum = NumericTraits< RealType >::max();
00156       m_Maximum = NumericTraits< RealType >::NonpositiveMin();
00157 
00158       // Default these to zero
00159       m_Mean = NumericTraits< RealType >::Zero;
00160       m_Sigma = NumericTraits< RealType >::Zero;
00161       m_Variance = NumericTraits< RealType >::Zero;
00162 
00163       unsigned int imageDimension = itkGetStaticConstMacro(ImageDimension);
00164       m_BoundingBox.resize(imageDimension * 2);
00165       for ( unsigned int i = 0; i < imageDimension * 2; i += 2 )
00166         {
00167         m_BoundingBox[i] = NumericTraits< IndexValueType >::max();
00168         m_BoundingBox[i + 1] = NumericTraits< IndexValueType >::NonpositiveMin();
00169         }
00170 
00171       // Histogram
00172       m_Histogram = HistogramType::New();
00173       typename HistogramType::SizeType hsize;
00174       typename HistogramType::MeasurementVectorType lb;
00175       typename HistogramType::MeasurementVectorType ub;
00176       hsize.SetSize(1);
00177       lb.SetSize(1);
00178       ub.SetSize(1);
00179       m_Histogram->SetMeasurementVectorSize(1);
00180       hsize[0] = size;
00181       lb[0] = lowerBound;
00182       ub[0] = upperBound;
00183       m_Histogram->Initialize(hsize, lb, ub);
00184     }
00185 
00186     // need copy constructor because of smart pointer to histogram
00187     LabelStatistics(const LabelStatistics & l)
00188     {
00189       m_Count = l.m_Count;
00190       m_Minimum = l.m_Minimum;
00191       m_Maximum = l.m_Maximum;
00192       m_Mean = l.m_Mean;
00193       m_Sum = l.m_Sum;
00194       m_SumOfSquares = l.m_SumOfSquares;
00195       m_Sigma = l.m_Sigma;
00196       m_Variance = l.m_Variance;
00197       m_BoundingBox = l.m_BoundingBox;
00198       m_Histogram = l.m_Histogram;
00199     }
00200 
00201     // added for completeness
00202     void operator= (const LabelStatistics& l)
00203     {
00204       m_Count = l.m_Count;
00205       m_Minimum = l.m_Minimum;
00206       m_Maximum = l.m_Maximum;
00207       m_Mean = l.m_Mean;
00208       m_Sum = l.m_Sum;
00209       m_SumOfSquares = l.m_SumOfSquares;
00210       m_Sigma = l.m_Sigma;
00211       m_Variance = l.m_Variance;
00212       m_BoundingBox = l.m_BoundingBox;
00213       m_Histogram = l.m_Histogram;
00214     }
00215 
00216     IdentifierType  m_Count;
00217     RealType        m_Minimum;
00218     RealType        m_Maximum;
00219     RealType        m_Mean;
00220     RealType        m_Sum;
00221     RealType        m_SumOfSquares;
00222     RealType        m_Sigma;
00223     RealType        m_Variance;
00224     BoundingBoxType m_BoundingBox;
00225     typename HistogramType::Pointer m_Histogram;
00226   };
00227 
00229   typedef itksys::hash_map< LabelPixelType, LabelStatistics >                          MapType;
00230   typedef typename itksys::hash_map< LabelPixelType, LabelStatistics >::iterator       MapIterator;
00231   typedef typename itksys::hash_map< LabelPixelType, LabelStatistics >::const_iterator MapConstIterator;
00232   typedef IdentifierType                                                               MapSizeType;
00233 
00235   typedef std::vector<LabelPixelType> ValidLabelValuesContainerType;
00236 
00237   // macros for Histogram enables
00238   itkSetMacro(UseHistograms, bool);
00239   itkGetConstMacro(UseHistograms, bool);
00240   itkBooleanMacro(UseHistograms);
00241 
00242 
00243   virtual const ValidLabelValuesContainerType &GetValidLabelValues() const
00244   {
00245     return m_ValidLabelValues;
00246   }
00247 
00249   void SetLabelInput(const TLabelImage *input)
00250   {
00251     // Process object is not const-correct so the const casting is required.
00252     this->SetNthInput( 1, const_cast< TLabelImage * >( input ) );
00253   }
00254 
00256   const LabelImageType * GetLabelInput() const
00257   {
00258     return static_cast< LabelImageType * >( const_cast< DataObject * >( this->ProcessObject::GetInput(1) ) );
00259   }
00260 
00263   bool HasLabel(LabelPixelType label) const
00264   {
00265     return m_LabelStatistics.find(label) != m_LabelStatistics.end();
00266   }
00267 
00269   MapSizeType GetNumberOfObjects() const
00270   {
00271     return m_LabelStatistics.size();
00272   }
00273 
00274   MapSizeType GetNumberOfLabels() const
00275   {
00276     return this->GetNumberOfObjects();
00277   }
00278 
00280   RealType GetMinimum(LabelPixelType label) const;
00281 
00283   RealType GetMaximum(LabelPixelType label) const;
00284 
00286   RealType GetMean(LabelPixelType label) const;
00287 
00290   RealType GetMedian(LabelPixelType label) const;
00291 
00293   RealType GetSigma(LabelPixelType label) const;
00294 
00296   RealType GetVariance(LabelPixelType label) const;
00297 
00299   BoundingBoxType GetBoundingBox(LabelPixelType label) const;
00300 
00302   RegionType GetRegion(LabelPixelType label) const;
00303 
00305   RealType GetSum(LabelPixelType label) const;
00306 
00308   MapSizeType GetCount(LabelPixelType label) const;
00309 
00311   HistogramPointer GetHistogram(LabelPixelType label) const;
00312 
00314   void SetHistogramParameters(const int numBins, RealType lowerBound,
00315                               RealType upperBound);
00316 
00317 #ifdef ITK_USE_CONCEPT_CHECKING
00318 
00319   itkConceptMacro( InputHasNumericTraitsCheck,
00320                    ( Concept::HasNumericTraits< PixelType > ) );
00321 
00323 #endif
00324 protected:
00325   LabelStatisticsImageFilter();
00326   ~LabelStatisticsImageFilter(){}
00327   void PrintSelf(std::ostream & os, Indent indent) const;
00329 
00332   void AllocateOutputs();
00333 
00335   void BeforeThreadedGenerateData();
00336 
00339   void AfterThreadedGenerateData();
00340 
00342   void  ThreadedGenerateData(const RegionType &
00343                              outputRegionForThread,
00344                              ThreadIdType threadId);
00345 
00346   // Override since the filter needs all the data for the algorithm
00347   void GenerateInputRequestedRegion();
00348 
00349   // Override since the filter produces all of its output
00350   void EnlargeOutputRequestedRegion(DataObject *data);
00351 
00352 private:
00353   LabelStatisticsImageFilter(const Self &); //purposely not implemented
00354   void operator=(const Self &);             //purposely not implemented
00355 
00356   std::vector< MapType >        m_LabelStatisticsPerThread;
00357   MapType                       m_LabelStatistics;
00358   ValidLabelValuesContainerType m_ValidLabelValues;
00359 
00360   bool m_UseHistograms;
00361 
00362   typename HistogramType::SizeType m_NumBins;
00363 
00364   RealType            m_LowerBound;
00365   RealType            m_UpperBound;
00366   SimpleFastMutexLock m_Mutex;
00367 }; // end of class
00368 } // end namespace itk
00369 
00370 #ifndef ITK_MANUAL_INSTANTIATION
00371 #include "itkLabelStatisticsImageFilter.hxx"
00372 #endif
00373 
00374 #endif
00375