1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkWeightedCentroidKdTreeGenerator.txx,v $
Language: C++
Date: $Date: 2009-03-04 19:29:54 $
Version: $Revision: 1.11 $
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 __itkWeightedCentroidKdTreeGenerator_txx
#define __itkWeightedCentroidKdTreeGenerator_txx
namespace itk {
namespace Statistics {
template< class TSample >
WeightedCentroidKdTreeGenerator< TSample >
::WeightedCentroidKdTreeGenerator()
{
}
template< class TSample >
void
WeightedCentroidKdTreeGenerator< TSample >
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);
}
template< class TSample >
inline typename WeightedCentroidKdTreeGenerator< TSample >::KdTreeNodeType*
WeightedCentroidKdTreeGenerator< TSample >
::GenerateNonterminalNode(unsigned int beginIndex,
unsigned int endIndex,
MeasurementVectorType &lowerBound,
MeasurementVectorType &upperBound,
unsigned int level)
{
MeasurementType dimensionLowerBound;
MeasurementType dimensionUpperBound;
MeasurementType partitionValue;
unsigned int partitionDimension = 0;
unsigned int i;
unsigned int j;
MeasurementType spread;
MeasurementType maxSpread;
unsigned int medianIndex;
SubsamplePointer subsample = this->GetSubsample();
// Sanity check. Verify that the subsample has measurement vectors of the
// same length as the sample generated by the tree.
if( this->GetMeasurementVectorSize() != subsample->GetMeasurementVectorSize() )
{
itkExceptionMacro( << "Measurement Vector Length mismatch" );
}
// calculates the weighted centroid which is the vector sum
// of all the associated instances.
typename KdTreeNodeType::CentroidType weightedCentroid;
MeasurementVectorTraits::SetLength( weightedCentroid, this->GetMeasurementVectorSize() );
MeasurementVectorType tempVector;
weightedCentroid.Fill(NumericTraits< MeasurementType >::Zero);
for (i = beginIndex; i < endIndex; i++)
{
tempVector = subsample->GetMeasurementVectorByIndex(i);
for(j = 0; j < this->GetMeasurementVectorSize(); j++)
{
weightedCentroid[j] += tempVector[j];
}
}
// find most widely spread dimension
FindSampleBoundAndMean< SubsampleType >(this->GetSubsample(),
beginIndex, endIndex,
m_TempLowerBound, m_TempUpperBound,
m_TempMean);
maxSpread = NumericTraits< MeasurementType >::NonpositiveMin();
for (i = 0; i < this->GetMeasurementVectorSize(); i++)
{
spread = m_TempUpperBound[i] - m_TempLowerBound[i];
if (spread >= maxSpread)
{
maxSpread = spread;
partitionDimension = i;
}
}
medianIndex = (endIndex - beginIndex) / 2;
//
// Find the medial element by using the NthElement function
// based on the STL implementation of the QuickSelect algorithm.
//
partitionValue =
NthElement< SubsampleType >(this->GetSubsample(),
partitionDimension,
beginIndex, endIndex,
medianIndex);
medianIndex += beginIndex;
// save bounds for cutting dimension
dimensionLowerBound = lowerBound[partitionDimension];
dimensionUpperBound = upperBound[partitionDimension];
upperBound[partitionDimension] = partitionValue;
const unsigned int beginLeftIndex = beginIndex;
const unsigned int endLeftIndex = medianIndex;
KdTreeNodeType* left = GenerateTreeLoop(beginLeftIndex, endLeftIndex, lowerBound, upperBound, level + 1);
upperBound[partitionDimension] = dimensionUpperBound;
lowerBound[partitionDimension] = partitionValue;
const unsigned int beginRightIndex = medianIndex+1;
const unsigned int endRighIndex = endIndex;
KdTreeNodeType* right = GenerateTreeLoop(beginRightIndex, endRighIndex, lowerBound, upperBound, level + 1);
lowerBound[partitionDimension] = dimensionLowerBound;
typedef KdTreeWeightedCentroidNonterminalNode< TSample > KdTreeNonterminalNodeType;
KdTreeNonterminalNodeType * nonTerminalNode =
new KdTreeNonterminalNodeType( partitionDimension,
partitionValue,
left, right,
weightedCentroid,
endIndex - beginIndex);
nonTerminalNode->AddInstanceIdentifier(
subsample->GetInstanceIdentifier( medianIndex ) );
return nonTerminalNode;
}
} // end of namespace Statistics
} // end of namespace itk
#endif
|