Skip to content

Commit b5ffa1a

Browse files
committed
Server: better exception handling in DLIBWorker
1 parent 9b51b1b commit b5ffa1a

File tree

2 files changed

+127
-62
lines changed

2 files changed

+127
-62
lines changed

server/source/DLIBWorker/DLIBWorker.cpp

Lines changed: 120 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <QJsonDocument>
2525
#include <QJsonArray>
2626
#include <QJsonObject>
27+
#include <QQueue>
28+
2729
#include <vector>
2830

2931
#include "Client/Client.h"
@@ -57,6 +59,8 @@ DLIBWorker::DLIBWorker(class QSettings* config, const Settings *settings)
5759
m_numCrops = config->value(CONFIG_DLIB_NUMCROPS, CONFIG_DLIB_DEFAULT_NUMCROPS).toULongLong();
5860
config->endGroup();
5961

62+
QQueue<QString> logQueue;
63+
6064
QFile refFile(_refFile);
6165
if(refFile.open(QIODevice::ReadOnly))
6266
{
@@ -88,19 +92,21 @@ DLIBWorker::DLIBWorker(class QSettings* config, const Settings *settings)
8892
}
8993
}
9094
}
95+
else
96+
{
97+
logQueue << QString("Could not open the reference file %1 !").arg(_refFile);
98+
}
9199

92100
#ifdef TURBOJPEG_AVAILABLE
93101
QMetaObject::invokeMethod(this, [this]() {
94102
m_tjHandle = tjInitDecompress();
95103
}, Qt::QueuedConnection);
96104
#endif
97105

98-
QMetaObject::invokeMethod(this, [this]() {
99-
detector = get_frontal_face_detector();
100-
string landmarkModel = m_faceLandmarkModelFile.toStdString();
101-
string recogModel = m_faceRecognitionModelFile.toStdString();
102-
deserialize(landmarkModel) >> sp;
103-
deserialize(recogModel) >> net;
106+
QMetaObject::invokeMethod(this, [this, logQueue]() mutable {
107+
while (!logQueue.isEmpty())
108+
emit log(logQueue.dequeue());
109+
104110
}, Qt::QueuedConnection);
105111
}
106112

@@ -332,7 +338,7 @@ std::vector<DLIBWorker::Cluster> DLIBWorker::cluster(const std::vector<sample_pa
332338
return clusters;
333339
}
334340

335-
void DLIBWorker::setupReference(const QVector<QPair<QString, QString>>& list)
341+
void DLIBWorker::resolveReferenceFaces(const QVector<QPair<QString, QString>>& list)
336342
{
337343
for(const auto& it : list)
338344
{
@@ -350,11 +356,66 @@ void DLIBWorker::setupReference(const QVector<QPair<QString, QString>>& list)
350356
}
351357
}
352358

353-
void DLIBWorker::setupImageNet()
359+
bool DLIBWorker::initFaceRecognition()
354360
{
355-
deserialize(m_imageNetClassifierFile.toStdString()) >> net2 >> labels;
361+
try
362+
{
363+
emit log(QString("Initializing face recognition..."));
364+
365+
string landmarkModel = m_faceLandmarkModelFile.toStdString();
366+
string recogModel = m_faceRecognitionModelFile.toStdString();
367+
deserialize(landmarkModel) >> sp;
368+
deserialize(recogModel) >> net;
356369

357-
snet.subnet() = net2.subnet();
370+
detector = get_frontal_face_detector();
371+
372+
emit log(QString("Successfully initialized face recognition!"));
373+
374+
emit log(QString("Resolving reference faces..."));
375+
resolveReferenceFaces(m_refPhotoFileList);
376+
377+
if(referenceFaces.size() == 0)
378+
{
379+
emit log("WARNING: Reference face list is empty!");
380+
}
381+
382+
m_faceRecognitionInitialized = true;
383+
}
384+
catch (const std::exception& e)
385+
{
386+
std::cerr << e.what() << std::endl;
387+
388+
emit log(QString("Could not parse the face landmark and/or recognition model files. Reason: %1").arg(e.what()));
389+
emit log(QString("Could not initialize face recognition. Face recognition will not work!"));
390+
391+
m_faceRecognitionInitialized = false;
392+
};
393+
394+
return m_faceRecognitionInitialized;
395+
}
396+
397+
bool DLIBWorker::initObjectRecognition()
398+
{
399+
try
400+
{
401+
deserialize(m_imageNetClassifierFile.toStdString()) >> net2 >> labels;
402+
snet.subnet() = net2.subnet();
403+
404+
emit log(QString("Successfully initialized object recognition!"));
405+
406+
m_objectRecognitionInitialized = true;
407+
}
408+
catch (const std::exception& e)
409+
{
410+
std::cerr << e.what() << std::endl;
411+
412+
emit log(QString("Could not parse the ImageNet classifier file. Reason: %1").arg(e.what()));
413+
emit log(QString("Could not initialize object recognition. Object recognition will not work!"));
414+
415+
m_objectRecognitionInitialized = false;
416+
}
417+
418+
return m_objectRecognitionInitialized;
358419
}
359420

360421
void DLIBWorker::process(const QByteArray& buffer)
@@ -374,78 +435,77 @@ void DLIBWorker::process(const QByteArray& buffer)
374435
return;
375436
}
376437

377-
if (m_settings->objectDetectionEnabled)
378-
{
379-
if (labels.empty())
438+
[&]() {
439+
if (m_settings->objectDetectionEnabled)
380440
{
381-
setupImageNet();
382-
}
441+
if (!m_objectRecognitionInitialized)
442+
{
443+
if (! initObjectRecognition() )
444+
return;
445+
}
383446

384-
matrix<rgb_pixel> crop;
385-
dlib::array<matrix<rgb_pixel>> images;
386-
matrix<rgb_pixel> imgMat = mat(img);
447+
matrix<rgb_pixel> crop;
448+
dlib::array<matrix<rgb_pixel>> images;
449+
matrix<rgb_pixel> imgMat = mat(img);
387450

388-
if (m_settings->deterministicObjectDetection)
389-
crop_images(imgMat, images, nullptr, m_numCrops);
390-
else
391-
crop_images(imgMat, images, &rnd, m_numCrops);
451+
if (m_settings->deterministicObjectDetection)
452+
crop_images(imgMat, images, nullptr, m_numCrops);
453+
else
454+
crop_images(imgMat, images, &rnd, m_numCrops);
392455

393-
matrix<float,1,1000> p = sum_rows(mat(snet(images.begin(), images.end()))) / m_numCrops;
456+
matrix<float,1,1000> p = sum_rows(mat(snet(images.begin(), images.end()))) / m_numCrops;
394457

395-
QVector<QPair<float, QString>> result;
458+
QVector<QPair<float, QString>> result;
396459

397-
for (size_t k = 0; k < m_settings->labelCount; ++k)
398-
{
399-
unsigned long predicted_label = index_of_max(p);
400-
result.append( { p(predicted_label), QString::fromStdString(labels[predicted_label]) } );
401-
p(predicted_label) = 0;
402-
}
460+
for (size_t k = 0; k < m_settings->labelCount; ++k)
461+
{
462+
unsigned long predicted_label = index_of_max(p);
463+
result.append( { p(predicted_label), QString::fromStdString(labels[predicted_label]) } );
464+
p(predicted_label) = 0;
465+
}
403466

404-
emit doneObject(result);
405-
}
467+
emit doneObject(result);
468+
}
469+
}();
406470

407-
if (m_settings->faceRecognitionEnabled)
408-
{
409-
if(referenceFaces.size() == 0)
471+
[&]() {
472+
if (m_settings->faceRecognitionEnabled)
410473
{
411-
if(m_refPhotoFileList.size() == 0)
474+
if(!m_faceRecognitionInitialized)
412475
{
413-
emit log("WARNING: Reference face list is empty!");
476+
if(! initFaceRecognition() )
477+
return;
414478
}
415-
else
416-
{
417-
setupReference(m_refPhotoFileList);
418-
}
419-
}
420479

421-
auto faces = findFaces(img);
480+
auto faces = findFaces(img);
422481

423-
if (faces.size() > 0)
424-
{
425-
rectangle rect;
426-
for (const auto& face : referenceFaces)
482+
if (faces.size() > 0)
427483
{
428-
faces.push_back(make_tuple(get<0>(face), rect, get<2>(face)));
429-
}
484+
rectangle rect;
485+
for (const auto& face : referenceFaces)
486+
{
487+
faces.push_back(make_tuple(get<0>(face), rect, get<2>(face)));
488+
}
430489

431-
auto graph = createGraph(faces, m_threshold);
490+
auto graph = createGraph(faces, m_threshold);
432491

433-
auto clusters = cluster(graph, faces);
492+
auto clusters = cluster(graph, faces);
434493

435-
QVector<QPair<QRect, QString>> linearFaces;
494+
QVector<QPair<QRect, QString>> linearFaces;
436495

437-
for (const auto& it : clusters)
438-
{
439-
QString str = it.first;
440-
for (const auto& it2 : it.second)
496+
for (const auto& it : clusters)
441497
{
442-
linearFaces.push_back(qMakePair(QRect(it2.left(), it2.top(), it2.width(), it2.height()), str));
498+
QString str = it.first;
499+
for (const auto& it2 : it.second)
500+
{
501+
linearFaces.push_back(qMakePair(QRect(it2.left(), it2.top(), it2.width(), it2.height()), str));
502+
}
443503
}
444-
}
445504

446-
emit doneFace(linearFaces);
505+
emit doneFace(linearFaces);
506+
}
447507
}
448-
}
508+
}();
449509

450510
m_busy = false;
451511
}

server/source/DLIBWorker/DLIBWorker.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ class DLIBWorker : public QObject
107107
bool m_busy;
108108
QString m_imageNetClassifierFile;
109109
size_t m_numCrops;
110+
bool m_faceRecognitionInitialized = false;
111+
bool m_objectRecognitionInitialized = false;
110112

111113
#ifdef TURBOJPEG_AVAILABLE
112114
void* m_tjHandle = nullptr;
@@ -116,8 +118,11 @@ class DLIBWorker : public QObject
116118

117119
std::vector<Face> referenceFaces;
118120

119-
void setupReference(const QVector<QPair<QString, QString>>& list);
120-
void setupImageNet();
121+
void resolveReferenceFaces(const QVector<QPair<QString, QString>>& list);
122+
123+
bool initFaceRecognition();
124+
bool initObjectRecognition();
125+
121126

122127
static std::vector<dlib::sample_pair> createGraph(const std::vector<Face>& faces, double threshold);
123128
static std::vector<Cluster> cluster(const std::vector<dlib::sample_pair>& graph, const std::vector<Face>& faces);

0 commit comments

Comments
 (0)