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 ¢eroid)
00101 { }
00102
00103 void GetCenteroid(CenteroidType ¢eroid)
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 index)
00156 { return 0 ; }
00157
00158 void AddInstanceIdentifier(InstanceIdentifier id) {}
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 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 for ( unsigned int i = 0 ; i < m_Distances.size() ; i++ )
00272 {
00273 if ( m_Distances[i] > farthestDistance )
00274 {
00275 farthestDistance = m_Distances[i] ;
00276 m_FarthestNeighborIndex = i ;
00277 }
00278 }
00279 }
00280
00281 std::vector< InstanceIdentifier >& GetNeighbors()
00282 { return m_Identifiers ; }
00283
00284 std::vector< double >& GetDistances()
00285 { return m_Identifiers ; }
00286
00287 private:
00288 unsigned int m_FarthestNeighborIndex ;
00289 std::vector< InstanceIdentifier > m_Identifiers ;
00290 std::vector< double > m_Distances ;
00291 } ;
00292
00293 void SetBucketSize(unsigned int size) ;
00294
00295 void SetSample(TSample* sample) ;
00296
00297 TSample* GetSample()
00298 { return m_Sample ; }
00299
00300 KdTreeNodeType* GetEmptyTerminalNode()
00301 { return m_EmptyTerminalNode ; }
00302
00303 void SetRoot(KdTreeNodeType* root)
00304 { m_Root = root ; }
00305
00306 KdTreeNodeType* GetRoot()
00307 { return m_Root ; }
00308
00309 MeasurementVectorType& GetMeasurementVector(InstanceIdentifier id)
00310 { return m_Sample->GetMeasurementVector(id) ; }
00311
00313 DistanceMetricType* GetDistanceMetric()
00314 { return m_DistanceMetric.GetPointer() ; }
00315
00316 bool BallWithinBounds(MeasurementVectorType &query,
00317 MeasurementVectorType &lowerBound,
00318 MeasurementVectorType &upperBound) ;
00319
00320 bool BoundsOverlapBall(MeasurementVectorType &query,
00321 MeasurementVectorType &lowerBound,
00322 MeasurementVectorType &upperBound) ;
00323
00324 void Search(MeasurementVectorType &query, unsigned int k) ;
00325
00326
00327 NearestNeighbors& GetSearchResult()
00328 { return m_Neighbors ; }
00329
00330 int GetNumberOfVisits()
00331 { return m_NumberOfVisits ; }
00332
00333 void DeleteNode(KdTreeNodeType *node) ;
00334
00335 void PrintTree(KdTreeNodeType *node, int level,
00336 unsigned int activeDimension) ;
00337
00338 protected:
00339 KdTree() ;
00340 virtual ~KdTree() ;
00341 void PrintSelf(std::ostream& os, Indent indent) const ;
00342
00343 int SearchLoop(KdTreeNodeType* node, MeasurementVectorType &query,
00344 MeasurementVectorType &lowerBound,
00345 MeasurementVectorType &upperBound) ;
00346
00347 void DumpVector(MeasurementVectorType &vec) ;
00348
00349 private:
00350 KdTree(const Self&) ;
00351 void operator=(const Self&) ;
00352
00353 TSample* m_Sample ;
00354 int m_BucketSize ;
00355 KdTreeNodeType* m_Root ;
00356 KdTreeNodeType* m_EmptyTerminalNode ;
00357 typename DistanceMetricType::Pointer m_DistanceMetric ;
00358 NearestNeighbors m_Neighbors ;
00359 MeasurementVectorType m_LowerBound ;
00360 MeasurementVectorType m_UpperBound ;
00361 int m_NumberOfVisits ;
00362 bool m_StopSearch ;
00363 NeighborType m_TempNeighbor ;
00364 } ;
00365
00366 }
00367 }
00368
00369 #ifndef ITK_MANUAL_INSTANTIATION
00370 #include "itkKdTree.txx"
00371 #endif
00372
00373 #endif
00374
00375
00376