File indexing completed on 2025-03-09 03:55:01
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam 0004 * 0005 * Date : 2010-06-16 0006 * Description : Training functions of recognition wrapper 0007 * 0008 * SPDX-FileCopyrightText: 2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0009 * SPDX-FileCopyrightText: 2010 by Aditya Bhatt <adityabhatt1991 at gmail dot com> 0010 * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2019 by Thanh Trung Dinh <dinhthanhtrung1996 at gmail dot com> 0012 * SPDX-FileCopyrightText: 2020 by Nghia Duong <minhnghiaduong997 at gmail dot com> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "facialrecognition_wrapper_p.h" 0019 0020 namespace Digikam 0021 { 0022 0023 void FacialRecognitionWrapper::Private::trainIdentityBatch(const QList<Identity>& identitiesToBeTrained, 0024 TrainingDataProvider* const data, 0025 const QString& trainingContext) 0026 { 0027 Q_FOREACH (const Identity& identity, identitiesToBeTrained) 0028 { 0029 ImageListProvider* const imageList = data->newImages(identity); 0030 QList<QImage*> images = imageList->images(); 0031 0032 qCDebug(DIGIKAM_FACESENGINE_LOG) << "Training" << images.size() << "images for identity" << identity.id(); 0033 0034 try 0035 { 0036 recognizer->train(images, identity.id(), trainingContext); 0037 } 0038 catch (cv::Exception& e) 0039 { 0040 qCCritical(DIGIKAM_FACESENGINE_LOG) << "cv::Exception training Recognizer:" << e.what(); 0041 } 0042 catch (...) 0043 { 0044 qCCritical(DIGIKAM_FACESENGINE_LOG) << "Default exception from OpenCV"; 0045 } 0046 } 0047 } 0048 0049 void FacialRecognitionWrapper::Private::clear(const QList<int>& idsToClear, const QString& trainingContext) 0050 { 0051 recognizer->clearTraining(idsToClear, trainingContext); 0052 0053 delete recognizer; 0054 0055 recognizer = new OpenCVDNNFaceRecognizer(OpenCVDNNFaceRecognizer::Tree); 0056 } 0057 0058 // ------------------------------------------------------------------------------------- 0059 0060 void FacialRecognitionWrapper::train(const QList<Identity>& identitiesToBeTrained, 0061 TrainingDataProvider* const data, 0062 const QString& trainingContext) 0063 { 0064 if (!d || !d->dbAvailable) 0065 { 0066 return; 0067 } 0068 0069 QMutexLocker lock(&d->mutex); 0070 0071 d->trainIdentityBatch(identitiesToBeTrained, data, trainingContext); 0072 } 0073 0074 void FacialRecognitionWrapper::train(const Identity& identityToBeTrained, 0075 TrainingDataProvider* const data, 0076 const QString& trainingContext) 0077 { 0078 train((QList<Identity>() << identityToBeTrained), data, trainingContext); 0079 } 0080 0081 void FacialRecognitionWrapper::train(const Identity& identityToBeTrained, 0082 QImage* image, 0083 const QString& trainingContext) 0084 { 0085 RecognitionTrainingProvider* const data = new RecognitionTrainingProvider(identityToBeTrained, 0086 QList<QImage*>() << image); 0087 train(identityToBeTrained, data, trainingContext); 0088 delete data; 0089 } 0090 0091 void FacialRecognitionWrapper::train(const Identity& identityToBeTrained, 0092 const QList<QImage*>& images, 0093 const QString& trainingContext) 0094 { 0095 RecognitionTrainingProvider* const data = new RecognitionTrainingProvider(identityToBeTrained, images); 0096 train(identityToBeTrained, data, trainingContext); 0097 delete data; 0098 } 0099 0100 // ------------------------------------------------------------------------------------- 0101 0102 void FacialRecognitionWrapper::clearAllTraining(const QString& trainingContext) 0103 { 0104 if (!d || !d->dbAvailable) 0105 { 0106 return; 0107 } 0108 0109 QMutexLocker lock(&d->mutex); 0110 0111 d->identityCache.clear(); 0112 FaceDbAccess().db()->clearIdentities(); 0113 0114 d->clear(QList<int>(), trainingContext); 0115 } 0116 0117 void FacialRecognitionWrapper::clearTraining(const QList<Identity>& identitiesToClean, 0118 const QString& trainingContext) 0119 { 0120 if (!d || !d->dbAvailable || identitiesToClean.isEmpty()) 0121 { 0122 return; 0123 } 0124 0125 QMutexLocker lock(&d->mutex); 0126 QList<int> ids; 0127 0128 Q_FOREACH (const Identity& id, identitiesToClean) 0129 { 0130 ids << id.id(); 0131 } 0132 0133 d->clear(ids, trainingContext); 0134 } 0135 0136 } // namespace Digikam