ITK  6.0.0
Insight Toolkit
itkKdTree.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright NumFOCUS
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * https://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkKdTree_h
19 #define itkKdTree_h
20 
21 #include <queue>
22 #include <vector>
23 
24 #include "itkPoint.h"
25 #include "itkSize.h"
26 #include "itkObject.h"
27 #include "itkArray.h"
28 
29 #include "itkSubsample.h"
30 
32 
33 namespace itk
34 {
35 namespace Statistics
36 {
63 template <typename TSample>
64 
65 struct ITK_TEMPLATE_EXPORT KdTreeNode
66 {
69 
71  using MeasurementType = typename TSample::MeasurementType;
72 
75 
78  using InstanceIdentifier = typename TSample::InstanceIdentifier;
79 
82  virtual bool
83  IsTerminal() const = 0;
84 
90  virtual void
91  GetParameters(unsigned int &, MeasurementType &) const = 0;
92 
94  virtual Self *
95  Left() = 0;
96 
98  virtual const Self *
99  Left() const = 0;
100 
102  virtual Self *
103  Right() = 0;
104 
106  virtual const Self *
107  Right() const = 0;
108 
113  virtual unsigned int
114  Size() const = 0;
115 
117  virtual void
118  GetWeightedCentroid(CentroidType &) = 0;
119 
121  virtual void
122  GetCentroid(CentroidType &) = 0;
123 
125  virtual InstanceIdentifier GetInstanceIdentifier(InstanceIdentifier) const = 0;
126 
128  virtual void AddInstanceIdentifier(InstanceIdentifier) = 0;
129 
131  virtual ~KdTreeNode() = default; // needed to subclasses will actually be deleted
132 }; // end of class
133 
147 template <typename TSample>
148 
149 struct ITK_TEMPLATE_EXPORT KdTreeNonterminalNode : public KdTreeNode<TSample>
150 {
152  using typename Superclass::MeasurementType;
153  using typename Superclass::CentroidType;
154  using typename Superclass::InstanceIdentifier;
155 
156  KdTreeNonterminalNode(unsigned int, MeasurementType, Superclass *, Superclass *);
157 
158  ~KdTreeNonterminalNode() override = default;
159 
160  bool
161  IsTerminal() const override
162  {
163  return false;
164  }
165 
166  void
167  GetParameters(unsigned int &, MeasurementType &) const override;
168 
170  Superclass *
171  Left() override
172  {
173  return m_Left;
174  }
175 
177  Superclass *
178  Right() override
179  {
180  return m_Right;
181  }
182 
184  const Superclass *
185  Left() const override
186  {
187  return m_Left;
188  }
189 
191  const Superclass *
192  Right() const override
193  {
194  return m_Right;
195  }
196 
201  unsigned int
202  Size() const override
203  {
204  return 0;
205  }
206 
211  void
213  {}
214 
219  void
221  {}
222 
228  InstanceIdentifier
230  {
231  return this->m_InstanceIdentifier;
232  }
233 
237  void
239  {
240  this->m_InstanceIdentifier = valueId;
241  }
242 
243 private:
244  unsigned int m_PartitionDimension{};
245  MeasurementType m_PartitionValue{};
246  InstanceIdentifier m_InstanceIdentifier{};
247  Superclass * m_Left{};
248  Superclass * m_Right{};
249 }; // end of class
250 
267 template <typename TSample>
268 struct ITK_TEMPLATE_EXPORT KdTreeWeightedCentroidNonterminalNode : public KdTreeNode<TSample>
269 {
271  using typename Superclass::MeasurementType;
272  using typename Superclass::CentroidType;
273  using typename Superclass::InstanceIdentifier;
274  using MeasurementVectorSizeType = typename TSample::MeasurementVectorSizeType;
275 
278  Superclass *,
279  Superclass *,
280  CentroidType &,
281  unsigned int);
282 
283  ~KdTreeWeightedCentroidNonterminalNode() override = default;
284 
286  bool
287  IsTerminal() const override
288  {
289  return false;
290  }
291 
293  void
294  GetParameters(unsigned int &, MeasurementType &) const override;
295 
297  MeasurementVectorSizeType
299  {
300  return m_MeasurementVectorSize;
301  }
302 
304  Superclass *
305  Left() override
306  {
307  return m_Left;
308  }
309 
311  Superclass *
312  Right() override
313  {
314  return m_Right;
315  }
316 
318  const Superclass *
319  Left() const override
320  {
321  return m_Left;
322  }
323 
325  const Superclass *
326  Right() const override
327  {
328  return m_Right;
329  }
330 
332  unsigned int
333  Size() const override
334  {
335  return m_Size;
336  }
337 
341  void
342  GetWeightedCentroid(CentroidType & centroid) override
343  {
344  centroid = m_WeightedCentroid;
345  }
346 
350  void
351  GetCentroid(CentroidType & centroid) override
352  {
353  centroid = m_Centroid;
354  }
355 
361  InstanceIdentifier
363  {
364  return this->m_InstanceIdentifier;
365  }
366 
370  void
372  {
373  this->m_InstanceIdentifier = valueId;
374  }
375 
376 private:
377  MeasurementVectorSizeType m_MeasurementVectorSize{};
378  unsigned int m_PartitionDimension{};
379  MeasurementType m_PartitionValue{};
380  CentroidType m_WeightedCentroid{};
381  CentroidType m_Centroid{};
382  InstanceIdentifier m_InstanceIdentifier{};
383  unsigned int m_Size{};
384  Superclass * m_Left{};
385  Superclass * m_Right{};
386 }; // end of class
387 
401 template <typename TSample>
402 struct ITK_TEMPLATE_EXPORT KdTreeTerminalNode : public KdTreeNode<TSample>
403 {
405  using typename Superclass::MeasurementType;
406  using typename Superclass::CentroidType;
407  using typename Superclass::InstanceIdentifier;
408 
409  KdTreeTerminalNode() = default;
410 
411  ~KdTreeTerminalNode() override { this->m_InstanceIdentifiers.clear(); }
412 
414  bool
415  IsTerminal() const override
416  {
417  return true;
418  }
419 
421  void
422  GetParameters(unsigned int &, MeasurementType &) const override
423  {}
424 
426  Superclass *
427  Left() override
428  {
429  return nullptr;
430  }
431 
433  Superclass *
434  Right() override
435  {
436  return nullptr;
437  }
438 
440  const Superclass *
441  Left() const override
442  {
443  return nullptr;
444  }
445 
447  const Superclass *
448  Right() const override
449  {
450  return nullptr;
451  }
452 
454  unsigned int
455  Size() const override
456  {
457  return static_cast<unsigned int>(m_InstanceIdentifiers.size());
458  }
459 
464  void
466  {}
467 
472  void
474  {}
475 
481  InstanceIdentifier
483  {
484  return m_InstanceIdentifiers[index];
485  }
486 
490  void
492  {
493  m_InstanceIdentifiers.push_back(id);
494  }
495 
496 private:
497  std::vector<InstanceIdentifier> m_InstanceIdentifiers{};
498 }; // end of class
499 
534 template <typename TSample>
535 class ITK_TEMPLATE_EXPORT KdTree : public Object
536 {
537 public:
538  ITK_DISALLOW_COPY_AND_MOVE(KdTree);
539 
541  using Self = KdTree;
545 
547  itkOverrideGetNameOfClassMacro(KdTree);
548 
550  itkNewMacro(Self);
551 
553  using SampleType = TSample;
554  using MeasurementVectorType = typename TSample::MeasurementVectorType;
555  using MeasurementType = typename TSample::MeasurementType;
556  using InstanceIdentifier = typename TSample::InstanceIdentifier;
557  using AbsoluteFrequencyType = typename TSample::AbsoluteFrequencyType;
558 
559  using MeasurementVectorSizeType = unsigned int;
560 
563  itkGetConstMacro(MeasurementVectorSize, MeasurementVectorSizeType);
564 
567 
570 
574  using NeighborType = std::pair<InstanceIdentifier, double>;
575 
576  using InstanceIdentifierVectorType = std::vector<InstanceIdentifier>;
577 
590  {
591  public:
592 
594  NearestNeighbors(std::vector<double> & cache_vector)
595  : m_FarthestNeighborIndex(0)
596  , m_Distances(cache_vector)
597  {}
598  NearestNeighbors() = delete;
599 
601  ~NearestNeighbors() = default;
602 
605  void
606  resize(unsigned int k)
607  {
608  m_Identifiers.clear();
609  m_Identifiers.resize(k, NumericTraits<IdentifierType>::max());
610  m_Distances.clear();
611  m_Distances.resize(k, NumericTraits<double>::max());
612  m_FarthestNeighborIndex = 0;
613  }
617  double
619  {
620  return m_Distances[m_FarthestNeighborIndex];
621  }
622 
625  void
627  {
628  m_Identifiers[m_FarthestNeighborIndex] = id;
629  m_Distances[m_FarthestNeighborIndex] = distance;
630  double farthestDistance = NumericTraits<double>::min();
631  const auto size = static_cast<unsigned int>(m_Distances.size());
632  for (unsigned int i = 0; i < size; ++i)
633  {
634  if (m_Distances[i] > farthestDistance)
635  {
636  farthestDistance = m_Distances[i];
637  m_FarthestNeighborIndex = i;
638  }
639  }
640  }
645  GetNeighbors() const
646  {
647  return m_Identifiers;
648  }
649 
653  GetNeighbor(unsigned int index) const
654  {
655  return m_Identifiers[index];
656  }
657 
658  private:
661 
664 
668  std::vector<double> & m_Distances;
669  };
670 
673  void
674  SetBucketSize(unsigned int);
675 
678  void
679  SetSample(const TSample *);
680 
682  const TSample *
683  GetSample() const
684  {
685  return m_Sample;
686  }
687 
689  Size() const
690  {
691  return m_Sample->Size();
692  }
693 
698  KdTreeNodeType *
700  {
701  return m_EmptyTerminalNode;
702  }
703 
706  void
708  {
709  if (this->m_Root)
710  {
711  this->DeleteNode(this->m_Root);
712  }
713  this->m_Root = root;
714  }
718  KdTreeNodeType *
720  {
721  return m_Root;
722  }
723 
726  const MeasurementVectorType &
728  {
729  return m_Sample->GetMeasurementVector(id);
730  }
731 
734  AbsoluteFrequencyType
736  {
737  return m_Sample->GetFrequency(id);
738  }
739 
741  DistanceMetricType *
743  {
744  return m_DistanceMetric.GetPointer();
745  }
746 
748  void
749  Search(const MeasurementVectorType &, unsigned int, InstanceIdentifierVectorType &) const;
750 
754  void
755  Search(const MeasurementVectorType &, unsigned int, InstanceIdentifierVectorType &, std::vector<double> &) const;
756 
758  void
759  Search(const MeasurementVectorType &, double, InstanceIdentifierVectorType &) const;
760 
766  bool
767  BallWithinBounds(const MeasurementVectorType &, MeasurementVectorType &, MeasurementVectorType &, double) const;
768 
772  bool
773  BoundsOverlapBall(const MeasurementVectorType &, MeasurementVectorType &, MeasurementVectorType &, double) const;
774 
776  void
777  DeleteNode(KdTreeNodeType *);
778 
780  void
781  PrintTree(std::ostream &) const;
782 
784  void
785  PrintTree(KdTreeNodeType *, unsigned int, unsigned int, std::ostream & os = std::cout) const;
786 
789  void
790  PlotTree(std::ostream & os) const;
791 
793  void
794  PlotTree(KdTreeNodeType * node, std::ostream & os = std::cout) const;
795 
796  using Iterator = typename TSample::Iterator;
797  using ConstIterator = typename TSample::ConstIterator;
798 
799 protected:
801  KdTree();
802 
804  ~KdTree() override;
805 
806  void
807  PrintSelf(std::ostream & os, Indent indent) const override;
808 
810  int
811  NearestNeighborSearchLoop(const KdTreeNodeType *,
812  const MeasurementVectorType &,
815  NearestNeighbors &) const;
816 
818  int
819  SearchLoop(const KdTreeNodeType *,
820  const MeasurementVectorType &,
821  double,
825 
826 private:
828  const TSample * m_Sample{};
829 
831  int m_BucketSize{};
832 
834  KdTreeNodeType * m_Root{};
835 
837  KdTreeNodeType * m_EmptyTerminalNode{};
838 
840  typename DistanceMetricType::Pointer m_DistanceMetric{};
841 
843  MeasurementVectorSizeType m_MeasurementVectorSize{};
844 }; // end of class
845 } // end of namespace Statistics
846 } // end of namespace itk
847 
848 #ifndef ITK_MANUAL_INSTANTIATION
849 # include "itkKdTree.hxx"
850 #endif
851 
852 #endif
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::GetWeightedCentroid
void GetWeightedCentroid(CentroidType &centroid) override
Definition: itkKdTree.h:342
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::Size
unsigned int Size() const override
Definition: itkKdTree.h:333
itk::Statistics::KdTree::NearestNeighbors::GetNeighbor
InstanceIdentifier GetNeighbor(unsigned int index) const
Definition: itkKdTree.h:653
itk::Statistics::KdTree
This class provides methods for k-nearest neighbor search and related data structures for a k-d tree.
Definition: itkKdTree.h:535
itkSubsample.h
itk::Statistics::KdTree::NearestNeighbors::m_FarthestNeighborIndex
unsigned int m_FarthestNeighborIndex
Definition: itkKdTree.h:660
itk::Statistics::KdTree::NearestNeighbors::m_Distances
std::vector< double > & m_Distances
Definition: itkKdTree.h:668
itk::Statistics::KdTreeNonterminalNode::AddInstanceIdentifier
void AddInstanceIdentifier(InstanceIdentifier valueId) override
Definition: itkKdTree.h:238
itk::Statistics::KdTreeNode::MeasurementType
typename TSample::MeasurementType MeasurementType
Definition: itkKdTree.h:71
itk::Size
Represent a n-dimensional size (bounds) of a n-dimensional image.
Definition: itkSize.h:69
itk::Statistics::KdTree::GetFrequency
AbsoluteFrequencyType GetFrequency(InstanceIdentifier id) const
Definition: itkKdTree.h:735
itk::Statistics::KdTree::MeasurementVectorSizeType
unsigned int MeasurementVectorSizeType
Definition: itkKdTree.h:559
itk::Statistics::KdTreeNonterminalNode::GetWeightedCentroid
void GetWeightedCentroid(CentroidType &) override
Definition: itkKdTree.h:212
itk::Statistics::KdTreeNode::InstanceIdentifier
typename TSample::InstanceIdentifier InstanceIdentifier
Definition: itkKdTree.h:78
itk::Statistics::KdTreeWeightedCentroidNonterminalNode
This is a subclass of the KdTreeNode.
Definition: itkKdTree.h:268
itkPoint.h
itk::Statistics::KdTree::NearestNeighbors::NearestNeighbors
NearestNeighbors(std::vector< double > &cache_vector)
Definition: itkKdTree.h:594
itk::Statistics::KdTree::GetDistanceMetric
DistanceMetricType * GetDistanceMetric()
Definition: itkKdTree.h:742
itk::Statistics::KdTree::NeighborType
std::pair< InstanceIdentifier, double > NeighborType
Definition: itkKdTree.h:574
itk::Statistics::KdTreeNonterminalNode
This is a subclass of the KdTreeNode.
Definition: itkKdTree.h:149
itk::NumericTraits::min
static constexpr T min(const T &)
Definition: itkNumericTraits.h:174
itk::Statistics::KdTree::InstanceIdentifier
typename TSample::InstanceIdentifier InstanceIdentifier
Definition: itkKdTree.h:556
itk::Statistics::KdTree::InstanceIdentifierVectorType
std::vector< InstanceIdentifier > InstanceIdentifierVectorType
Definition: itkKdTree.h:576
itk::Statistics::KdTreeTerminalNode::Size
unsigned int Size() const override
Definition: itkKdTree.h:455
itk::Statistics::KdTreeNonterminalNode::GetCentroid
void GetCentroid(CentroidType &) override
Definition: itkKdTree.h:220
itk::Statistics::KdTreeNonterminalNode::Left
const Superclass * Left() const override
Definition: itkKdTree.h:185
itk::SmartPointer< Self >
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::MeasurementVectorSizeType
typename TSample::MeasurementVectorSizeType MeasurementVectorSizeType
Definition: itkKdTree.h:274
itk::Indent
Control indentation during Print() invocation.
Definition: itkIndent.h:49
itk::Statistics::KdTree::NearestNeighbors::GetLargestDistance
double GetLargestDistance()
Definition: itkKdTree.h:618
itk::Statistics::KdTreeNonterminalNode::Left
Superclass * Left() override
Definition: itkKdTree.h:171
itk::Statistics::KdTree::MeasurementVectorType
typename TSample::MeasurementVectorType MeasurementVectorType
Definition: itkKdTree.h:554
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::Left
Superclass * Left() override
Definition: itkKdTree.h:305
itk::Statistics::KdTreeTerminalNode::~KdTreeTerminalNode
~KdTreeTerminalNode() override
Definition: itkKdTree.h:411
itk::Statistics::KdTree::GetEmptyTerminalNode
KdTreeNodeType * GetEmptyTerminalNode()
Definition: itkKdTree.h:699
itk::Statistics::KdTreeNonterminalNode::Right
const Superclass * Right() const override
Definition: itkKdTree.h:192
itk::Statistics::KdTree::NearestNeighbors::GetNeighbors
const InstanceIdentifierVectorType & GetNeighbors() const
Definition: itkKdTree.h:645
itk::Statistics::KdTreeNonterminalNode::IsTerminal
bool IsTerminal() const override
Definition: itkKdTree.h:161
itk::LightObject
Light weight base class for most itk classes.
Definition: itkLightObject.h:55
itk::Statistics::KdTree::NearestNeighbors::ReplaceFarthestNeighbor
void ReplaceFarthestNeighbor(InstanceIdentifier id, double distance)
Definition: itkKdTree.h:626
itk::Statistics::KdTree::NearestNeighbors::resize
void resize(unsigned int k)
Definition: itkKdTree.h:606
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::AddInstanceIdentifier
void AddInstanceIdentifier(InstanceIdentifier valueId) override
Definition: itkKdTree.h:371
itk::Statistics::KdTreeNonterminalNode::Size
unsigned int Size() const override
Definition: itkKdTree.h:202
itk::Statistics::KdTreeTerminalNode::IsTerminal
bool IsTerminal() const override
Definition: itkKdTree.h:415
itk::Statistics::KdTreeTerminalNode
This class is the node that doesn't have any child node. The IsTerminal method returns true for this ...
Definition: itkKdTree.h:402
itk::Statistics::KdTree::Size
SizeValueType Size() const
Definition: itkKdTree.h:689
itk::Statistics::KdTree::NearestNeighbors::m_Identifiers
InstanceIdentifierVectorType m_Identifiers
Definition: itkKdTree.h:663
itk::Statistics::KdTreeNonterminalNode::GetInstanceIdentifier
InstanceIdentifier GetInstanceIdentifier(InstanceIdentifier) const override
Definition: itkKdTree.h:229
itk::Statistics::KdTree::GetSample
const TSample * GetSample() const
Definition: itkKdTree.h:683
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::GetCentroid
void GetCentroid(CentroidType &centroid) override
Definition: itkKdTree.h:351
itk::Statistics::KdTreeTerminalNode::GetCentroid
void GetCentroid(CentroidType &) override
Definition: itkKdTree.h:473
itk::Statistics::KdTree::MeasurementType
typename TSample::MeasurementType MeasurementType
Definition: itkKdTree.h:555
itk::Statistics::KdTree::SetRoot
void SetRoot(KdTreeNodeType *root)
Definition: itkKdTree.h:707
itk::Statistics::KdTreeTerminalNode::Right
const Superclass * Right() const override
Definition: itkKdTree.h:448
itk::Statistics::KdTreeTerminalNode::Left
const Superclass * Left() const override
Definition: itkKdTree.h:441
itk::Statistics::EuclideanDistanceMetric
Euclidean distance function.
Definition: itkEuclideanDistanceMetric.h:35
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::Right
const Superclass * Right() const override
Definition: itkKdTree.h:326
itk::Statistics::KdTreeTerminalNode::GetWeightedCentroid
void GetWeightedCentroid(CentroidType &) override
Definition: itkKdTree.h:465
itk::Statistics::KdTree::ConstIterator
typename TSample::ConstIterator ConstIterator
Definition: itkKdTree.h:797
itk::NumericTraits
Define additional traits for native types such as int or float.
Definition: itkNumericTraits.h:60
itkArray.h
itk::Statistics::KdTree::SampleType
TSample SampleType
Definition: itkKdTree.h:553
itk::Statistics::KdTreeTerminalNode::GetInstanceIdentifier
InstanceIdentifier GetInstanceIdentifier(InstanceIdentifier index) const override
Definition: itkKdTree.h:482
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::GetInstanceIdentifier
InstanceIdentifier GetInstanceIdentifier(InstanceIdentifier) const override
Definition: itkKdTree.h:362
itkObject.h
itk::Statistics::KdTreeTerminalNode::GetParameters
void GetParameters(unsigned int &, MeasurementType &) const override
Definition: itkKdTree.h:422
itk::Statistics::KdTreeTerminalNode::Right
Superclass * Right() override
Definition: itkKdTree.h:434
itk::Statistics::KdTreeNonterminalNode::Right
Superclass * Right() override
Definition: itkKdTree.h:178
itk::Statistics::KdTree::Iterator
typename TSample::Iterator Iterator
Definition: itkKdTree.h:796
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnatomicalOrientation.h:29
itk::Statistics::KdTreeTerminalNode::Left
Superclass * Left() override
Definition: itkKdTree.h:427
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::Right
Superclass * Right() override
Definition: itkKdTree.h:312
itk::Array< double >
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::IsTerminal
bool IsTerminal() const override
Definition: itkKdTree.h:287
itk::Object
Base class for most ITK classes.
Definition: itkObject.h:61
itk::Statistics::KdTree::GetRoot
KdTreeNodeType * GetRoot()
Definition: itkKdTree.h:719
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::Left
const Superclass * Left() const override
Definition: itkKdTree.h:319
itk::Statistics::KdTree::GetMeasurementVector
const MeasurementVectorType & GetMeasurementVector(InstanceIdentifier id) const
Definition: itkKdTree.h:727
itkEuclideanDistanceMetric.h
itk::Statistics::KdTreeWeightedCentroidNonterminalNode::GetMeasurementVectorSize
MeasurementVectorSizeType GetMeasurementVectorSize() const
Definition: itkKdTree.h:298
Superclass
BinaryGeneratorImageFilter< TInputImage1, TInputImage2, TOutputImage > Superclass
Definition: itkAddImageFilter.h:90
itk::Statistics::KdTreeTerminalNode::AddInstanceIdentifier
void AddInstanceIdentifier(InstanceIdentifier id) override
Definition: itkKdTree.h:491
itk::Statistics::KdTree::NearestNeighbors
data structure for storing k-nearest neighbor search result (k number of Neighbors)
Definition: itkKdTree.h:589
itk::SizeValueType
unsigned long SizeValueType
Definition: itkIntTypes.h:86
itkSize.h
itk::Statistics::KdTree::AbsoluteFrequencyType
typename TSample::AbsoluteFrequencyType AbsoluteFrequencyType
Definition: itkKdTree.h:557
itk::Statistics::KdTreeNode
This class defines the interface of its derived classes.
Definition: itkKdTree.h:65