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 face recognizer. 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: 2019 by Thanh Trung Dinh <dinhthanhtrung1996 at gmail dot com> 0011 * SPDX-FileCopyrightText: 2020 by Nghia Duong <minhnghiaduong997 at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "facedb_p.h" 0018 0019 namespace Digikam 0020 { 0021 0022 int FaceDb::insertFaceVector(const cv::Mat& faceEmbedding, 0023 const int label, 0024 const QString& context) const 0025 { 0026 QVariantList bindingValues; 0027 0028 bindingValues << label; 0029 bindingValues << context; 0030 bindingValues << QByteArray::fromRawData((char*)faceEmbedding.ptr<float>(), (sizeof(float) * 128)); 0031 0032 DbEngineSqlQuery query = d->db->execQuery(QLatin1String("INSERT INTO FaceMatrices (identity, `context`, embedding) " 0033 "VALUES (?,?,?);"), 0034 bindingValues); 0035 0036 if (query.lastInsertId().isNull()) 0037 { 0038 qCWarning(DIGIKAM_FACEDB_LOG) << "fail to insert face embedding, last query" 0039 << query.lastQuery() 0040 << "bound values" << query.boundValues() 0041 << query.lastError(); 0042 } 0043 else 0044 { 0045 qCDebug(DIGIKAM_FACEDB_LOG) << "Commit face mat data " 0046 << query.lastInsertId().toInt() 0047 << " for identity " << label; 0048 } 0049 0050 return query.lastInsertId().toInt(); 0051 } 0052 0053 KDTree* FaceDb::reconstructTree() const 0054 { 0055 KDTree* const tree = new KDTree(128); 0056 DbEngineSqlQuery query = d->db->execQuery(QLatin1String("SELECT id, identity, embedding FROM FaceMatrices;")); 0057 0058 while (query.next()) 0059 { 0060 int nodeId = query.value(0).toInt(); 0061 int identity = query.value(1).toInt(); 0062 cv::Mat recordedFaceEmbedding = cv::Mat(1, 128, CV_32F, query.value(2).toByteArray().data()).clone(); 0063 KDNode* const newNode = tree->add(recordedFaceEmbedding, identity); 0064 0065 if (newNode) 0066 { 0067 newNode->setNodeId(nodeId); 0068 } 0069 else 0070 { 0071 qCWarning(DIGIKAM_FACEDB_LOG) << "Error insert node" << nodeId; 0072 } 0073 } 0074 0075 return tree; 0076 } 0077 0078 cv::Ptr<cv::ml::TrainData> FaceDb::trainData() const 0079 { 0080 cv::Mat feature, label; 0081 DbEngineSqlQuery query = d->db->execQuery(QLatin1String("SELECT identity, embedding " 0082 "FROM FaceMatrices;")); 0083 0084 while (query.next()) 0085 { 0086 label.push_back(query.value(0).toInt()); 0087 feature.push_back(cv::Mat(1, 128, CV_32F, query.value(1).toByteArray().data()).clone()); 0088 } 0089 0090 return cv::ml::TrainData::create(feature, 0, label); 0091 } 0092 0093 void FaceDb::clearDNNTraining(const QString& context) 0094 { 0095 if (context.isNull()) 0096 { 0097 d->db->execSql(QLatin1String("DELETE FROM FaceMatrices;")); 0098 } 0099 else 0100 { 0101 d->db->execSql(QLatin1String("DELETE FROM FaceMatrices WHERE `context`=?;"), 0102 context); 0103 } 0104 } 0105 0106 void FaceDb::clearDNNTraining(const QList<int>& identities, const QString& context) 0107 { 0108 Q_FOREACH (int id, identities) 0109 { 0110 if (context.isNull()) 0111 { 0112 d->db->execSql(QLatin1String("DELETE FROM FaceMatrices WHERE identity=?;"), 0113 id); 0114 } 0115 else 0116 { 0117 d->db->execSql(QLatin1String("DELETE FROM FaceMatrices WHERE identity=? AND `context`=?;"), 0118 id, context); 0119 } 0120 } 0121 } 0122 0123 } // namespace Digikam