Direct Graphical Models  v.1.7.0
KDNode.cpp
1 #include "KDNode.h"
2 #include "mathop.h"
3 
4 namespace DirectGraphicalModels
5 {
6  // Protected Constructor
7  CKDNode::CKDNode(Mat &key, byte value, pair_mat_t &boundingBox, byte splitVal, int splitDim, std::shared_ptr<CKDNode> left, std::shared_ptr<CKDNode> right)
8  : m_value(value)
9  , m_boundingBox(boundingBox)
10  , m_splitVal(splitVal)
11  , m_splitDim(splitDim)
12  , m_pLeft(left)
13  , m_pRight(right)
14  {
15  key.copyTo(m_key);
16  }
17 
18  void CKDNode::save(FILE *pFile) const
19  {
20  byte _isLeaf = isLeaf();
21  fwrite(&_isLeaf, sizeof(byte), 1, pFile);
22  if (isLeaf()) { // --- Leaf node ---
23  fwrite(m_key.data, sizeof(byte), m_key.cols, pFile);
24  fwrite(&m_value, sizeof(byte), 1, pFile);
25  } else { // --- Branch node ---
26  fwrite(m_boundingBox.first.data, sizeof(byte), m_boundingBox.first.cols, pFile);
27  fwrite(m_boundingBox.second.data, sizeof(byte), m_boundingBox.second.cols, pFile);
28  fwrite(&m_splitVal, sizeof(byte), 1, pFile);
29  fwrite(&m_splitDim, sizeof(int), 1, pFile);
30 
31  m_pLeft->save(pFile);
32  m_pRight->save(pFile);
33  }
34  }
35 
36  void CKDNode::findNearestNeighbors(const Mat &key, size_t maxNeighbors, pair_mat_t &searchBox, float &searchRadius, std::vector<std::shared_ptr<const CKDNode>> &nearestNeighbors) const
37  {
38  if (isLeaf()) { // --- Leaf node ---
39  float distance = mathop::Euclidian<byte, float>(key, m_key) + 0.5f;
40  if (distance < searchRadius) {
41  if (nearestNeighbors.size() < maxNeighbors) nearestNeighbors.push_back(shared_from_this());
42  else nearestNeighbors.back() = shared_from_this();
43 
44  // Sort the nodes
45  float distTo_i = mathop::Euclidian<byte, float>(key, nearestNeighbors.back()->m_key);
46  for (size_t i = nearestNeighbors.size() - 1; i > 0; i--) {
47  float distTo_p = mathop::Euclidian<byte, float>(key, nearestNeighbors[i - 1]->m_key);
48  if (distTo_p <= distTo_i) break;
49  std::swap(nearestNeighbors[i - 1], nearestNeighbors[i]);
50  }
51 
52  if (nearestNeighbors.size() == maxNeighbors) {
53  searchRadius = (maxNeighbors == 1) ? distance : mathop::Euclidian<byte, float>(key, nearestNeighbors.back()->m_key) + 0.5f;
54  searchBox.first = key - searchRadius;
55  searchBox.second = key + searchRadius;
56  }
57  } // if distance
58  } else { // --- Branch node ---
59  // if (mathop::ifOverlap<byte>(m_pLeft->getBoundingBox(), searchBox))
60  if (mathop::ifOverlap<byte>(m_pLeft->m_boundingBox, searchBox))
61  m_pLeft->findNearestNeighbors(key, maxNeighbors, searchBox, searchRadius, nearestNeighbors);
62  // if (mathop::ifOverlap<byte>(m_pRight->getBoundingBox(), searchBox))
63  if (mathop::ifOverlap<byte>(m_pRight->m_boundingBox, searchBox))
64  m_pRight->findNearestNeighbors(key, maxNeighbors, searchBox, searchRadius, nearestNeighbors);
65  }
66  }
67 }
std::shared_ptr< CKDNode > m_pRight
Definition: KDNode.h:116
std::shared_ptr< CKDNode > m_pLeft
Definition: KDNode.h:115
CKDNode(Mat &key, byte value)
Leaf node constructor.
Definition: KDNode.h:25
bool isLeaf(void) const
Checks whether the node is either leaf or brach node.
Definition: KDNode.h:56
void findNearestNeighbors(const Mat &key, size_t maxNeighbors, pair_mat_t &searchBox, float &searchRadius, std::vector< std::shared_ptr< const CKDNode >> &nearestNeighbors) const
Auxiliary recursive method for finding the k-nearest (in terms of the Euclidian distance between the ...
Definition: KDNode.cpp:36
void save(FILE *pFile) const
Saves the state of the node to the file.
Definition: KDNode.cpp:18