ITK  4.1.0
Insight Segmentation and Registration Toolkit
itkHistogram.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 __itkHistogram_h
00019 #define __itkHistogram_h
00020 
00021 #include <vector>
00022 
00023 #include "itkArray.h"
00024 #include "itkSample.h"
00025 #include "itkDenseFrequencyContainer2.h"
00026 #include "itkSparseFrequencyContainer2.h"
00027 
00028 namespace itk
00029 {
00030 namespace Statistics
00031 {
00038 template< typename THistogram >
00039 struct GetHistogramDimension {
00040   itkStaticConstMacro(HistogramDimension, unsigned int, THistogram::MeasurementVectorSize);
00041 };
00042 
00085 template< class TMeasurement = float,
00086           class TFrequencyContainer = DenseFrequencyContainer2 >
00087 class ITK_EXPORT Histogram:
00088   public Sample< Array< TMeasurement > >
00089 {
00090 public:
00091 
00092   // This type serves as the indirect definition of MeasurementVectorType
00093   typedef Array< TMeasurement > ArrayType;
00094 
00096   typedef Histogram                  Self;
00097   typedef Sample< ArrayType  >       Superclass;
00098   typedef SmartPointer< Self >       Pointer;
00099   typedef SmartPointer< const Self > ConstPointer;
00100 
00102   itkTypeMacro(Histogram, Sample);
00103 
00105   itkNewMacro(Self);
00106 
00108   typedef TMeasurement MeasurementType;
00109 
00111   typedef typename Superclass::MeasurementVectorType      MeasurementVectorType;
00112   typedef typename Superclass::InstanceIdentifier         InstanceIdentifier;
00113   typedef typename Superclass::MeasurementVectorSizeType  MeasurementVectorSizeType;
00114 
00115   typedef MeasurementVectorType ValueType;
00116 
00118   typedef TFrequencyContainer                      FrequencyContainerType;
00119   typedef typename FrequencyContainerType::Pointer FrequencyContainerPointer;
00120 
00122   typedef typename FrequencyContainerType::AbsoluteFrequencyType      AbsoluteFrequencyType;
00123   typedef typename FrequencyContainerType::TotalAbsoluteFrequencyType TotalAbsoluteFrequencyType;
00124   typedef typename FrequencyContainerType::RelativeFrequencyType      RelativeFrequencyType;
00125   typedef typename FrequencyContainerType::TotalRelativeFrequencyType TotalRelativeFrequencyType;
00126 
00128   typedef Array< ::itk::IndexValueType > IndexType;
00129   typedef typename IndexType::ValueType  IndexValueType;
00130 
00132   typedef Array< ::itk::SizeValueType > SizeType;
00133   typedef typename SizeType::ValueType  SizeValueType;
00134 
00136   typedef std::vector< MeasurementType >  BinMinVectorType;
00137   typedef std::vector< MeasurementType >  BinMaxVectorType;
00138   typedef std::vector< BinMinVectorType > BinMinContainerType;
00139   typedef std::vector< BinMaxVectorType > BinMaxContainerType;
00140 
00144   void Initialize(const SizeType & size);
00145 
00149   void Initialize(const SizeType & size, MeasurementVectorType & lowerBound,
00150                   MeasurementVectorType & upperBound);
00151 
00153   void SetToZero();
00154 
00158   const IndexType & GetIndex(const MeasurementVectorType & measurement) const;
00159 
00163   bool GetIndex(const MeasurementVectorType & measurement,
00164                 IndexType & index) const;
00165 
00169   const IndexType & GetIndex(InstanceIdentifier id) const;
00170 
00173   itkGetConstMacro(ClipBinsAtEnds, bool);
00174 
00177   itkSetMacro(ClipBinsAtEnds, bool);
00178 
00181   bool IsIndexOutOfBounds(const IndexType & index) const;
00182 
00186   InstanceIdentifier GetInstanceIdentifier(const IndexType & index) const;
00187 
00189   InstanceIdentifier Size() const;
00190 
00192   const SizeType & GetSize() const;
00193 
00195   SizeValueType GetSize(unsigned int dimension) const;
00196 
00198   const MeasurementType & GetBinMin(unsigned int dimension,
00199                                     InstanceIdentifier nbin) const;
00200 
00202   const MeasurementType & GetBinMax(unsigned int dimension,
00203                                     InstanceIdentifier nbin) const;
00204 
00206   void SetBinMin(unsigned int dimension, InstanceIdentifier nbin,
00207                  MeasurementType min);
00208 
00210   void SetBinMax(unsigned int dimension,
00211                  InstanceIdentifier nbin, MeasurementType max);
00212 
00215   const MeasurementType & GetBinMinFromValue(unsigned int dimension,
00216                                              float value) const;
00217 
00220   const MeasurementType & GetBinMaxFromValue(unsigned int dimension,
00221                                              float value) const;
00222 
00224   const BinMinVectorType & GetDimensionMins(unsigned int dimension) const;
00225 
00227   const BinMaxVectorType & GetDimensionMaxs(unsigned int dimension) const;
00228 
00230   const BinMinContainerType & GetMins() const;
00231 
00233   const BinMaxContainerType & GetMaxs() const;
00234 
00236   const MeasurementVectorType & GetHistogramMinFromIndex(const IndexType & index) const;
00237 
00239   const MeasurementVectorType & GetHistogramMaxFromIndex(const IndexType & index) const;
00240 
00242   AbsoluteFrequencyType GetFrequency(InstanceIdentifier id) const;
00243 
00245   AbsoluteFrequencyType GetFrequency(const IndexType & index) const;
00246 
00248   void SetFrequency(AbsoluteFrequencyType value);
00249 
00252   bool SetFrequency(InstanceIdentifier id, AbsoluteFrequencyType value);
00253 
00256   bool SetFrequencyOfIndex(const IndexType & index,
00257                     AbsoluteFrequencyType value);
00258 
00261   bool SetFrequencyOfMeasurement(const MeasurementVectorType & measurement,
00262                                   AbsoluteFrequencyType value);
00263 
00267   bool IncreaseFrequency(InstanceIdentifier id, AbsoluteFrequencyType value);
00268 
00272   bool IncreaseFrequencyOfIndex(const IndexType & index,
00273                                  AbsoluteFrequencyType value);
00274 
00278   bool IncreaseFrequencyOfMeasurement(
00279          const MeasurementVectorType & measurement,
00280          AbsoluteFrequencyType value);
00281 #ifdef ITKV3_COMPATIBILITY
00282   //In ITKv4 the member functions are given unique names to dis-ambiguate
00283   //the intended behavior.  Make aliases of the overloaded calls
00284   //for ITKv3 backwards compatibility.
00285   bool IncreaseFrequency(const IndexType & index,
00286                                  AbsoluteFrequencyType value)
00287     {
00288     return IncreaseFrequencyOfIndex(index,value);
00289     }
00291 
00292   bool IncreaseFrequency(
00293          const MeasurementVectorType & measurement,
00294          AbsoluteFrequencyType value)
00295     {
00296     return IncreaseFrequencyOfMeasurement(measurement,value);
00297     }
00298 
00299 #endif
00300 
00304   const MeasurementVectorType & GetMeasurementVector(InstanceIdentifier id) const;
00305 
00307   const MeasurementVectorType & GetMeasurementVector(const IndexType & index) const;
00308 
00311   MeasurementType GetMeasurement(InstanceIdentifier n,
00312                                  unsigned int dimension) const;
00313 
00315   TotalAbsoluteFrequencyType GetTotalFrequency() const;
00316 
00318   AbsoluteFrequencyType GetFrequency(InstanceIdentifier n,
00319                                      unsigned int dimension) const;
00320 
00336   double Quantile(unsigned int dimension, double p) const;
00338 
00340   double Mean(unsigned int dimension) const;
00341 
00343   virtual void Graft(const DataObject *);
00344 
00345 protected:
00346   void PrintSelf(std::ostream & os, Indent indent) const;
00347 
00348 public:
00349 
00354   class ConstIterator
00355   {
00356 public:
00357 
00358     friend class Histogram;
00359 
00360     ConstIterator(const Self *histogram)
00361     {
00362       m_Id = 0;
00363       m_Histogram = histogram;
00364     }
00365 
00366     ConstIterator(const ConstIterator & it)
00367     {
00368       m_Id        = it.m_Id;
00369       m_Histogram = it.m_Histogram;
00370     }
00371 
00372     ConstIterator & operator=(const ConstIterator & it)
00373     {
00374       m_Id  = it.m_Id;
00375       m_Histogram = it.m_Histogram;
00376       return *this;
00377     }
00378 
00379     AbsoluteFrequencyType GetFrequency() const
00380     {
00381       return m_Histogram->GetFrequency(m_Id);
00382     }
00383 
00384     InstanceIdentifier GetInstanceIdentifier() const
00385     {
00386       return m_Id;
00387     }
00388 
00389     const MeasurementVectorType & GetMeasurementVector() const
00390     {
00391       return m_Histogram->GetMeasurementVector(m_Id);
00392     }
00393 
00394     const IndexType & GetIndex() const
00395     {
00396       return m_Histogram->GetIndex(m_Id);
00397     }
00398 
00399     ConstIterator & operator++()
00400     {
00401       ++m_Id;
00402       return *this;
00403     }
00404 
00405     bool operator!=(const ConstIterator & it)
00406     {
00407       return ( m_Id != it.m_Id );
00408     }
00409 
00410     bool operator==(const ConstIterator & it)
00411     {
00412       return ( m_Id == it.m_Id );
00413     }
00414 
00415 protected:
00416     // This method is purposely not implemented
00417     ConstIterator();
00418 
00419     ConstIterator(InstanceIdentifier id, const Self *histogram):
00420       m_Id(id), m_Histogram(histogram)
00421     {}
00422 
00423     // ConstIterator pointing DenseFrequencyContainer
00424     InstanceIdentifier m_Id;
00425 
00426     // Pointer of DenseFrequencyContainer
00427     const Self *m_Histogram;
00428   };   // end of iterator class
00429 
00434   class Iterator:public ConstIterator
00435   {
00436 public:
00437 
00438     Iterator(Self *histogram):ConstIterator(histogram)
00439     {}
00440 
00441     Iterator(InstanceIdentifier id, Self *histogram):
00442       ConstIterator(id, histogram)
00443     {}
00444 
00445     Iterator(const Iterator & it):ConstIterator(it)
00446     {}
00447 
00448     Iterator & operator=(const Iterator & it)
00449     {
00450       this->ConstIterator::operator=(it);
00451       return *this;
00452     }
00453 
00454     bool SetFrequency(const AbsoluteFrequencyType value)
00455     {
00456       Self *histogram = const_cast< Self * >( this->m_Histogram );
00457 
00458       return histogram->SetFrequency(this->m_Id, value);
00459     }
00460 
00461 protected:
00462     // To ensure const-correctness these method must not be in the public API.
00463     // The are purposly not implemented, since they should never be called.
00464     Iterator();
00465     Iterator(const Self *histogram);
00466     Iterator(InstanceIdentifier id, const Self *histogram);
00467     Iterator(const ConstIterator & it);
00468     ConstIterator & operator=(const ConstIterator & it);
00469 
00470 private:
00471   };   // end of iterator class
00472 
00473   Iterator  Begin()
00474   {
00475     Iterator iter(0, this);
00476 
00477     return iter;
00478   }
00479 
00480   Iterator  End()
00481   {
00482     return Iterator(m_OffsetTable[this->GetMeasurementVectorSize()], this);
00483   }
00484 
00485   ConstIterator  Begin() const
00486   {
00487     ConstIterator iter(0, this);
00488 
00489     return iter;
00490   }
00491 
00492   ConstIterator End() const
00493   {
00494     return ConstIterator(m_OffsetTable[this->GetMeasurementVectorSize()], this);
00495   }
00496 
00497 protected:
00498   Histogram();
00499   virtual ~Histogram() {}
00500 
00501   // The number of bins for each dimension
00502   SizeType m_Size;
00503 private:
00504   Histogram(const Self &);      //purposely not implemented
00505   void operator=(const Self &); //purposely not implemented
00506 
00507   typedef std::vector< InstanceIdentifier > OffsetTableType;
00508   OffsetTableType           m_OffsetTable;
00509   FrequencyContainerPointer m_FrequencyContainer;
00510   unsigned int              m_NumberOfInstances;
00511 
00512   // This method is provided here just to avoid a "hidden" warning
00513   // related to the virtual method available in DataObject.
00514   virtual void Initialize() {}
00515 
00516   // lower bound of each bin
00517   std::vector< std::vector< MeasurementType > > m_Min;
00518 
00519   // upper bound of each bin
00520   std::vector< std::vector< MeasurementType > > m_Max;
00521 
00522   mutable MeasurementVectorType m_TempMeasurementVector;
00523   mutable IndexType             m_TempIndex;
00524 
00525   bool m_ClipBinsAtEnds;
00526 };
00527 } // end of namespace Statistics
00528 } // end of namespace itk
00529 
00530 #ifndef ITK_MANUAL_INSTANTIATION
00531 #include "itkHistogram.hxx"
00532 #endif
00533 
00534 #endif
00535