File indexing completed on 2025-03-09 03:55:01

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam
0004  *
0005  * Date        : 2019-06-08
0006  * Description : Implementation of KD-Tree for vector space partitioning
0007  *
0008  * SPDX-FileCopyrightText: 2020 by Nghia Duong <minhnghiaduong997 at gmail dot com>
0009  *
0010  * SPDX-License-Identifier: GPL-2.0-or-later
0011  *
0012  * ============================================================ */
0013 
0014 #include "kd_tree.h"
0015 
0016 // Qt includes
0017 
0018 #include <QMutex>
0019 
0020 namespace Digikam
0021 {
0022 
0023 class Q_DECL_HIDDEN KDTree::Private
0024 {
0025 
0026 public:
0027 
0028     Private(int dim)
0029         : nbDimension   (dim),
0030           root          (nullptr)
0031     {
0032     }
0033 
0034     ~Private()
0035     {
0036         delete root;
0037     }
0038 
0039 public:
0040 
0041     int     nbDimension;
0042     KDNode* root;
0043     QMutex  mutex;
0044 };
0045 
0046 KDTree::KDTree(int dim)
0047     : d(new Private(dim))
0048 {
0049 }
0050 
0051 KDTree::~KDTree()
0052 {
0053     delete d;
0054 }
0055 
0056 KDNode* KDTree::add(const cv::Mat& position, const int identity)
0057 {
0058     KDNode* newNode = nullptr;
0059 
0060     d->mutex.lock();
0061     {
0062         if (d->root == nullptr)
0063         {
0064             d->root = new KDNode(position, identity, 0, d->nbDimension);
0065 
0066             newNode = d->root;
0067         }
0068         else
0069         {
0070             newNode = d->root->insert(position, identity);
0071         }
0072     }
0073     d->mutex.unlock();
0074 
0075     return newNode;
0076 }
0077 
0078 QMap<double, QVector<int> > KDTree::getClosestNeighbors(const cv::Mat& position,
0079                                                         float sqRange,
0080                                                         float cosThreshold,
0081                                                         int maxNbNeighbors) const
0082 {
0083     QMap<double, QVector<int> > closestNeighbors;
0084 
0085     if (d->root)
0086     {
0087         d->root->getClosestNeighbors(closestNeighbors, position, sqRange, cosThreshold, maxNbNeighbors);
0088     }
0089 
0090     return closestNeighbors;
0091 }
0092 
0093 } // namespace Digikam