44 #ifndef __cv_kdtree_h__
45 #define __cv_kdtree_h__
60 template <
class __valuetype,
class __deref >
74 typedef std::vector < node > node_array;
83 template <
class __instype,
class __valuector >
84 int dimension_of_highest_variance(__instype *
first, __instype * last,
88 accum_type maxvar = -std::numeric_limits < accum_type >::max();
90 for (
int j = 0;
j < point_dim; ++
j) {
92 for (__instype *
k = first;
k < last; ++
k)
93 mean += deref(ctor(*
k),
j);
96 for (__instype *
k = first;
k < last; ++
k) {
102 assert(maxj != -1 || var >= maxvar);
116 template <
class __instype,
class __valuector >
117 __instype * median_partition(__instype * first, __instype * last,
118 int dim, __valuector ctor) {
120 __instype *
k = first + (last -
first) / 2;
121 median_partition(first, last, k, dim, ctor);
125 template <
class __instype,
class __valuector >
127 const __instype & pivot;
131 median_pr(
const __instype & _pivot,
int _dim, __deref _deref, __valuector _ctor)
132 : pivot(_pivot), dim(_dim), deref(_deref), ctor(_ctor) {
134 bool operator() (
const __instype & lhs)
const {
135 return deref(ctor(lhs), dim) <= deref(ctor(pivot), dim);
139 template <
class __instype,
class __valuector >
140 void median_partition(__instype * first, __instype * last,
141 __instype *
k,
int dim, __valuector ctor) {
142 int pivot = (last -
first) / 2;
144 std::swap(first[pivot], last[-1]);
145 __instype *middle = std::partition(first, last - 1,
146 median_pr < __instype, __valuector >
147 (last[-1], dim, deref, ctor));
148 std::swap(*middle, last[-1]);
151 median_partition(middle + 1, last, k, dim, ctor);
153 median_partition(first, middle, k, dim, ctor);
157 template <
class __instype,
class __valuector >
158 int insert(__instype * first, __instype * last, __valuector ctor) {
163 int dim = dimension_of_highest_variance(first, last, ctor);
164 __instype *median = median_partition(first, last, dim, ctor);
166 __instype *split = median;
167 for (; split != last && deref(ctor(*split), dim) ==
168 deref(ctor(*median), dim); ++split);
172 for (--split; split >=
first; --split) {
173 int i = nodes.size();
174 node &
n = *nodes.insert(nodes.end(),
node());
176 n.value = ctor(*split);
184 int i = nodes.size();
186 node &
n = *nodes.insert(nodes.end(),
node());
189 n.boundary = deref(ctor(*median), dim);
191 int left = insert(first, split, ctor);
192 nodes[
i].left = left;
193 int right = insert(split, last, ctor);
203 bool remove(
int *
i,
const __valuetype & p) {
210 if (deref(p, n.dim) <= n.boundary)
211 r =
remove(&n.left, p);
213 r =
remove(&n.right, p);
216 if (n.left == -1 && n.right == -1)
225 return remove(&n.right, p);
231 const __valuetype &
operator() (
const __valuetype & rhs)
const {
238 : deref(_deref), root_node(-1) {
241 CvKDTree(__valuetype * first, __valuetype * last,
int _point_dim,
242 __deref _deref = __deref())
247 template <
class __instype,
class __valuector >
248 CvKDTree(__instype * first, __instype * last,
int _point_dim,
249 __valuector ctor, __deref _deref = __deref())
251 set_data(first, last, _point_dim, ctor);
258 void set_data(__valuetype * first, __valuetype * last,
int _point_dim) {
261 template <
class __instype,
class __valuector >
262 void set_data(__instype * first, __instype * last,
int _point_dim,
264 point_dim = _point_dim;
266 nodes.reserve(last - first);
267 root_node = insert(first, last, ctor);
275 bool remove(
const __valuetype & p) {
276 return remove(&root_node, p);
282 void print(
int i,
int indent = 0)
const {
285 for (
int j = 0;
j < indent; ++
j)
287 const node & n = nodes[
i];
289 std::cout <<
"node " << i <<
", left " << nodes[
i].left <<
", right " <<
290 nodes[
i].right <<
", dim " << nodes[
i].dim <<
", boundary " <<
291 nodes[
i].boundary << std::endl;
292 print(n.left, indent + 3);
293 print(n.right, indent + 3);
295 std::cout <<
"leaf " << i <<
", value = " << nodes[
i].value << std::endl;
302 const __valuetype *
p;
305 :
p(&_p),
dist(_dist) {
319 bool operator<(
const bbf_node & rhs)
const {
320 return dist > rhs.dist;
323 typedef std::vector < bbf_node > bbf_pqueue;
324 mutable bbf_pqueue tmp_pq;
328 void pq_alternate(
int alt_n, bbf_pqueue & pq,
scalar_type dist)
const {
333 pq.push_back(bbf_node(alt_n, dist));
334 push_heap(pq.begin(), pq.end());
339 template <
class __desctype >
340 int bbf_branch(
int i,
const __desctype * d, bbf_pqueue & pq)
const {
341 const node & n = nodes[
i];
343 if (d[n.dim] <= n.boundary) {
344 pq_alternate(n.right, pq, n.boundary - d[n.dim]);
347 pq_alternate(n.left, pq, d[n.dim] - n.boundary);
353 template <
class __desctype >
354 accum_type distance(
const __desctype * d,
const __valuetype & p)
const {
356 for (
int j = 0;
j < point_dim; ++
j) {
365 template <
class __desctype >
367 const __desctype * d,
const __valuetype & p)
const {
368 bbf_nn nn(p, distance(d, p));
369 if ((
int) nn_pq.size() <
k) {
371 push_heap(nn_pq.begin(), nn_pq.end());
372 }
else if (nn_pq[0].dist > nn.dist) {
373 pop_heap(nn_pq.begin(), nn_pq.end());
374 nn_pq.end()[-1] = nn;
375 push_heap(nn_pq.begin(), nn_pq.end());
377 assert(nn_pq.size() < 2 || nn_pq[0].dist >= nn_pq[1].dist);
385 template <
class __desctype >
398 tmp_pq.push_back(bbf_node(root_node, 0));
399 while (tmp_pq.size() && emax > 0) {
402 pop_heap(tmp_pq.begin(), tmp_pq.end());
403 bbf_node bbf(tmp_pq.end()[-1]);
404 tmp_pq.erase(tmp_pq.end() - 1);
408 i != -1 && nodes[i].dim >= 0;
409 i = bbf_branch(i, d, tmp_pq));
415 bbf_new_nn(ret_nn_pq, k, d, nodes[i].
value);
416 }
while (-1 != (i = nodes[i].
right));
423 return ret_nn_pq.size();
431 std::vector < __valuetype > &inbounds)
const {
434 const node & n = nodes[
i];
436 if (bounds_min[n.dim] <= n.boundary)
437 find_ortho_range(n.left, bounds_min, bounds_max, inbounds);
438 if (bounds_max[n.dim] > n.boundary)
439 find_ortho_range(n.right, bounds_min, bounds_max, inbounds);
442 inbounds.push_back(nodes[i].
value);
443 }
while (-1 != (i = nodes[i].
right));
450 std::vector < __valuetype > &inbounds)
const {
452 find_ortho_range(root_node, bounds_min, bounds_max, inbounds);
453 return inbounds.size();
457 #endif // __cv_kdtree_h__