[Insight-users] ItkHistogram errors and proposing changes to BinMin/Max

Jisung Kim bahrahm@yahoo.com
Mon, 9 Sep 2002 06:25:17 -0700 (PDT)


HI Martin.

Thank you for bug fixing. I will test you code and
check them in. 

Thank you,

Jisung Kim.

--- Martin Styner <martin_styner@ieee.org> wrote:
> Hi
> My earlier changes are not enough, one also needs to
> adjust some 
> 'interval 'variables used in the code of
> itkHistogram.txx. I have 
> attached the changed files.
> 
> best wishes
> Martin
> 
> Martin Styner wrote:
> > Hi
> > 
> > I found a (minor) error in itkHistogram.txx
> (mispelling of a member at 
> > line 341), here is the diff of that specific
> location:
> > 341c341
> > <     m_TempMeasurmentVector[i] =
> this->GetBinMin(i, index[i]) ;
> > ---
> >  >     m_TempMeasurementVector[i] =
> this->GetBinMin(i, index[i]) ;
> > 
> > 
> > Also, I think that the Min and Max values for the
> Bin's should not be of 
> > type float, but of the same types as the histogram
> values 
> > (Statistics::Histogram<..>::MeasurementType). On
> one hand, this would 
> > eliminate all the conversion froma and to the
> float type, also it  would 
> > make more sense from a design-viewpoint. This
> would create following 
> > changes to itkHistogram.txx and itkHistogram.h
> (again as diffs):
> > 
> > Index: Code/Numerics/Statistics/itkHistogram.h
> > diff -r1.20 itkHistogram.h
> > 176c176
> > <                  const float min)
> > ---
> >  >                  const MeasurementType min)
> > 181c181
> > <                  unsigned long nbin, float max)
> > ---
> >  >                  unsigned long nbin, const
> MeasurementType max)
> > 212c212
> > <                                                 
>  &measurement) const ;
> > ---
> >  >                                                
>   &measurement)  ;
> > 216c216
> > <                                                 
>  &measurement) const;
> > ---
> >  >                                                
>   &measurement) ;
> > 219c219
> > <   MeasurementVectorType&
> GetHistogramMinFromIndex(const IndexType 
> > &index) const ;
> > ---
> >  >   MeasurementVectorType&
> GetHistogramMinFromIndex(const IndexType 
> > &index) ;
> > 222c222
> > <   MeasurementVectorType&
> GetHistogramMaxFromIndex(const IndexType 
> > &index) const ;
> > ---
> >  >   MeasurementVectorType&
> GetHistogramMaxFromIndex(const IndexType 
> > &index) ;
> > 387c387
> > <   std::vector< std::vector<float> > m_Min ;
> > ---
> >  >   std::vector< std::vector<MeasurementType> >
> m_Min ;
> > 390c390
> > <   std::vector< std::vector<float> > m_Max ;
> > ---
> >  >   std::vector< std::vector<MeasurementType> >
> m_Max ;
> > 
> > Index: Code/Numerics/Statistics/itkHistogram.txx
> > diff -r1.14 itkHistogram.txx
> > 308c308
> > < ::GetHistogramMinFromValue(const
> MeasurementVectorType &measurement) 
> > const
> > ---
> >  > ::GetHistogramMinFromValue(const
> MeasurementVectorType &measurement)
> > 322c322
> > < ::GetHistogramMaxFromValue(const
> MeasurementVectorType &measurement) 
> > const
> > ---
> >  > ::GetHistogramMaxFromValue(const
> MeasurementVectorType &measurement)
> > 337c337
> > < ::GetHistogramMinFromIndex(const IndexType
> &index) const
> > ---
> >  > ::GetHistogramMinFromIndex(const IndexType
> &index)
> > 341c341
> > <     m_TempMeasurmentVector[i] =
> this->GetBinMin(i, index[i]) ;
> > ---
> >  >     m_TempMeasurementVector[i] =
> this->GetBinMin(i, index[i]) ;
> > 343c343
> > <   return m_TempMeasurmentVector ;
> > ---
> >  >   return m_TempMeasurementVector ;
> > 351c351
> > < ::GetHistogramMaxFromIndex(const IndexType
> &index) const
> > ---
> >  > ::GetHistogramMaxFromIndex(const IndexType
> &index)
> > 
> > What do others think of the proposed changes
> > best wishes
> > Martin
> > 
> 
> -- 
> Martin Styner, PhD. Ing. ETH
> Group Head Medical Image Analysis for Orthopedics
> M.E. Mueller Institute for Biomechanics
> Center for Computed Assisted Surgery
> University of Bern
> Murtenstrasse 35
> P.O.Box 30
> CH - 3010 Bern
> Switzerland
> Tel office: ++41-31-632-8784 , FAX: ++41-31-632-4951
> email: Martin.Styner@memot.unibe.ch,
> martin_styner@ieee.org
> WWW: http://cranium.unibe.ch/~mstyner
> >
/*=========================================================================
> 
>   Program:   Insight Segmentation & Registration
> Toolkit
>   Module:    $RCSfile: itkHistogram.h,v $
>   Language:  C++
>   Date:      $Date: 2002/09/03 16:59:01 $
>   Version:   $Revision: 1.20 $
> 
>   Copyright (c) 2002 Insight Consortium. All rights
> reserved.
>   See ITKCopyright.txt or
> http://www.itk.org/HTML/Copyright.htm for details.
> 
>      This software is distributed WITHOUT ANY
> WARRANTY; without even 
>      the implied warranty of MERCHANTABILITY or
> FITNESS FOR A PARTICULAR 
>      PURPOSE.  See the above copyright notices for
> more information.
> 
>
=========================================================================*/
> #ifndef __itkHistogram_h
> #define __itkHistogram_h
> 
> #include <vector>
> 
> #include "itkIndex.h"
> #include "itkSize.h"
> #include "itkFixedArray.h"
> #include "itkSample.h"
> #include "itkDenseFrequencyContainer.h"
> #include "itkSparseFrequencyContainer.h"
> 
> namespace itk{
> namespace Statistics{
> 
> /** \class Histogram 
>  *  \brief This class stores measurement vectors in
> the context of n-dimensional
>  *  histogram.
>  *
>  * Users can set arbitrary value for each bins min
> max value for each 
>  * dimension (variable interval). Each dimension of
> the histogram represents
>  * each dimension of measurement vectors. For
> example, an Image with each pixel
>  * having a gray level intensity value and a
> gradient magnitude can be imported
>  * to this class. Then the resulting Histogram has
> two dimensions, intensity
>  * and gradient magnitude.
>  *
>  * Before any operation, users have to call
> Initialize(SizeType) method to
>  * prepare the indexing mechanism and the internal
> frequency container.
>  * After this, users want to set range of each bin
> using 
>  * SetBinMin(dimension, n) and SetBinMax(dimension,
> n) methods.
>  * 
>  * The first two template arguments are same as
> those of 
>  * Sample. The last one, "TFrequencyContainter", is 
>  * the type of the internal frequency container. If
> you think your Histogram
>  * is dense, in other words, almost every bin is
> used, then use default.
>  * If you expect that a very little portion of bins
> will be used, replace it
>  * with SparseFrequencyContainer class
>  * 
>  * Since this class is n-dimensional, it supports
> data access
>  * methods using ITK Index type in addition to the
> methods using 
>  * "InstanceIdentifiers".
>  *
>  * \sa Sample, DenseFrequencyContainer, 
>  * SparseFrequencyContainer
>  */
> 
> template < class TMeasurement = float, unsigned int
> VMeasurementVectorSize = 1,
>   class TFrequencyContainer =
> DenseFrequencyContainer< float > > 
> class ITK_EXPORT Histogram 
>   : public Sample < FixedArray< TMeasurement,
> VMeasurementVectorSize > >
> {
> public:
>   /** Standard typedefs */
>   typedef Histogram  Self ;
>   typedef Sample< FixedArray< TMeasurement,
> VMeasurementVectorSize > > Superclass ;
>   typedef SmartPointer<Self> Pointer ;
> 
>   /** Run-time type information (and related
> methods). */
>   itkTypeMacro(Histogram, Sample) ;
> 
>   /** standard New() method support */
>   itkNewMacro(Self) ;
> 
>   /** Dimension of a measurement vector */
>   enum { MeasurementVectorSize =
> VMeasurementVectorSize } ;
>  
>   /** type of an element of a measurement vector */
>   typedef TMeasurement MeasurementType ;
> 
>   /** Common sample class typedefs */
>   typedef typename Superclass::MeasurementVectorType
> MeasurementVectorType ;
>   typedef typename Superclass::InstanceIdentifier
> InstanceIdentifier ;
>   typedef MeasurementVectorType ValueType ;
> 
>   /** frequency container typedef */
>   typedef TFrequencyContainer FrequencyContainerType
> ;
>   typedef typename FrequencyContainerType::Pointer
> FrequencyContainerPointer ;
> 
>   /** Frequency value type from superclass */
>   typedef typename
> FrequencyContainerType::FrequencyType FrequencyType
> ;
> 
>   /** Index typedef support. An index is used to
> access pixel values. */
>   typedef itk::Index< VMeasurementVectorSize > 
> IndexType;
>   typedef typename IndexType::IndexValueType 
> IndexValueType;
> 
>   /** size array type */
>   typedef itk::Size< VMeasurementVectorSize >
> SizeType ;
>   typedef typename SizeType::SizeValueType
> SizeValueType ;
> 
>   /** bin min max value storage types */
>   typedef std::vector< MeasurementType >
> BinMinVectorType ;
>   typedef std::vector< MeasurementType >
> BinMaxVectorType ;
>   typedef std::vector< BinMinVectorType >
> BinMinContainerType ;
>   typedef std::vector< BinMaxVectorType >
> BinMaxContainerType ;
> 
>   /** generates the offset table.
>    * subclasses should call this method in their
> initialize() method
>    * the overide methods have prepare the frequency
> container for
>    * input and output. */
>   void Initialize(const SizeType &size) ;
>   
> 
>   /** Do the same thing as the above
> Initialize(SizeType) method do
>    * , and also creates equal size bins within the
> range given 
>    * by lower and upper bound. If users want to
> assign bin's min and
>    * max values along each dimension use SetBinMin()
> and SetBinMax()
>    * functions*/
>   void Initialize(const SizeType &size,
> MeasurementVectorType lowerBound,
>                   MeasurementVectorType upperBound)
> ;
> 
>   /** returns the index of histogram corresponding
> to measurement value */
>   IndexType& GetIndex(const MeasurementVectorType
> &measurement) ;
>   
>   /** returns the index that is uniquely labelled by
> an instance identifier
>    * The corresponding id is the offset of the index
> 
>    * This method uses ImageBase::ComputeIndex()
> method */
>   IndexType& GetIndex(const InstanceIdentifier &id)
> ;
> 
>   /** returns true if the given index is out of
> bound meaning one of index
>    * is not between [0, last index] */
>   bool IsIndexOutOfBound(const IndexType &index)
> const;
> 
>   /** returns the instance identifier of the cell
> that is indexed by the 
>    * index. The corresponding instance identifier is
> the offset of the index 
> 
=== message truncated ===>
/*=========================================================================
> 
>   Program:   Insight Segmentation & Registration
> Toolkit
>   Module:    $RCSfile: itkHistogram.txx,v $
>   Language:  C++
>   Date:      $Date: 2002/09/03 16:59:01 $
>   Version:   $Revision: 1.14 $
> 
>   Copyright (c) 2002 Insight Consortium. All rights
> reserved.
>   See ITKCopyright.txt or
> http://www.itk.org/HTML/Copyright.htm for details.
> 
>      This software is distributed WITHOUT ANY
> WARRANTY; without even 
>      the implied warranty of MERCHANTABILITY or
> FITNESS FOR A PARTICULAR 
>      PURPOSE.  See the above copyright notices for
> more information.
> 
>
=========================================================================*/
> #ifndef _itkHistogram_txx
> #define _itkHistogram_txx
> 
> #include "itkHistogram.h"
> #include "itkNumericTraits.h"
> 
> namespace itk{ 
>   namespace Statistics{
> 
> template< class TMeasurement, unsigned int
> VMeasurementVectorSize,
>           class TFrequencyContainer>
> Histogram<TMeasurement, VMeasurementVectorSize,
> TFrequencyContainer>
> ::Histogram()
> {
>   m_FrequencyContainer =
> FrequencyContainerType::New() ;
> }
> 
> template< class TMeasurement, unsigned int
> VMeasurementVectorSize,
>           class TFrequencyContainer>
> unsigned int
> Histogram<TMeasurement, VMeasurementVectorSize,
> TFrequencyContainer>
> ::Size() const
> {
>   unsigned int size = 1 ;
>   for (unsigned int i = 0 ; i <
> MeasurementVectorSize ; i++)
>     {
>       size *= m_Size[i] ;
>     }
>   return size ;
> }
> 
> template< class TMeasurement, unsigned int
> VMeasurementVectorSize,
>           class TFrequencyContainer>
> void
> Histogram<TMeasurement, VMeasurementVectorSize,
> TFrequencyContainer>
> ::Initialize(const SizeType &size)
> {
>   m_Size = size ;
>   
>   // creates offset table which will be used for
> generation of
>   // instance identifiers.
>   InstanceIdentifier num = 1 ;
>   
>   m_OffsetTable[0] = num ;
>   for (unsigned int i = 0 ; i <
> MeasurementVectorSize ; i++)
>     {
>       num *= m_Size[i] ;
>       m_OffsetTable[i + 1] = num ;
>     }
> 
>   m_NumberOfInstances = num ;
> 
>   // adjust the sizes of min max value containers 
>   int dim;
>   m_Min.resize(MeasurementVectorSize);
>   for ( dim = 0; dim < MeasurementVectorSize; dim++)
>     {
>     m_Min[dim].resize(m_Size[dim]);
>     } 
> 
>   m_Max.resize(MeasurementVectorSize);
>   for ( dim = 0; dim < MeasurementVectorSize; dim++)
>     {
>     m_Max[dim].resize(m_Size[dim]);
>     } 
> 
>   // initialize the frequency container
>  
>
m_FrequencyContainer->Initialize(m_OffsetTable[VMeasurementVectorSize])
> ;
>   this->SetFrequency(0.0f) ;
> }
> 
> template< class TMeasurement, unsigned int
> VMeasurementVectorSize,
>           class TFrequencyContainer>
> void 
> Histogram<TMeasurement, VMeasurementVectorSize,
> TFrequencyContainer>
> ::Initialize(const SizeType &size,
> MeasurementVectorType lowerBound,
>              MeasurementVectorType upperBound)
> {
>   this->Initialize(size) ;
> 
>   float interval ;
>   for ( int i = 0 ; i < MeasurementVectorSize ; i++)
>     {
>       interval = (float) (upperBound[i] -
> lowerBound[i]) / 
>         static_cast< MeasurementType >(size[i]) ;
>       // Set the min vector and max vector
>       for (unsigned int j = 0; j < (size[i] - 1) ;
> j++)
>         {
>           this->SetBinMin(i, j, lowerBound[i] + 
> ((float)j * interval)) ;
>           this->SetBinMax(i, j, lowerBound[i] + 
> (((float)j + 1) * interval));
>         }
>       this->SetBinMin(i, size[i] - 1, 
>                            lowerBound[i] + (((float)
> size[i] - 1) * interval)) ;
>       this->SetBinMax(i, size[i] - 1, 
>                            upperBound[i]) ;
>     }
> }
> 
> template< class TMeasurement, unsigned int
> VMeasurementVectorSize, 
>   class TFrequencyContainer>
> inline typename Histogram<TMeasurement,
> VMeasurementVectorSize,
> TFrequencyContainer>::IndexType&
> Histogram<TMeasurement, VMeasurementVectorSize,
> TFrequencyContainer>
> ::GetIndex(const MeasurementVectorType &measurement)
> {
>   // now using somthing similar to binary search to
> find
>   // index.
>   int dim ;
>   
>   int begin, mid, end ;
>   MeasurementType median ;
>   MeasurementType tempMeasurement ;
> 
>   for (dim = 0 ; dim < MeasurementVectorSize ;
> dim++)
>     {
>       tempMeasurement = measurement[dim] ;
>       begin = 0 ;
>       if (tempMeasurement < m_Min[dim][begin])
>         {
>           // one of measurement is below the minimum
>           m_TempIndex[0] = (long) m_Size[0] ;
>           return m_TempIndex ;
>         }
> 
>       end = m_Min[dim].size() - 1 ;
>       if (tempMeasurement >= m_Max[dim][end])
>         {
>           // one of measurement is above the maximum
>           m_TempIndex[0] = (long) m_Size[0] ;
>           return m_TempIndex ;
>         }
> 
>       mid = (end + 1) / 2 ;
>       median = m_Min[dim][mid] ;
>       while(true)
>         {
>           if (tempMeasurement < median )
>             {
>               end = mid - 1 ;
>             } 
>           else if (tempMeasurement > median)
>             {
>               if (tempMeasurement < m_Max[dim][mid])
>                 {
>                   m_TempIndex[dim] = mid ;
>                   break ;
>                 }
>               
>               begin = mid + 1 ;
>             }
>           else
>             {
>               // measurement[dim] = m_Min[dim][med] 
>               m_TempIndex[dim] = mid ;
> 
=== message truncated ===


=====
Jisung Kim
bahrahm@yahoo.com
106 Mason Farm Rd.
129 Radiology Research Lab., CB# 7515
Univ. of North Carolina at Chapel Hill
Chapel Hill, NC 27599-7515

__________________________________________________
Do You Yahoo!?
Yahoo! Finance - Get real-time stock quotes
http://finance.yahoo.com