1 /* ============================================================
2  *
3  * This file is a part of digiKam
4  *
5  * Date        : 2010-06-16
6  * Description : The recognition wrapper
7  *
8  * Copyright (C)      2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
9  * Copyright (C)      2010 by Aditya Bhatt <adityabhatt1991 at gmail dot com>
10  * Copyright (C) 2010-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11  * Copyright (C)      2020 by Nghia Duong <minhnghiaduong997 at gmail dot com>
12  *
13  * This program is free software; you can redistribute it
14  * and/or modify it under the terms of the GNU General
15  * Public License as published by the Free Software Foundation;
16  * either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * ============================================================ */
25 
26 #ifndef FACIAL_RECOGNITION_WRAPPER_H
27 #define FACIAL_RECOGNITION_WRAPPER_H
28 
29 // Qt includes
30 
31 #include <QExplicitlySharedDataPointer>
32 #include <QImage>
33 #include <QList>
34 #include <QMap>
35 #include <QVariant>
36 
37 // Local includes
38 
39 #include "digikam_export.h"
40 #include "identity.h"
41 #include "dataproviders.h"
42 
43 namespace Digikam
44 {
45 
46 class DIGIKAM_GUI_EXPORT FacialRecognitionWrapper
47 {
48 public:
49 
50     explicit FacialRecognitionWrapper();
51     FacialRecognitionWrapper(const FacialRecognitionWrapper&);
52 
53     ~FacialRecognitionWrapper();
54 
55 public:
56 
57     /**
58      * Checks the integrity and returns true if everything is fine.
59      */
60     bool integrityCheck();
61 
62     /**
63      * Shrinks the database.
64      */
65     void vacuum();
66 
67 public:
68 
69     // --- Backend parameters (facesengine_interface_setup.cpp) --------------------------
70     /**
71      * Tunes backend parameters.
72      * Available parameters:
73      * "accuracy", synonymous: "threshold", range: 0-1, type: float
74      * Determines recognition threshold, 0->accept very insecure recognitions, 1-> be very sure about a recognition.
75      *
76      * "k-nearest" : limit the number of nearest neighbors for KNN
77      */
78     void        setParameter(const QString& parameter, const QVariant& value);
79     void        setParameters(const QVariantMap& parameters);
80     QVariantMap parameters()                                                const;
81 
82     // --- Identity management (facesengine_interface_identity.cpp) -----------------------------------------
83 
84     /// NOTE: For the documentation of standard attributes, see identity.h
85 
86     /**
87      * Returns all identities known to the database
88      */
89     QList<Identity> allIdentities()                                         const;
90     Identity        identity(int id)                                        const;
91 
92     /**
93      * Finds the first identity with matching attribute - value.
94      * Returns a null identity if no match is found or attribute is empty.
95      */
96     Identity findIdentity(const QString& attribute, const QString& value)   const;
97 
98     /**
99      * Finds the identity matching the given attributes.
100      * Attributes are first checked with knowledge of their meaning.
101      * Secondly, all unknown attributes are used.
102      * Returns a null Identity if no match is possible or the map is empty.
103      */
104     Identity findIdentity(const QMap<QString, QString>& attributes)         const;
105 
106     /**
107      * Adds a new identity with the specified attributes.
108      * Please note that a UUID is automatically generated.
109      */
110     Identity addIdentity(const QMap<QString, QString>& attributes);
111 
112     /**
113      * This is the debug version of addIdentity, so the identity is only added
114      * to identityCache, but not into the recognition database.
115      */
116     Identity addIdentityDebug(const QMap<QString, QString>& attributes);
117 
118     /**
119      * Adds or sets, resp., the attributes of an identity.
120      */
121     void addIdentityAttributes(int id, const QMap<QString, QString>& attributes);
122     void addIdentityAttribute(int id, const QString& attribute, const QString& value);
123     void setIdentityAttributes(int id, const QMap<QString, QString>& attributes);
124 
125     /**
126      * Deletes an identity from the database.
127      */
128     void deleteIdentity(const Identity& identityToBeDeleted);
129 
130     /**
131      * Deletes a list of identities from the database.
132      */
133     void deleteIdentities(QList<Identity> identitiesToBeDeleted);
134 
135     // --- Faces Training management (facesengine_interface_training.cpp) ----------------------------------------------------
136     /**
137      * Performs training.
138      * The identities which have new images to be trained are given.
139      * An empty list means that all identities are checked.
140      *
141      * All needed data will be queried from the provider.
142      *
143      * An identifier for the current training context is given,
144      * which can identify the application or group of collections.
145      * (It is assumed that training from different contexts is based on
146      * non-overlapping collections of images. Keep it always constant for your app.)
147      */
148     void train(const QList<Identity>& identitiesToBeTrained,
149                TrainingDataProvider* const data,
150                const QString& trainingContext);
151     void train(const Identity& identityToBeTrained,
152                TrainingDataProvider* const data,
153                const QString& trainingContext);
154 
155     /**
156      * Performs training by using image data directly.
157      *
158      * These are convenience functions for simple setups.
159      * If you want good performance and/or a more versatile implementation, be sure to
160      * implement your own TrainingDataProvider and use one of the above functions.
161      */
162     void train(const Identity& identityToBeTrained,
163                QImage* image,
164                const QString& trainingContext);
165     void train(const Identity& identityToBeTrained,
166                const QList<QImage*>& images,
167                const QString& trainingContext);
168 
169     /**
170      * Deletes the training data for all identities,
171      * leaving the identities as such in the database.
172      */
173     void clearAllTraining(const QString& trainingContext = QString());
174 
175     /**
176      * Deletes the training data for the given identity,
177      * leaving the identity as such in the database.
178      */
179     void clearTraining(const QList<Identity>& identitiesToClean,
180                        const QString& trainingContext = QString());
181 
182     // --- Recognition management (facesengine_interface_recognize.cpp) -------------------
183 
184     /**
185      * Returns the recommended size if you want to scale face images for recognition.
186      * Larger images can be passed, but may be downscaled.
187      */
188     // TODO : review to see if this function is necessary
189     //int recommendedImageSize(const QSize& availableSize = QSize()) const;
190 
191     /**
192      * Performs recognition.
193      * The face details to be recognized are passed by the provider.
194      * For each entry in the provider, in 1-to-1 mapping,
195      * a recognized identity or the null identity is returned.
196      */
197     QList<Identity> recognizeFaces(ImageListProvider* const images);
198     QList<Identity> recognizeFaces(const QList<QImage*>& images);
199     Identity        recognizeFace(QImage* const image);
200 
201 private:
202 
203     // Disable
204     FacialRecognitionWrapper& operator=(const FacialRecognitionWrapper&) = delete;
205 
206 private:
207 
208     class Private;
209     static Private* d;
210 };
211 
212 } // namespace Digikam
213 
214 #endif // FACIAL_RECOGNITION_WRAPPER_H
215