⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 itkstatisticsalgorithm.txx

📁 DTMK软件开发包,此为开源软件,是一款很好的医学图像开发资源.
💻 TXX
📖 第 1 页 / 共 2 页
字号:
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkStatisticsAlgorithm.txx,v $
  Language:  C++
  Date:      $Date: 2008-04-29 23:00:07 $
  Version:   $Revision: 1.24 $

  Copyright (c) Insight Software 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 __itkStatisticsAlgorithm_txx
#define __itkStatisticsAlgorithm_txx

#include "itkStatisticsAlgorithm.h"
#include "itkNumericTraits.h"

namespace itk{
namespace Statistics{

template< class TSize >
inline TSize FloorLog(TSize size) 
{
  TSize k ;
  
  for (k = 0; size != 1; size >>= 1) 
    {
    ++k;
    }
  
  return k;
}

/** The endIndex should points one point after the last elements if multiple
 * partitionValue exist in the sample the return index will points the middle
 * of such values. Implemented following the description of the partition
 * algorithm in the QuickSelect entry of the Wikipedia.
 * http://en.wikipedia.org/wiki/Selection_algorithm. */
template< class TSubsample >
inline int Partition(TSubsample* sample,
                     unsigned int activeDimension,
                     int beginIndex, int endIndex,
                     const typename TSubsample::MeasurementType partitionValue)
{
  typedef typename TSubsample::MeasurementType MeasurementType;

  int moveToFrontIndex = beginIndex;
  int moveToBackIndex = endIndex-1;

  //
  // Move to the back all entries whose activeDimension component is equal to
  // the partitionValue.
  // 
  while( moveToFrontIndex < moveToBackIndex )
    {
    // 
    //  Find the first element (from the back) that is in the wrong side of the partition.
    //
    while( moveToBackIndex >= beginIndex )
      {
      if( sample->GetMeasurementVectorByIndex(moveToBackIndex)[activeDimension] != partitionValue )
        {
        break;
        }
      moveToBackIndex--;
      }

    // 
    //  Find the first element (from the front) that is in the wrong side of the partition.
    //
    while( moveToFrontIndex < endIndex )
      {
      if( sample->GetMeasurementVectorByIndex(moveToFrontIndex)[activeDimension] == partitionValue )
        {
        break;
        }
      moveToFrontIndex++;
      }

    if( moveToFrontIndex < moveToBackIndex )
      {
      // 
      // Swap them to place them in the correct side of the partition
      //
      sample->Swap( moveToBackIndex, moveToFrontIndex );
      }
    }


  //
  // Now, ignore the section at the end with all the values equal to the partition value,
  // and start swapping entries that are in the wrong side of the partition.
  // 
  moveToFrontIndex = beginIndex;
  moveToBackIndex  = endIndex-1;
  while( moveToFrontIndex < moveToBackIndex )
    {
    // 
    //  Find the first element (from the back) that is in the wrong side of the partition.
    //
    while( moveToBackIndex >= beginIndex )
      {
      if( sample->GetMeasurementVectorByIndex(moveToBackIndex)[activeDimension] < partitionValue )
        {
        break;
        }
      moveToBackIndex--;
      }

    // 
    //  Find the first element (from the front) that is in the wrong side of the partition.
    //
    while( moveToFrontIndex < endIndex )
      {
      if( sample->GetMeasurementVectorByIndex(moveToFrontIndex)[activeDimension] > partitionValue )
        {
        break;
        }
      moveToFrontIndex++;
      }


    if( moveToFrontIndex < moveToBackIndex )
      {
      // 
      // Swap them to place them in the correct side of the partition
      //
      sample->Swap( moveToBackIndex, moveToFrontIndex );
      }
    }


  //
  // Take all the entries with activeDimension component equal to
  // partitionValue, that were placed at the end of the list, and move them to
  // the interface between smaller and larger values.
  //
  int beginOfSectionEqualToPartition = moveToFrontIndex;
  moveToBackIndex = endIndex-1;
  while( moveToFrontIndex < moveToBackIndex )
    {
    // 
    //  Find the first element (from the back) that is in the wrong side of the partition.
    //
    while( moveToBackIndex >= beginIndex )
      {
      if( sample->GetMeasurementVectorByIndex(moveToBackIndex)[activeDimension] == partitionValue )
        {
        break;
        }
      moveToBackIndex--;
      }


    // 
    //  Find the first element (from the front) that is in the wrong side of the partition.
    //
    while( moveToFrontIndex < endIndex )
      {
      if( sample->GetMeasurementVectorByIndex(moveToFrontIndex)[activeDimension] != partitionValue )
        {
        break;
        }
      moveToFrontIndex++;
      }

    if( moveToFrontIndex < moveToBackIndex )
      {
      // 
      // Swap them to place them in the correct side of the partition
      //
      sample->Swap( moveToBackIndex, moveToFrontIndex );
      }
    }
  int endOfSectionEqualToPartition = moveToFrontIndex-1;

  int storeIndex = ( beginOfSectionEqualToPartition + endOfSectionEqualToPartition ) / 2;

  const MeasurementType pivotValue  = sample->GetMeasurementVectorByIndex( storeIndex )[activeDimension];
  if( pivotValue != partitionValue )
    {
    // The partition was done using a value that is not present in the sample.
    // Therefore we must now find the largest value of the left section and
    // swap it to the boundary between smaller and larger than the
    // partitionValue.
    for(int kk=beginIndex; kk<storeIndex; kk++)
      {
      MeasurementType nodeValue      = sample->GetMeasurementVectorByIndex( kk )[activeDimension];
      MeasurementType boundaryValue  = sample->GetMeasurementVectorByIndex( storeIndex )[activeDimension];
      if( nodeValue > boundaryValue )
        {
        sample->Swap(kk, storeIndex) ;
        }
      }

    }

  return storeIndex;
}


template< class TValue >
inline TValue MedianOfThree(const TValue a, 
                            const TValue b, 
                            const TValue c)
{  
  if (a < b) {
  if (b < c) {
  return b;
  }
  else if (a < c) {
  return c;
  }
  else {
  return a;
  }
  }
  else if (a < c) {
  return a ;
  }
  else if (b < c) {
  return c;
  }
  else {
  return b;
  }
}

template< class TSample >
inline void FindSampleBound(const TSample* sample,
                            typename TSample::ConstIterator begin,
                            typename TSample::ConstIterator end,
                            typename TSample::MeasurementVectorType &min,
                            typename TSample::MeasurementVectorType &max)
{    
  typedef typename TSample::MeasurementVectorSizeType MeasurementVectorSizeType;

  const MeasurementVectorSizeType Dimension = sample->GetMeasurementVectorSize();
  if( Dimension == 0 )
    {
    itkGenericExceptionMacro( 
        << "Length of a sample's measurement vector hasn't been set.");
    }
  // Sanity check
  MeasurementVectorTraits::Assert( max, Dimension, 
          "Length mismatch StatisticsAlgorithm::FindSampleBound");
  MeasurementVectorTraits::Assert( min, Dimension, 
          "Length mismatch StatisticsAlgorithm::FindSampleBound");

  unsigned int dimension;
  typename TSample::MeasurementVectorType temp ;

  min = max = temp = begin.GetMeasurementVector() ;
  while (true)
    {
    for (dimension= 0 ; dimension < Dimension ; dimension++) 
      {
      if ( temp[dimension] < min[dimension]) 
        {
        min[dimension] = temp[dimension] ;
        }
      else if (temp[dimension] > max[dimension]) 
        {
        max[dimension] = temp[dimension] ;
        }
      }
    ++begin ;
    if (begin == end)
      {
      break ;
      }
    temp = begin.GetMeasurementVector() ;
    } // end of while
}

/** The endIndex should points one point after the last elements. */
template< class TSubsample >
inline void 
FindSampleBoundAndMean(const TSubsample* sample,
                       int beginIndex,
                       int endIndex,
                       typename TSubsample::MeasurementVectorType &min,
                       typename TSubsample::MeasurementVectorType &max,
                       typename TSubsample::MeasurementVectorType &mean)
{    
  typedef typename TSubsample::MeasurementType MeasurementType ;
  typedef typename TSubsample::MeasurementVectorType MeasurementVectorType ;

  typedef typename TSubsample::MeasurementVectorSizeType MeasurementVectorSizeType;  
  const MeasurementVectorSizeType Dimension = sample->GetMeasurementVectorSize();
  if( Dimension == 0 )
    {
    itkGenericExceptionMacro( 
        << "Length of a sample's measurement vector hasn't been set.");
    }

  Array< double > sum( Dimension ) ;

  MeasurementVectorSizeType dimension ;
  MeasurementVectorType temp;
  MeasurementVectorTraits::SetLength( temp, Dimension );  
  MeasurementVectorTraits::SetLength( mean, Dimension );

  min = max = temp = sample->GetMeasurementVectorByIndex(beginIndex) ;
  double frequencySum = sample->GetFrequencyByIndex(beginIndex) ;
  sum.Fill(0.0) ;
 
  while (true)
    {
    for (dimension= 0 ; dimension < Dimension ; dimension++) 
      {
      if ( temp[dimension] < min[dimension]) 
        {
        min[dimension] = temp[dimension] ;
        }
      else if (temp[dimension] > max[dimension]) 
        {
        max[dimension] = temp[dimension] ;
        }
      sum[dimension] += temp[dimension] ;
      }
    ++beginIndex ;
    if (beginIndex == endIndex)
      {
      break ;
      }
    temp = sample->GetMeasurementVectorByIndex(beginIndex) ;
    frequencySum += sample->GetFrequencyByIndex(beginIndex) ;
    } // end of while

  for (unsigned int i = 0 ; i < Dimension ; i++)
    {
    mean[i] = (MeasurementType)(sum[i] / frequencySum) ;
    }
}

/** The endIndex should point one point after the last elements.  Note that kth
 * is an index in a different scale than [beginIndex,endIndex].  For example,
 * it is possible to feed this function with beginIndex=15, endIndex=23, and
 * kth=3, since we can ask for the element 3rd in the range [15,23]. */
 
template< class TSubsample >
inline typename TSubsample::MeasurementType 
QuickSelect(TSubsample* sample,
            unsigned int activeDimension,
            int beginIndex,
            int endIndex,
            int kth,
            typename TSubsample::MeasurementType medianGuess)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -