27#include <QElapsedTimer>
47 recognizeModel(recModel)
51 for (
int i = 0 ; i < 1 ; ++i)
53 switch (recognizeModel)
55 case FaceScanSettings::FaceRecognitionModel::OpenFace:
61 case FaceScanSettings::FaceRecognitionModel::SFace:
69 qCritical(DIGIKAM_DPLUGIN_GENERIC_LOG) <<
"OpenCVDNNFaceRecognizer::Private() Unknown recognition model specified" << Qt::endl;
79 svm = cv::ml::SVM::create();
80 svm->setKernel(cv::ml::SVM::LINEAR);
86 knn = cv::ml::KNearest::create();
87 knn->setAlgorithmType(cv::ml::KNearest::BRUTE_FORCE);
88 knn->setIsClassifier(
true);
111 qFatal(
"Invalid classifier");
118 QVector<DNNFaceExtractorBase*>::iterator extractor = extractors.begin();
120 while (extractor != extractors.end())
123 extractor = extractors.erase(extractor);
134 int predictSVM(
const cv::Mat& faceEmbedding);
135 int predictKNN(
const cv::Mat& faceEmbedding);
137 int predictKDTree(
const cv::Mat& faceEmbedding)
const;
138 int predictDb(
const cv::Mat& faceEmbedding)
const;
141 bool insertData(
const cv::Mat& position,
const int label,
const QString& context = QString());
151 cv::Ptr<cv::ml::KNearest>
knn;
160 bool newDataAdded =
true;
175 const QList<QPair<QImage*, QString> >& images,
181 ids.resize(images.size());
186 for(
int i = range.start ; i < range.end ; ++i)
221 qCWarning(DIGIKAM_FACEDB_LOG) <<
"Not recognized classifying method";
232 const QList<QPair<QImage*, QString> >& images;
247 const QList<QPair<QImage*,
258 for(
int i = range.start ; i < range.end ; ++i)
263 if (!d->
insertData(faceEmbedding,
id, images[i].second))
265 qCWarning(DIGIKAM_FACEDB_LOG) <<
"Fail to register a face of identity" << id;
272 const QList<QPair<QImage*, QString> >& images;
289 qCDebug(DIGIKAM_FACEDB_LOG) <<
"Support vector machine trains in" << timer.elapsed() <<
"ms";
291 return (
svm->isTrained());
301 qCDebug(DIGIKAM_FACEDB_LOG) <<
"KNN trains in" << timer.elapsed() <<
"ms";
303 return (knn->isTrained());
315 newDataAdded =
false;
318 return (
int(svm->predict(faceEmbedding)));
330 newDataAdded =
false;
334 knn->findNearest(faceEmbedding, kNeighbors, output);
336 return (
int(output.at<
float>(0)));
351 DNNModelUsage::DNNUsageFaceRecognition)->
getThreshold(uiThreshold);
356 DNNModelUsage::DNNUsageFaceRecognition)->
getThreshold(uiThreshold);
361 QMap<double, QVector<int> > closestNeighbors = tree->getClosestNeighbors(faceEmbedding, threshold, kNeighbors);
363 QMap<int, QVector<double> > votingGroups;
365 for (QMap<
double, QVector<int> >::const_iterator iter = closestNeighbors.cbegin();
366 iter != closestNeighbors.cend();
369 for (QVector<int>::const_iterator node = iter.value().cbegin();
370 node != iter.value().cend();
375 votingGroups[label].append(iter.key());
379 double maxScore = 0.0;
382 for (QMap<
int, QVector<double> >::const_iterator group = votingGroups.cbegin();
383 group != votingGroups.cend();
388 for (
int i = 0 ; i < group.value().size() ; ++i)
390 score += (threshold - group.value()[i]);
393 if (score > maxScore)
396 prediction = group.key();
410 DNNModelUsage::DNNUsageFaceRecognition)->
getThreshold(uiThreshold);
415 DNNModelUsage::DNNUsageFaceRecognition)->
getThreshold(uiThreshold);
420 QMap<int, QVector<double> > votingGroups;
422 for (QMap<
double, QVector<int> >::const_iterator iter = closestNeighbors.cbegin();
423 iter != closestNeighbors.cend();
426 for (
int i = 0 ; i < iter.value().size() ; ++i)
428 votingGroups[iter.value()[i]].append(iter.key());
432 double maxScore = 0.0;
435 for (QMap<
int, QVector<double> >::const_iterator group = votingGroups.cbegin();
436 group != votingGroups.cend();
441 for (
int i = 0 ; i < group.value().size() ; ++i)
443 score += (threshold - group.value()[i]);
446 if (score > maxScore)
449 prediction = group.key();
458 if (nodePos.rows != 1)
460 qCWarning(DIGIKAM_FACEDB_LOG) <<
"Error face embedding not valid";
469 qCWarning(DIGIKAM_FACEDB_LOG) <<
"Error inserting face embedding to database";
474 if (!
FaceDbAccess().db()->insertToTreeDb(nodeId, nodePos))
476 qCWarning(DIGIKAM_FACEDB_LOG) <<
"Error insert face embedding";
481 else if (method ==
Tree)
483 KDNodeBase*
const newNode = tree->add(nodePos, label);
491 qCWarning(DIGIKAM_FACEDB_LOG) <<
"Error insert new node" << nodeId;
float getThreshold(int uiThreshold=DNN_MODEL_THRESHOLD_NOT_SET) const
Definition dnnmodelbase.cpp:137
static DNNModelManager * instance()
Definition dnnmodelmanager.cpp:77
DNNModelBase * getModel(const QString &modelName, DNNModelUsage usage) const
Definition dnnmodelmanager.cpp:99
Definition facedbaccess.h:35
FaceDb * db() const
Definition facedbaccess.cpp:131
KDTreeBase * reconstructTree(FaceScanSettings::FaceRecognitionModel recModel)
reconstructTree: reconstruct KD-Tree from data in the database.
Definition facedb_dnn.cpp:79
QMap< double, QVector< int > > getClosestNeighborsTreeDb(const cv::Mat &position, float sqRange, float cosThreshold, int maxNbNeighbors) const
getClosestNeighborsTreeDb: return a list of closest neighbor, limited by maxNbNeighbors and sqRange.
Definition facedb_dnn_spatial.cpp:106
int insertFaceVector(const cv::Mat &faceEmbedding, const int label, const QString &context) const
insertFaceVector: insert a new face embedding to database.
Definition facedb_dnn.cpp:28
FaceRecognitionModel
Definition facescansettings.h:89
@ SFace
SFace pre-trained neural network model [https://github.com/opencv/opencv_zoo/blob/main/models/face_re...
Definition facescansettings.h:91
Definition kd_nodebase.h:34
void setNodeId(int id)
Definition kd_nodebase.cpp:189
Definition kd_treebase.h:44
Definition opencvdnnfacerecognizer_p.h:171
void operator()(const cv::Range &range) const override
Definition opencvdnnfacerecognizer_p.h:184
ParallelRecognizer(OpenCVDNNFaceRecognizer::Private *const d, const QList< QPair< QImage *, QString > > &images, QVector< int > &ids)
Definition opencvdnnfacerecognizer_p.h:174
Definition opencvdnnfacerecognizer_p.h:243
ParallelTrainer(OpenCVDNNFaceRecognizer::Private *const d, const QList< QPair< QImage *, QString > > &images, const int &id)
Definition opencvdnnfacerecognizer_p.h:246
void operator()(const cv::Range &range) const override
Definition opencvdnnfacerecognizer_p.h:256
Definition opencvdnnfacerecognizer_p.h:42
int predictKDTree(const cv::Mat &faceEmbedding) const
Definition opencvdnnfacerecognizer_p.h:339
Classifier method
Definition opencvdnnfacerecognizer_p.h:147
QVector< DNNFaceExtractorBase * > extractors
Definition opencvdnnfacerecognizer_p.h:149
int predictSFace(const cv::Mat &faceEmbedding) const
~Private()
Definition opencvdnnfacerecognizer_p.h:116
cv::Ptr< cv::ml::SVM > svm
Definition opencvdnnfacerecognizer_p.h:150
int predictDb(const cv::Mat &faceEmbedding) const
Definition opencvdnnfacerecognizer_p.h:403
cv::Ptr< cv::ml::KNearest > knn
Definition opencvdnnfacerecognizer_p.h:151
int predictKNN(const cv::Mat &faceEmbedding)
Definition opencvdnnfacerecognizer_p.h:321
int predictSVM(const cv::Mat &faceEmbedding)
Definition opencvdnnfacerecognizer_p.h:306
bool insertData(const cv::Mat &position, const int label, const QString &context=QString())
Definition opencvdnnfacerecognizer_p.h:456
bool trainSVM()
Definition opencvdnnfacerecognizer_p.h:282
bool trainKNN()
Definition opencvdnnfacerecognizer_p.h:294
Private(Classifier mthd, FaceScanSettings::FaceRecognitionModel recModel)
Definition opencvdnnfacerecognizer_p.h:45
Definition opencvdnnfacerecognizer.h:34
static cv::Mat prepareForRecognition(QImage &inputImage)
Definition opencvdnnfacerecognizer.cpp:57
Classifier
Definition opencvdnnfacerecognizer.h:38
@ OpenCV_KNN
K-Nearest Neighbors (https://docs.opencv.org/4.x/dc/dd6/ml_intro.html#ml_intro_knn)
Definition opencvdnnfacerecognizer.h:40
@ DB
Closest Neighbors Tree from the database.
Definition opencvdnnfacerecognizer.h:42
@ Tree
K-Nearest Neighbors Tree (https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm)
Definition opencvdnnfacerecognizer.h:41
@ SVM
Support Vector Machines (https://docs.opencv.org/4.x/dc/dd6/ml_intro.html#ml_intro_svm)
Definition opencvdnnfacerecognizer.h:39
Definition datefolderview.cpp:34
const int DNN_MODEL_THRESHOLD_NOT_SET
Definition dnnmodeldefinitions.h:43