File indexing completed on 2025-03-09 03:54:59

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam
0004  *
0005  * Date        : 02-02-2012
0006  * Description : Face database interface to train identities.
0007  *
0008  * SPDX-FileCopyrightText: 2012-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0009  * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText:      2020 by Nghia Duong <minhnghiaduong997 at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #ifndef DIGIKAM_FACE_DB_H
0017 #define DIGIKAM_FACE_DB_H
0018 
0019 // C++ includes
0020 
0021 #include <vector>
0022 
0023 // Qt includes
0024 
0025 #include <QString>
0026 #include <QFile>
0027 #include <QDataStream>
0028 #include <QStandardPaths>
0029 
0030 // Local includes
0031 
0032 #include "digikam_config.h"
0033 #include "digikam_opencv.h"
0034 #include "identity.h"
0035 #include "facedbbackend.h"
0036 
0037 namespace Digikam
0038 {
0039 
0040 class KDTree;
0041 
0042 class FaceDb
0043 {
0044 public:
0045 
0046     explicit FaceDb(FaceDbBackend* const db);
0047     ~FaceDb();
0048 
0049     BdEngineBackend::QueryState setSetting(const QString& keyword, const QString& value);
0050     QString setting(const QString& keyword)                                     const;
0051 
0052     /**
0053      * Returns true if the integrity of the database is preserved.
0054      */
0055     bool integrityCheck();
0056 
0057     /**
0058      * Shrinks the database.
0059      */
0060     void vacuum();
0061 
0062 public:
0063 
0064     // --- Identity management (facedb_identity.cpp)
0065 
0066     int  addIdentity()                                                          const;
0067     int  getNumberOfIdentities()                                                const;
0068 
0069     void updateIdentity(const Identity& p);
0070     void deleteIdentity(int id);
0071     void deleteIdentity(const QString& uuid);
0072     void clearIdentities();
0073 
0074     QList<Identity> identities()                                                const;
0075     QList<int>      identityIds()                                               const;
0076 
0077 public:
0078 
0079     // --- OpenCV DNN
0080 
0081     /**
0082      * @brief insertFaceVector : insert a new face embedding to database
0083      * @param faceEmbedding
0084      * @param label
0085      * @return id of newly inserted entry
0086      */
0087     int insertFaceVector(const cv::Mat& faceEmbedding,
0088                          const int label,
0089                          const QString& context)                                const;
0090 
0091     /**
0092      * @brief reconstructTree: reconstruct KD-Tree from data in the database
0093      * @return
0094      */
0095     KDTree* reconstructTree()                                                   const;
0096 
0097     /**
0098      * @brief trainData: extract train data from database
0099      * @return
0100      */
0101     cv::Ptr<cv::ml::TrainData> trainData()                                      const;
0102 
0103     /**
0104      * @brief insertToTreeDb : insert a new node to spatial database
0105      * @param nodeID
0106      * @param label
0107      * @param faceEmbedding
0108      * @return true if successed
0109      */
0110     bool insertToTreeDb(const int nodeID,
0111                         const cv::Mat& faceEmbedding)                           const;
0112 
0113     /**
0114      * @brief getClosestNeighbors : return a list of closest neighbor, limited by maxNbNeighbors and sqRange
0115      * @param subTree
0116      * @param neighborList
0117      * @param position
0118      * @param sqRange
0119      * @param cosThreshold
0120      * @param maxNbNeighbors
0121 
0122      * @return
0123      */
0124     QMap<double, QVector<int> > getClosestNeighborsTreeDb(const cv::Mat& position,
0125                                                           float sqRange,
0126                                                           float cosThreshold,
0127                                                           int maxNbNeighbors)   const;
0128 
0129     void clearTreeDb()                                                          const;
0130 
0131     /**
0132      * @brief clearDNNTraining : clear all trained data in the database
0133      * @param context
0134      */
0135     void clearDNNTraining(const QString& context = QString());
0136     void clearDNNTraining(const QList<int>& identities, const QString& context = QString());
0137 
0138 private:
0139 
0140     void updateRangeTreeDb(int nodeId,
0141                            cv::Mat& minRange,
0142                            cv::Mat& maxRange,
0143                            const cv::Mat& position)                             const;
0144     int findParentTreeDb(const cv::Mat& nodePos,
0145                          bool& leftChild,
0146                          int& parentSplitAxis)                                  const;
0147 
0148     class DataNode;
0149 
0150     /**
0151      * @brief getClosestNeighborsTreeDb : return a list of closest neighbor from a sub tree, limited by maxNbNeighbors and sqRange
0152      * @param subTree
0153      * @param neighborList
0154      * @param position
0155      * @param sqRange
0156      * @param cosThreshold
0157      * @param maxNbNeighbors
0158 
0159      * @return
0160      */
0161     double getClosestNeighborsTreeDb(const DataNode& subTree,
0162                                      QMap<double, QVector<int> >& neighborList,
0163                                      const cv::Mat& position,
0164                                      float sqRange,
0165                                      float cosThreshold,
0166                                      int maxNbNeighbors)                        const;
0167 
0168 private:
0169 
0170     // Disable
0171     FaceDb(const FaceDb&)            = delete;
0172     FaceDb& operator=(const FaceDb&) = delete;
0173 
0174 private:
0175 
0176     class Private;
0177     Private* const d;
0178 };
0179 
0180 } // namespace Digikam
0181 
0182 #endif // DIGIKAM_FACE_DB_H