00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkKdTree_h
00018 #define __itkKdTree_h
00019
00020 #include <queue>
00021 #include <vector>
00022
00023 #include "itkMacro.h"
00024 #include "itkPoint.h"
00025 #include "itkSize.h"
00026 #include "itkObject.h"
00027 #include "itkNumericTraits.h"
00028 #include "itkArray.h"
00029
00030 #include "itkSample.h"
00031 #include "itkSubsample.h"
00032
00033 #include "itkEuclideanDistance.h"
00034
00035 namespace itk{
00036 namespace Statistics{
00037
00038 template< class TSample >
00039 struct KdTreeNode
00040 {
00041 typedef KdTreeNode< TSample> Self ;
00042 typedef typename TSample::MeasurementType MeasurementType ;
00043 itkStaticConstMacro(MeasurementVectorSize, unsigned int,
00044 TSample::MeasurementVectorSize) ;
00045 typedef FixedArray< double,
00046 itkGetStaticConstMacro(MeasurementVectorSize) > CenteroidType ;
00047 typedef typename TSample::InstanceIdentifier InstanceIdentifier ;
00048
00049 virtual bool IsTerminal() = 0 ;
00050
00051 virtual void GetParameters(unsigned int &partitionDimension,
00052 MeasurementType &partitionValue) = 0 ;
00053 virtual Self* Left() = 0 ;
00054
00055 virtual Self* Right() = 0 ;
00056
00057 virtual unsigned int Size() = 0 ;
00058
00059 virtual void GetWeightedCenteroid(CenteroidType ¢eroid) = 0 ;
00060
00061 virtual void GetCenteroid(CenteroidType ¢eroid) = 0 ;
00062
00063 virtual InstanceIdentifier GetInstanceIdentifier(size_t index) = 0 ;
00064
00065 virtual void AddInstanceIdentifier(InstanceIdentifier id) = 0 ;
00066
00067 virtual ~KdTreeNode() {};
00068 } ;
00069
00070 template< class TSample >
00071 struct KdTreeNonterminalNode: public KdTreeNode< TSample >
00072 {
00073 typedef KdTreeNode< TSample > Superclass ;
00074 typedef typename Superclass::MeasurementType MeasurementType ;
00075 typedef typename Superclass::CenteroidType CenteroidType ;
00076 typedef typename Superclass::InstanceIdentifier InstanceIdentifier ;
00077
00078 KdTreeNonterminalNode(unsigned int partitionDimension,
00079 MeasurementType partitionValue,
00080 Superclass* left,
00081 Superclass* right) ;
00082
00083 virtual ~KdTreeNonterminalNode() {}
00084
00085 virtual bool IsTerminal()
00086 { return false ; }
00087
00088 void GetParameters(unsigned int &partitionDimension,
00089 MeasurementType &partitionValue) ;
00090
00091 Superclass* Left()
00092 { return m_Left ; }
00093
00094 Superclass* Right()
00095 { return m_Right ; }
00096
00097 unsigned int Size()
00098 { return 0 ; }
00099
00100 void GetWeightedCenteroid(CenteroidType &)
00101 { }
00102
00103 void GetCenteroid(CenteroidType &)
00104 { }
00105
00106 InstanceIdentifier GetInstanceIdentifier(size_t)
00107 { return 0 ; }
00108
00109 void AddInstanceIdentifier(InstanceIdentifier) {}
00110
00111 private:
00112 unsigned int m_PartitionDimension ;
00113 MeasurementType m_PartitionValue ;
00114 Superclass* m_Left ;
00115 Superclass* m_Right ;
00116 } ;
00117
00118 template< class TSample >
00119 struct KdTreeWeightedCenteroidNonterminalNode: public KdTreeNode< TSample >
00120 {
00121 typedef KdTreeNode< TSample > Superclass ;
00122 typedef typename Superclass::MeasurementType MeasurementType ;
00123 typedef typename Superclass::CenteroidType CenteroidType ;
00124 typedef typename Superclass::InstanceIdentifier InstanceIdentifier ;
00125
00126 KdTreeWeightedCenteroidNonterminalNode(unsigned int partitionDimension,
00127 MeasurementType partitionValue,
00128 Superclass* left,
00129 Superclass* right,
00130 CenteroidType ¢eroid,
00131 unsigned int size) ;
00132 virtual ~KdTreeWeightedCenteroidNonterminalNode() {}
00133
00134 virtual bool IsTerminal()
00135 { return false ; }
00136
00137 void GetParameters(unsigned int &partitionDimension,
00138 MeasurementType &partitionValue) ;
00139
00140 Superclass* Left()
00141 { return m_Left ; }
00142
00143 Superclass* Right()
00144 { return m_Right ; }
00145
00146 unsigned int Size()
00147 { return m_Size ; }
00148
00149 void GetWeightedCenteroid(CenteroidType ¢eroid)
00150 { centeroid = m_WeightedCenteroid ; }
00151
00152 void GetCenteroid(CenteroidType ¢eroid)
00153 { centeroid = m_Centeroid ; }
00154
00155 InstanceIdentifier GetInstanceIdentifier(size_t)
00156 { return 0 ; }
00157
00158 void AddInstanceIdentifier(InstanceIdentifier) {}
00159
00160 private:
00161 unsigned int m_PartitionDimension ;
00162 MeasurementType m_PartitionValue ;
00163 CenteroidType m_WeightedCenteroid ;
00164 CenteroidType m_Centeroid ;
00165 unsigned int m_Size ;
00166 Superclass* m_Left ;
00167 Superclass* m_Right ;
00168 } ;
00169
00170
00171 template< class TSample >
00172 struct KdTreeTerminalNode: public KdTreeNode< TSample >
00173 {
00174 typedef KdTreeNode< TSample > Superclass ;
00175 typedef typename Superclass::MeasurementType MeasurementType ;
00176 typedef typename Superclass::CenteroidType CenteroidType ;
00177 typedef typename Superclass::InstanceIdentifier InstanceIdentifier ;
00178
00179 KdTreeTerminalNode() {}
00180
00181 virtual ~KdTreeTerminalNode() {}
00182
00183 bool IsTerminal()
00184 { return true ; }
00185
00186 void GetParameters(unsigned int &,
00187 MeasurementType &) {}
00188
00189 Superclass* Left()
00190 { return 0 ; }
00191
00192 Superclass* Right()
00193 { return 0 ; }
00194
00195 unsigned int Size()
00196 { return static_cast<unsigned int>( m_InstanceIdentifiers.size() ); }
00197
00198 void GetWeightedCenteroid(CenteroidType &)
00199 { }
00200
00201 void GetCenteroid(CenteroidType &)
00202 { }
00203
00204 InstanceIdentifier GetInstanceIdentifier(size_t index)
00205 { return m_InstanceIdentifiers[index] ; }
00206
00207 void AddInstanceIdentifier(InstanceIdentifier id)
00208 { m_InstanceIdentifiers.push_back(id) ;}
00209
00210 private:
00211 std::vector< InstanceIdentifier > m_InstanceIdentifiers ;
00212 } ;
00213
00218 template < class TSample >
00219 class ITK_EXPORT KdTree : public Object
00220 {
00221 public:
00223 typedef KdTree Self ;
00224 typedef Object Superclass ;
00225 typedef SmartPointer<Self> Pointer;
00226
00228 itkTypeMacro(KdTree, Object);
00229
00231 itkNewMacro(Self) ;
00232
00234 typedef TSample SampleType ;
00235 typedef typename TSample::MeasurementVectorType MeasurementVectorType ;
00236 typedef typename TSample::MeasurementType MeasurementType ;
00237 typedef typename TSample::InstanceIdentifier InstanceIdentifier ;
00238
00239 itkStaticConstMacro(MeasurementVectorSize, unsigned int,
00240 TSample::MeasurementVectorSize) ;
00241
00242 typedef EuclideanDistance< MeasurementVectorType > DistanceMetricType ;
00243
00244 typedef KdTreeNode< TSample > KdTreeNodeType ;
00245
00246 typedef std::pair< InstanceIdentifier, double > NeighborType ;
00247
00248 class NearestNeighbors
00249 {
00250 public:
00251 NearestNeighbors() {}
00252 ~NearestNeighbors() {}
00253
00254 void resize(unsigned int k)
00255 {
00256 m_Identifiers.clear() ;
00257 m_Identifiers.resize(k, NumericTraits< unsigned long >::max()) ;
00258 m_Distances.clear() ;
00259 m_Distances.resize(k, NumericTraits< double >::max()) ;
00260 m_FarthestNeighborIndex = 0 ;
00261 }
00262
00263 double GetLargestDistance()
00264 { return m_Distances[m_FarthestNeighborIndex] ; }
00265
00266 void ReplaceFarthestNeighbor(InstanceIdentifier id, double distance)
00267 {
00268 m_Identifiers[m_FarthestNeighborIndex] = id ;
00269 m_Distances[m_FarthestNeighborIndex] = distance ;
00270 double farthestDistance = NumericTraits< double >::min() ;
00271 const unsigned int size = static_cast<unsigned int>( m_Distances.size() );
00272 for ( unsigned int i = 0 ; i < size; i++ )
00273 {
00274 if ( m_Distances[i] > farthestDistance )
00275 {
00276 farthestDistance = m_Distances[i] ;
00277 m_FarthestNeighborIndex = i ;
00278 }
00279 }
00280 }
00281
00282 std::vector< InstanceIdentifier >& GetNeighbors()
00283 { return m_Identifiers ; }
00284
00285 std::vector< double >& GetDistances()
00286 { return m_Identifiers ; }
00287
00288 private:
00289 unsigned int m_FarthestNeighborIndex ;
00290 std::vector< InstanceIdentifier > m_Identifiers ;
00291 std::vector< double > m_Distances ;
00292 } ;
00293
00294 void SetBucketSize(unsigned int size) ;
00295
00296 void SetSample(TSample* sample) ;
00297
00298 TSample* GetSample()
00299 { return m_Sample ; }
00300
00301 KdTreeNodeType* GetEmptyTerminalNode()
00302 { return m_EmptyTerminalNode ; }
00303
00304 void SetRoot(KdTreeNodeType* root)
00305 { m_Root = root ; }
00306
00307 KdTreeNodeType* GetRoot()
00308 { return m_Root ; }
00309
00310 MeasurementVectorType& GetMeasurementVector(InstanceIdentifier id)
00311 { return m_Sample->GetMeasurementVector(id) ; }
00312
00314 DistanceMetricType* GetDistanceMetric()
00315 { return m_DistanceMetric.GetPointer() ; }
00316
00317 bool BallWithinBounds(MeasurementVectorType &query,
00318 MeasurementVectorType &lowerBound,
00319 MeasurementVectorType &upperBound) ;
00320
00321 bool BoundsOverlapBall(MeasurementVectorType &query,
00322 MeasurementVectorType &lowerBound,
00323 MeasurementVectorType &upperBound) ;
00324
00325 void Search(MeasurementVectorType &query, unsigned int k) ;
00326
00327
00328 NearestNeighbors& GetSearchResult()
00329 { return m_Neighbors ; }
00330
00331 int GetNumberOfVisits()
00332 { return m_NumberOfVisits ; }
00333
00334 void DeleteNode(KdTreeNodeType *node) ;
00335
00336 void PrintTree(KdTreeNodeType *node, int level,
00337 unsigned int activeDimension) ;
00338
00339 protected:
00340 KdTree() ;
00341 virtual ~KdTree() ;
00342 void PrintSelf(std::ostream& os, Indent indent) const ;
00343
00344 int SearchLoop(KdTreeNodeType* node, MeasurementVectorType &query,
00345 MeasurementVectorType &lowerBound,
00346 MeasurementVectorType &upperBound) ;
00347
00348 void DumpVector(MeasurementVectorType &vec) ;
00349
00350 private:
00351 KdTree(const Self&) ;
00352 void operator=(const Self&) ;
00353
00354 TSample* m_Sample ;
00355 int m_BucketSize ;
00356 KdTreeNodeType* m_Root ;
00357 KdTreeNodeType* m_EmptyTerminalNode ;
00358 typename DistanceMetricType::Pointer m_DistanceMetric ;
00359 NearestNeighbors m_Neighbors ;
00360 MeasurementVectorType m_LowerBound ;
00361 MeasurementVectorType m_UpperBound ;
00362 int m_NumberOfVisits ;
00363 bool m_StopSearch ;
00364 NeighborType m_TempNeighbor ;
00365 } ;
00366
00367 }
00368 }
00369
00370 #ifndef ITK_MANUAL_INSTANTIATION
00371 #include "itkKdTree.txx"
00372 #endif
00373
00374 #endif
00375
00376
00377