This patch is added FaceRecognitionEngine which handle face recognition event.
The logic for using FaceRecognitionEngine is in mmi_iu module.
Also, it added creating json result logic about face recognition event's result.
Then, it can check it's working by adding test case which get result from face recognition event.
Change-Id: I43cf857b341f064f0d173eb71fbd1e361ee3567a
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <chrono>
+
+#include "mmi_iu_log.h"
+#include "FaceRecognitionEngine.h"
+
+FaceRecognitionEngine::FaceRecognitionEngine()
+{
+ outputResultUserData = nullptr;
+ outputResultCallback = nullptr;
+}
+
+FaceRecognitionEngine::~FaceRecognitionEngine()
+{
+}
+
+long FaceRecognitionEngine::getCurrentTimestamp()
+{
+ auto currentTime = std::chrono::system_clock::now();
+ long timestamp = chrono::time_point_cast<chrono::milliseconds>(currentTime).time_since_epoch().count();
+ _D("[FaceRecognitionEngine] current timestamp(%ld)", timestamp);
+
+ return timestamp;
+}
+
+void FaceRecognitionEngine::iterateRecognizedFacesCallback(gpointer data, gpointer userData)
+{
+ face_result* info = reinterpret_cast<face_result*>(data);
+ FaceRecognitionEngine* engine = reinterpret_cast<FaceRecognitionEngine*>(userData);
+
+ engine->mRecognizedFacesList.push_back(*info);
+ _D("[FaceRecognitionEngine] iterateRecognizedFacesCallback: name(%s), id(%s), confidence(%f)", info->name, info->id, info->confidence);
+}
+
+bool FaceRecognitionEngine::setInputModalityData(int modalityType, void *data)
+{
+ _I("[FaceRecognitionEngine] Set input modality data. type(%d)", modalityType);
+
+ mmi_provider_event_face_recognizer *event = reinterpret_cast<mmi_provider_event_face_recognizer *>(data);
+ if (event == nullptr) {
+ _E("[FaceRecognitionEngine] event is NULL");
+ return false;
+ }
+
+ int timestamp = this->getCurrentTimestamp();
+ JsonProvider provider;
+ provider.setInputEvent(MMI_KEY_FACE_RECOGNITION);
+
+ switch (event->type) {
+ case MMI_FACE_RECOGNIZER_RECORDING_START:
+ _I("[FaceRecognitionEngine] mmi_face_recognizer camera_preview_start");
+ provider.setOutputEvent(MMI_KEY_CAMERA_PREVIEW_START);
+ break;
+
+ case MMI_FACE_RECOGNIZER_RECORDING_STOP:
+ _I("[FaceRecognitionEngine] mmi_face_recognizer camera_preview_stop");
+ provider.setOutputEvent(MMI_KEY_CAMERA_PREVIEW_STOP);
+ break;
+
+ case MMI_FACE_RECOGNIZER_ADD_USER:
+ _I("[FaceRecognitionEngine] mmi_face_recognizer add_user");
+ provider.setOutputEvent(MMI_KEY_ADD_USER_FACE);
+ break;
+
+ case MMI_FACE_RECOGNIZER_DELETE_USER:
+ provider.setOutputEvent(MMI_KEY_DELETE_USER_FACE);
+ break;
+
+ case MMI_FACE_RECOGNIZER_RECOGNIZE_FACE:
+ if (event->n_faces == 0) {
+ _E("[FaceRecognitionEngine] There is no recognized face");
+ provider.setOutputEvent(MMI_KEY_ERROR);
+ provider.setErrorEvent(MMI_REASON_NO_RECOGNIZED_FACES, timestamp);
+ break;
+ }
+
+ provider.setOutputEvent(MMI_KEY_RECOGNIZED_FACE);
+ provider.setFaceRecognitionEvent(MMI_KEY_RECOGNIZED_FACE, event->n_faces, timestamp);
+ mRecognizedFacesList.clear();
+
+ g_list_foreach(event->recognized_faces_list, iterateRecognizedFacesCallback, reinterpret_cast<gpointer>(this));
+
+ for (auto &recognizedFace : mRecognizedFacesList) {
+ provider.addInfoRecognizedFaces(recognizedFace.id, recognizedFace.name, recognizedFace.confidence,recognizedFace.coord_x, recognizedFace.coord_y, recognizedFace.width, recognizedFace.height);
+ }
+ break;
+
+ default:
+ _E("[FaceRecognitionEngine] Unknown event type(%d)", event->type);
+ return false;
+ }
+
+ // send json data
+ _D("face recognition engine json data(%s)", provider.jsonToString().c_str());
+ invokeOutputResultCallback(provider.jsonToString());
+ return true;
+}
+
+void FaceRecognitionEngine::invokeOutputResultCallback(std::string outputResult)
+{
+ if (outputResultCallback == nullptr) {
+ _W("[FaceRecognitionEngine] output result callback is not set. Please check it");
+ return;
+ }
+
+ _I("[FaceRecognitionEngine] invokeOutputResultCallback");
+ outputResultCallback(outputResult.c_str(), outputResultUserData);
+}
+
+void FaceRecognitionEngine::setOutputResultCallback(face_recognition_engine_output_result_cb callback, void *userData)
+{
+ outputResultCallback = callback;
+ outputResultUserData = userData;
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef __FACE_RECOGNITION_ENGINE_H__
+#define __FACE_RECOGNITION_ENGINE_H__
+
+#include <vector>
+#include "json_provider.h"
+#include "mmi-common.h"
+
+typedef void (*face_recognition_engine_output_result_cb)(const char *output_result, void *user_data);
+
+class FaceRecognitionEngine {
+public:
+ FaceRecognitionEngine();
+ ~FaceRecognitionEngine();
+
+ bool setInputModalityData(int modalityType, void *data);
+ void setOutputResultCallback(face_recognition_engine_output_result_cb callback, void *userData);
+
+private:
+ long getCurrentTimestamp();
+ void invokeOutputResultCallback(std::string result);
+ static void iterateRecognizedFacesCallback(gpointer data, gpointer userData);
+
+private:
+ std::vector<face_result> mRecognizedFacesList;
+ void *outputResultUserData;
+ face_recognition_engine_output_result_cb outputResultCallback;
+};
+
+#endif /* __FACE_RECOGNITION_ENGINE_H__ */
mSpeakerRecognitionObj = nullptr;
}
+ if (mFaceRecognitionObj) {
+ json_object_unref(mFaceRecognitionObj);
+ mFaceRecognitionObj = nullptr;
+ }
+
if (mRecognizedSpeakerCandidateListArr) {
json_array_unref(mRecognizedSpeakerCandidateListArr);
mRecognizedSpeakerCandidateListArr = nullptr;
mRecognizedSpeakerResultObj = nullptr;
}
+ if (mRecognizedFaceResultObj) {
+ json_object_unref(mRecognizedFaceResultObj);
+ mRecognizedFaceResultObj = nullptr;
+ }
+}
+
+void JsonProvider::setFaceRecognitionEvent(const char* resultType, int numOfFaces, int timeStamp)
+{
+ if (!mFaceRecognitionObj)
+ mFaceRecognitionObj = json_object_new();
+
+ json_object_set_object_member(mRootObj, MMI_KEY_RECOGNIZED_FACE, mFaceRecognitionObj);
+ json_object_set_int_member(mFaceRecognitionObj, MMI_KEY_NUM_OF_RECOGNIZED_FACES, numOfFaces);
+ json_object_set_int_member(mFaceRecognitionObj, MMI_KEY_TIMESTAMP, timeStamp);
}
+void JsonProvider::addInfoRecognizedFaces(const char* id, const char* name, float confidence, int x, int y, int w, int h)
+{
+ if (!mRecognizedFaceResultListArr)
+ {
+ mRecognizedFaceResultListArr = json_array_new();
+ json_object_set_array_member(mFaceRecognitionObj, MMI_KEY_RECOGNIZED_FACE_LISTS, mRecognizedFaceResultListArr);
+ }
+
+ JsonObject* obj = json_object_new();
+ json_array_add_object_element(mRecognizedFaceResultListArr, obj);
+ json_object_set_string_member(obj, MMI_KEY_RECOGNIZED_FACE_ID, id);
+ json_object_set_string_member(obj, MMI_KEY_RECOGNIZED_FACE_NAME, name);
+ json_object_set_double_member(obj, MMI_KEY_RECOGNIZED_FACE_CONFIDENCE, (double)confidence);
+ json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_X, x);
+ json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_Y, y);
+ json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_WIDTH, w);
+ json_object_set_int_member(obj, MMI_KEY_UI_OBJECT_HEIGHT, h);
+}
void JsonProvider::setSpeakerRecognitionEvent(const char* result, int timeStamp)
{
json_object_set_double_member(obj, MMI_KEY_SPEAKER_SCORE, (double)score);
}
-
-
void JsonProvider::setInputEvent(const char* value)
{
json_object_set_string_member(mRootObj, MMI_KEY_INPUT_EVENT, value);
#define MMI_KEY_SPEAKER_NAME "speakerName"
#define MMI_KEY_SPEAKER_SCORE "speakerScore"
+#define MMI_KEY_FACE_RECOGNITION "faceRecognition"
+#define MMI_KEY_CAMERA_PREVIEW_START "cameraPreviewStart"
+#define MMI_KEY_CAMERA_PREVIEW_STOP "cameraPreviewStop"
+#define MMI_KEY_ADD_USER_FACE "addUserFace"
+#define MMI_KEY_DELETE_USER_FACE "deleteUserFace"
+
+#define MMI_KEY_RECOGNIZED_FACE "recognizedFace"
+#define MMI_KEY_RECOGNIZED_FACE_LISTS "recognizedFaceLists"
+
+#define MMI_KEY_NUM_OF_RECOGNIZED_FACES "numOfRecognizedFaces"
+#define MMI_KEY_RECOGNIZED_FACE_ID "recognizedFaceId"
+#define MMI_KEY_RECOGNIZED_FACE_NAME "recognizedFaceName"
+#define MMI_KEY_RECOGNIZED_FACE_CONFIDENCE "recognizedFaceConfidence"
#define MMI_REASON_NO_MATCHED_COMMANDS "noMatchedCommands"
#define MMI_REASON_NO_CLICKABLE_OBJECTS "noClickableObjects"
+#define MMI_REASON_NO_RECOGNIZED_FACES "noRecognizedFaces"
struct UiClickedObject{
int timeStamp;
void addRecognizedSpeakerCandidate(const char* id, const char* name, float score);
void setRecognizedSpeakerResult(const char* result);
+ void setFaceRecognitionEvent(const char* resultType, int numOfFaces, int timeStamp);
+ void addInfoRecognizedFaces(const char* id, const char* name, float confidence, int x, int y, int w, int h);
std::string jsonToString(void);
JsonArray* mRecognizedSpeakerCandidateListArr = nullptr;
JsonObject* mRecognizedSpeakerResultObj = nullptr;
+ JsonObject* mFaceRecognitionObj = nullptr;
+ JsonArray* mRecognizedFaceResultListArr = nullptr;
+ JsonObject* mRecognizedFaceResultObj = nullptr;
};
#include "mmi_iu_log.h"
#include "VoiceTouchEngine.h"
#include "SpeakerRecognitionEngine.h"
+#include "FaceRecognitionEngine.h"
#include "mmi-common.h"
using namespace std;
static VoiceTouchEngine *g_VoiceTouchEngine = nullptr;
static SpeakerRecognitionEngine *g_SpeakerRecognitionEngine = nullptr;
-
+static FaceRecognitionEngine *g_FaceRecognitionEngine = nullptr;
static void init()
{
iu_output_result_received_callback(MMI_INPUT_EVENT_TYPE_SPEAKER_RECOGNITION, output_result, iu_output_result_user_data);
}
+void mmi_iu_face_recognition_engine_output_result_cb(const char *output_result, void *user_data)
+{
+ if (iu_output_result_received_callback == nullptr) {
+ _E("[MMI IU] Output result callback is not set");
+ return;
+ }
+
+ iu_output_result_received_callback(MMI_INPUT_EVENT_TYPE_FACE_RECOGNITION, output_result, iu_output_result_user_data);
+}
EXPORT_API int mmi_iu_init()
{
g_SpeakerRecognitionEngine->setOutputResultCallback(__mmi_iu_speaker_recognition_engine_output_result_cb, nullptr);
}
+ try {
+ g_FaceRecognitionEngine = new FaceRecognitionEngine();
+ } catch (exception &e) {
+ _E("[MMI IU] Fail to allocate memory. (%s)", e.what());
+ return MMI_IU_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (g_FaceRecognitionEngine) {
+ g_FaceRecognitionEngine->setOutputResultCallback(mmi_iu_face_recognition_engine_output_result_cb, nullptr);
+ }
return MMI_IU_ERROR_NONE;
}
delete g_SpeakerRecognitionEngine;
g_SpeakerRecognitionEngine = nullptr;
+ delete g_FaceRecognitionEngine;
+ g_FaceRecognitionEngine = nullptr;
if (!initialized)
return MMI_IU_ERROR_NOT_INITIALIZED;
}
if (type == MMI_PROVIDER_EVENT_FACE_RECOGNIZER) {
- // Todo. FaceRecognitionEngine
- _D("Face Recognition Engine is not supported yet.");
- return MMI_IU_ERROR_NOT_SUPPORTED_TYPE;
+ _D("[DEBUG] The type is MMI_PROVIDER_EVENT_FACE_RECOGNIZER(%d)", type);
+ if (g_FaceRecognitionEngine) {
+ int res = g_FaceRecognitionEngine->setInputModalityData(type, event);
+ if(!res) {
+ _W("[ERROR] Not Supported Event Type");
+ return MMI_IU_ERROR_NOT_SUPPORTED_TYPE;
+ }
+ return MMI_IU_ERROR_NONE;
+ }
}
if (type == MMI_PROVIDER_EVENT_SPEAKER_RECOGNIZER) {
'output_modality/mmi_output_modality.h',
'output_modality/TouchModule.cpp',
'output_modality/TouchModule.h',
+ 'iu/FaceRecognitionEngine.cpp',
+ 'iu/FaceRecognitionEngine.h',
]
install_headers(
MMI_SPEAKER_RECOGNIZER_RECORDING_STOP,
MMI_SPEAKER_RECOGNIZER_ADD_USER,
MMI_SPEAKER_RECOGNIZER_DELETE_USER,
- MMI_SPEAKER_RECOGNIZER_RECOGNIZE_SPEAKER,
+ MMI_SPEAKER_RECOGNIZER_RECOGNIZE_SPEAKER
} mmi_speaker_recognizer_operation;
typedef struct
GList *speaker_list; // list of speaker_result
} mmi_provider_event_speaker_recognizer;
+typedef enum mmi_face_recognizer_operation
+{
+ MMI_FACE_RECOGNIZER_RECORDING_START,
+ MMI_FACE_RECOGNIZER_RECORDING_STOP,
+ MMI_FACE_RECOGNIZER_ADD_USER,
+ MMI_FACE_RECOGNIZER_DELETE_USER,
+ MMI_FACE_RECOGNIZER_RECOGNIZE_FACE,
+} mmi_face_recognizer_operation;
+
+typedef struct
+{
+ char *id;
+ char *name;
+ float confidence;
+ int coord_x;
+ int coord_y;
+ int width;
+ int height;
+} face_result;
+
typedef struct
{
int type;
int timestamp;
- double confidence;
- char *recognizer;
- int n_recognizers;
- GList *recognizer_list;
+ int n_faces;
+ GList *recognized_faces_list;
} mmi_provider_event_face_recognizer;
typedef struct
static Eina_Bool face_recognizer_event_cb(void *data EINA_UNUSED, int type, void *event)
{
mmi_provider_event_face_recognizer *ev = (mmi_provider_event_face_recognizer *)event;
+ _I("[Face recognizer] type : %d, timestamp : %d, n_faces : %d", ev->type, ev->timestamp, ev->n_faces);
mmi_iu_feed_input_modality(MMI_PROVIDER_EVENT_FACE_RECOGNIZER, ev);
return ECORE_CALLBACK_PASS_ON;
LOGD("MMI_PROVIDER_EVENT_SCREEN_ANALYZER=%d\n", MMI_PROVIDER_EVENT_SCREEN_ANALYZER);
LOGD("MMI_PROVIDER_EVENT_VOICE_TOUCH=%d\n", MMI_PROVIDER_EVENT_VOICE_TOUCH);
+ LOGD("MMI_PROVIDER_EVENT_FACE_RECOGNIZER=%d\n", MMI_PROVIDER_EVENT_FACE_RECOGNIZER);
+ LOGD("MMI_EVENT_FACE_RECOGNIZER=%d\n", MMI_EVENT_FACE_RECOGNIZER);
+
//For debugging
_provider_event_handlers[0] = ecore_event_handler_add(MMI_PROVIDER_EVENT_KEY,
_key_provider_event_cb, NULL);
#include "mmi_iu.h"
#include "mmi_iu_log.h"
#include "mmi_iu_event.h"
+#include "json_provider.h"
#include <glib.h>
#include <string>
static bool g_check_event_received = false;
#define MMI_EVENT_VOICE_TYPE_GO 1000 // for test
-#define MMI_KEY_OUTPUT_EVENT "outputEvent"
-#define MMI_KEY_ASR_FINAL_RESULT "asrFinalResult"
-#define MMI_KEY_RESULT "result"
-#define MMI_KEY_UI_CLICKABLE_OBJECT "uiClickableObject"
-#define MMI_KEY_NUM_OF_CLICKABLE_OBJECTS "numOfClickableObjects"
namespace {
MMI_PROVIDER_EVENT_VISION = ecore_event_type_new();
MMI_PROVIDER_EVENT_SCREEN_ANALYZER = ecore_event_type_new();
MMI_PROVIDER_EVENT_VOICE_TOUCH = ecore_event_type_new();
+ MMI_PROVIDER_EVENT_FACE_RECOGNIZER = ecore_event_type_new();
g_received_event_type = -1;
g_received_event_data = NULL;
MMI_PROVIDER_EVENT_VOICE = -1;
MMI_PROVIDER_EVENT_VISION = -1;
MMI_PROVIDER_EVENT_VOICE_TOUCH = -1;
+ MMI_PROVIDER_EVENT_FACE_RECOGNIZER = -1;
ecore_shutdown();
}
{
_D("face_output_intent_received_cb\n");
+ JsonParser *parser = json_parser_new();
+ GError *err_msg = NULL;
+ JsonNode *root = NULL;
+ JsonObject *root_obj = NULL;
+ JsonObject *result_obj = NULL;
+ const gchar *action = NULL;
+ string output_event = "";
+ JsonArray *output_array = NULL;
+ int num = NULL;
+
+ json_parser_load_from_data(parser, (char *)json_data, -1, &err_msg);
+ if (err_msg) {
+ _E("failed to load json file. error message: %s\n", err_msg->message);
+ goto cleanup;
+ }
+
+ root = json_parser_get_root(parser);
+ if (root == NULL) {
+ _E("failed to get root\n");
+ goto cleanup;
+ }
+
+ root_obj = json_node_get_object(root);
+ if (root_obj == NULL) {
+ _E("failed to get root_obj\n");
+ goto cleanup;
+ }
+
+ output_array = json_object_get_array_member(root_obj, MMI_KEY_OUTPUT_EVENT);
+ if (output_array == NULL) {
+ _E("output array is null");
+ goto cleanup;
+ }
+
+ action = json_array_get_string_element(output_array, 0);
+ if (action == nullptr) {
+ _E("failed to get output_array\n");
+ goto cleanup;
+ }
+
+ output_event = string(action);
+ if (output_event == MMI_KEY_RECOGNIZED_FACE) {
+ result_obj = json_object_get_object_member(root_obj, MMI_KEY_RECOGNIZED_FACE);
+ if (result_obj != NULL) {
+ num = json_object_get_int_member(result_obj, MMI_KEY_NUM_OF_RECOGNIZED_FACES);
+ if (num == NULL) {
+ _E("failed to get object of result\n");
+ goto cleanup;
+ }
+ _D("num of faces : %d", num);
+
+ output_array = json_object_get_array_member(result_obj, MMI_KEY_RECOGNIZED_FACE_LISTS);
+ if (output_array == NULL) {
+ _E("output array is null");
+ goto cleanup;
+ }
+
+ result_obj = json_array_get_object_element(output_array, 0);
+ if (result_obj != NULL) {
+ action = json_object_get_string_member(result_obj, MMI_KEY_RECOGNIZED_FACE_NAME);
+ if (action == nullptr) {
+ _E("failed to get object of result\n");
+ goto cleanup;
+ }
+
+ output_action = string(action);
+ }
+ }
+ }
+ else if (output_event == MMI_KEY_ERROR) {
+ result_obj = json_object_get_object_member(root_obj, MMI_KEY_ERROR);
+ if (result_obj != NULL) {
+ action = json_object_get_string_member(result_obj, MMI_KEY_REASON);
+ if (action == nullptr) {
+ _E("failed to get object of result\n");
+ goto cleanup;
+ }
+
+ output_action = string(action);
+ }
+ }
+
+ if (parser)
+ g_object_unref(parser);
+
return;
+
+cleanup:
+ if (err_msg)
+ g_error_free(err_msg);
+
+ if (parser)
+ g_object_unref(parser);
}
TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_input_event_face_recognizer_p)
EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
mmi_provider_event_face_recognizer fe = { 0, };
- fe.type = 0;
- fe.n_recognizers = 1;
+ fe.type = MMI_FACE_RECOGNIZER_RECOGNIZE_FACE;
+ fe.n_faces = 1;
+ face_result *person1 = (face_result *)malloc(sizeof(face_result));
+ person1->id = strdup("id1");
+ person1->name = strdup("person1");
+ person1->confidence = 0.9;
+ person1->coord_x = 0;
+ person1->coord_y = 0;
+ person1->width = 100;
+ person1->height = 100;
+ fe.recognized_faces_list = g_list_append(fe.recognized_faces_list, person1);
ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_PROVIDER_EVENT_FACE_RECOGNIZER, &fe);
- EXPECT_EQ(ret, MMI_IU_ERROR_NOT_SUPPORTED_TYPE);
+ EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+ EXPECT_STREQ(output_action.c_str(), person1->name);
+}
+
+TEST_F(IUClientFeedInputEventTest, utc_mmi_iu_feed_input_event_face_recognizer_n)
+{
+ int ret = mmi_iu_set_output_result_received_callback(face_output_intent_received_cb, NULL);
+ EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+ mmi_provider_event_face_recognizer fe = { 0, };
+ fe.type = MMI_FACE_RECOGNIZER_RECOGNIZE_FACE;
+ fe.n_faces = 0;
+
+ ret = feed_input_event_test(MMI_STATE_EXPLORATION, MMI_PROVIDER_EVENT_FACE_RECOGNIZER, &fe);
+ EXPECT_EQ(ret, MMI_IU_ERROR_NONE);
+
+ EXPECT_STREQ(output_action.c_str(), MMI_REASON_NO_RECOGNIZED_FACES);
}
} // namespace