mv_machine_learning: introduce Context, ITask and adapter classes
authorInki Dae <inki.dae@samsung.com>
Fri, 1 Jul 2022 06:44:32 +0000 (15:44 +0900)
committerInki Dae <inki.dae@samsung.com>
Wed, 20 Jul 2022 05:16:57 +0000 (14:16 +0900)
[Issue type] new feature

Introduced Context, ITask, and adapter class derived from ITask one.

With this patch, each Task API has a context which can have one more
itask objects for controlling inference or training modules.
The purpose of this patch is to keep same interfaces for each module.

As a reference, this patch applies this new approach to Face recognition
framework. This is just a step for next code refactoring
for multi models support.

Change-Id: Iad4c4df9fc87143723decadbc003787854e60e4b
Signed-off-by: Inki Dae <inki.dae@samsung.com>
12 files changed:
CMakeLists.txt
media-vision-config.json
mv_machine_learning/common/include/context.h [new file with mode: 0644]
mv_machine_learning/common/include/itask.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/face_recognition.h
mv_machine_learning/face_recognition/include/face_recognition_adapter.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/mv_face_recognition_open.h
mv_machine_learning/face_recognition/meta/face_recognition.json [new file with mode: 0644]
mv_machine_learning/face_recognition/src/face_recognition.cpp
mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/mv_face_recognition_open.cpp
packaging/capi-media-vision.spec

index 7050132..bbc1735 100644 (file)
@@ -148,6 +148,7 @@ configure_file(
     @ONLY
 )
 install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}-face-recognition.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/face_recognition/meta/face_recognition.json DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
 
 set(PC_NAME ${fw_name}-tracker)
 set(PC_LDFLAGS "-l${MV_ROI_TRACKER_LIB_NAME} -l${MV_COMMON_LIB_NAME}")
index b12a490..9987623 100644 (file)
             "name"  : "MV_INFERENCE_MODEL_META_FILE_PATH",
             "type"  : "string",
             "value" : ""
-        },
-        {
-            "name"  : "MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH",
-            "type"  : "string",
-            "value" : "/usr/share/capi-media-vision/models/FR/backbone/tflite/facenet.tflite"
-        },
-        {
-            "name"  : "MV_FACE_RECOGNITION_DEFAULT_PATH",
-            "type"  : "string",
-            "value" : "/usr/share/capi-media-vision/models/FR/training/"
-        },
-        {
-            "name"  : "MV_FACE_RECOGNITION_DECISION_THRESHOLD",
-            "type"  : "double",
-            "value" : -0.85
-        },
-        {
-            "name"  : "MV_ROI_TRACKER_TYPE",
-            "type"  : "integer",
-            "value" : 2
         }
     ]
 }
diff --git a/mv_machine_learning/common/include/context.h b/mv_machine_learning/common/include/context.h
new file mode 100644 (file)
index 0000000..518fbe4
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2022 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 __CONTEXT_H__
+#define __CONTEXT_H__
+
+#include "itask.h"
+#include <map>
+
+namespace mediavision
+{
+namespace common
+{
+class Context {
+public:
+       Context() { }
+       ~Context() { }
+
+       std::map<std::string, void *> __itasks;
+};
+} // namespace
+} // namespace
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/itask.h b/mv_machine_learning/common/include/itask.h
new file mode 100644 (file)
index 0000000..cacf827
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2022 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 __ITASK_H__
+#define __ITASK_H__
+
+namespace mediavision
+{
+namespace common
+{
+// T : parameter type, V : return type
+template <typename T, typename V>
+class ITask {
+public:
+       virtual ~ITask() { };
+       virtual void configure() = 0;
+       virtual void prepare() = 0;
+       virtual void setInput(T& t) = 0;
+       virtual void perform() = 0;
+       virtual V& getOutput() = 0;
+};
+} // namespace
+} // namespace
+
+#endif
\ No newline at end of file
index bb79825..f4d65a8 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __FACE_RECOGNITION_H__
 #define __FACE_RECOGNITION_H__
 
+#include <unordered_map>
 #include <mv_common.h>
 #include <mv_inference_type.h>
 
@@ -35,18 +36,36 @@ namespace Mv
 {
 namespace FaceRecognition
 {
+
 namespace Status
 {
-       enum {
-               NONE = 0,
-               INITIALIZED,
-               REGISTERED,
-               INFERENCED,
-               DELETED
-       };
-}
-}
-}
+enum {
+       NONE = 0,
+       INITIALIZED,
+       REGISTERED,
+       INFERENCED,
+       DELETED
+};
+} // Status
+
+namespace Mode
+{
+enum {
+       REGISTER = 0,
+       INFERENCE,
+       DELETE
+};
+} // Mode
+
+} // FaceRecognition
+} // Mv
+
+typedef struct {
+       unsigned int mode;
+       std::unordered_map<mv_source_h, std::string> register_src;
+       mv_source_h inference_src;
+       std::vector<std::string> labels;
+} mv_face_recognition_input_s;
 
 /**
  * @brief The face recognition result structure.
@@ -108,6 +127,8 @@ public:
        int RecognizeFace(mv_source_h img_src);
        int DeleteLabel(std::string label_name);
        int GetLabel(const char **out_label);
+       mv_face_recognition_result_s& GetResult();
+
 };
 
 #endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/face_recognition_adapter.h b/mv_machine_learning/face_recognition/include/face_recognition_adapter.h
new file mode 100644 (file)
index 0000000..f5a4ad0
--- /dev/null
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2022 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_ADAPTER_H__
+#define __FACE_RECOGNITION_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "itask.h"
+#include "face_recognition.h"
+
+/**
+ * @brief Defines #MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH
+ *        to set the backbone model file path.
+ * @details This model file is used to extract the feature vectors from a given face image data.
+ *
+ * @since_tizen 7.0
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+#define MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH "MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH"
+
+/**
+ * @brief Defines #MV_FACE_RECOGNITION_DEFAULT_PATH
+ *        to set the path where the training relevant files are created.
+ * @details This path is used as a default location where the trained model, label and feature vector files are created.
+ *
+ * @since_tizen 7.0
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+#define MV_FACE_RECOGNITION_DEFAULT_PATH "MV_FACE_RECOGNITION_DEFAULT_PATH"
+
+/**
+ * @brief Defines #MV_FACE_RECOGNITION_DECISION_THRESHOLD
+ *        to set the decision threshold file+.
+ * @details This file is used to determine face recognition result with a given face image data is true or false..
+ *
+ * @since_tizen 7.0
+ * @see mv_engine_config_set_string_attribute()
+ * @see mv_engine_config_get_string_attribute()
+ */
+#define MV_FACE_RECOGNITION_DECISION_THRESHOLD "MV_FACE_RECOGNITION_DECISION_THRESHOLD"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template <typename T, typename V>
+class FaceRecognitionAdapter : public mediavision::common::ITask<T, V> {
+private:
+       std::unique_ptr<FaceRecognition> _face_recognition;
+       mv_face_recognition_input_s _source;
+       std::unique_ptr<MediaVision::Common::EngineConfig> _config;
+
+public:
+       FaceRecognitionAdapter();
+       ~FaceRecognitionAdapter();
+
+       std::unique_ptr<MediaVision::Common::EngineConfig>& getConfig()
+       {
+               return _config;
+       }
+
+       void configure();
+       void prepare();
+       void setInput(T& t);
+       void perform();
+       V& getOutput();
+};
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
index 1f17b1f..5055ec5 100644 (file)
 #include <mv_private.h>
 #include <mv_face_recognition_type.h>
 
-/**
- * @brief Defines #MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH
- *        to set the backbone model file path.
- * @details This model file is used to extract the feature vectors from a given face image data.
- *
- * @since_tizen 7.0
- * @see mv_engine_config_set_string_attribute()
- * @see mv_engine_config_get_string_attribute()
- */
-#define MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH "MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH"
-
-/**
- * @brief Defines #MV_FACE_RECOGNITION_DEFAULT_PATH
- *        to set the path where the training relevant files are created.
- * @details This path is used as a default location where the trained model, label and feature vector files are created.
- *
- * @since_tizen 7.0
- * @see mv_engine_config_set_string_attribute()
- * @see mv_engine_config_get_string_attribute()
- */
-#define MV_FACE_RECOGNITION_DEFAULT_PATH "MV_FACE_RECOGNITION_DEFAULT_PATH"
-
-/**
- * @brief Defines #MV_FACE_RECOGNITION_DECISION_THRESHOLD
- *        to set the decision threshold file+.
- * @details This file is used to determine face recognition result with a given face image data is true or false..
- *
- * @since_tizen 7.0
- * @see mv_engine_config_set_string_attribute()
- * @see mv_engine_config_get_string_attribute()
- */
-#define MV_FACE_RECOGNITION_DECISION_THRESHOLD "MV_FACE_RECOGNITION_DECISION_THRESHOLD"
-
 #ifdef __cplusplus
 extern "C"
 {
diff --git a/mv_machine_learning/face_recognition/meta/face_recognition.json b/mv_machine_learning/face_recognition/meta/face_recognition.json
new file mode 100644 (file)
index 0000000..db563ac
--- /dev/null
@@ -0,0 +1,20 @@
+{
+    "attributes":
+    [
+        {
+            "name"  : "MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH",
+            "type"  : "string",
+            "value" : "/usr/share/capi-media-vision/models/FR/backbone/tflite/facenet.tflite"
+        },
+        {
+            "name"  : "MV_FACE_RECOGNITION_DEFAULT_PATH",
+            "type"  : "string",
+            "value" : "/usr/share/capi-media-vision/models/FR/training/"
+        },
+        {
+            "name"  : "MV_FACE_RECOGNITION_DECISION_THRESHOLD",
+            "type"  : "double",
+            "value" : -0.85
+        }
+    ]
+}
index ecf0d26..11ad1a2 100644 (file)
@@ -601,4 +601,16 @@ int FaceRecognition::GetLabel(const char **out_label)
        *out_label = _result.label.c_str();
 
        return MEDIA_VISION_ERROR_NONE;
-}
\ No newline at end of file
+}
+
+ mv_face_recognition_result_s& FaceRecognition::GetResult()
+ {
+       try {
+               _label_manager->GetLabelString(_result.label, _result.label_idx);
+       } catch (const BaseException& e) {
+               LOGE("%s", e.what());
+               throw e;
+       }
+
+       return _result;
+ }
diff --git a/mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp b/mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp
new file mode 100644 (file)
index 0000000..de0abb9
--- /dev/null
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2022 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 "machine_learning_exception.h"
+#include "face_recognition_adapter.h"
+
+#define FACE_RECOGNITION_META_FILE_NAME        "face_recognition.json"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace Mediavision::MachineLearning::Exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template <typename T, typename V>
+FaceRecognitionAdapter<T, V>::FaceRecognitionAdapter()
+{
+       _face_recognition = make_unique<FaceRecognition>();
+}
+
+template <typename T, typename V>
+FaceRecognitionAdapter<T, V>::~FaceRecognitionAdapter()
+{
+
+}
+
+template <typename T, typename V>
+void FaceRecognitionAdapter<T, V>::configure()
+{
+       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) +
+                                                                               string(FACE_RECOGNITION_META_FILE_NAME));
+       string backboneModelFilePath;
+       int ret = _config->getStringAttribute(string(MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH),
+                                                                                       &backboneModelFilePath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidParameter("Failed to get an attribute");
+
+       LOGD("Backbone model file path : %s", backboneModelFilePath.c_str());
+
+       string defaultPath;
+
+       ret = _config->getStringAttribute(string(MV_FACE_RECOGNITION_DEFAULT_PATH),
+                                                                               &defaultPath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get default path.");
+
+       LOGD("Default path : %s", defaultPath.c_str());
+
+       double decisionThreshold = 0.0f;
+       ret = _config->getDoubleAttribute(string(MV_FACE_RECOGNITION_DECISION_THRESHOLD),
+                                                                               &decisionThreshold);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get default decision threshold value.");
+
+       FaceRecognitionConfig config = {
+               MV_INFERENCE_TARGET_DEVICE_CPU, // not used and default type is used. See TrainingModel()
+               MV_INFERENCE_BACKEND_NNTRAINER, // not used and default type is used. See TrainingModel()
+               MV_INFERENCE_TARGET_DEVICE_CPU,
+               MV_INFERENCE_BACKEND_NNTRAINER,
+               MV_INFERENCE_TARGET_DEVICE_CPU,
+               MV_INFERENCE_BACKEND_TFLITE,
+               backboneModelFilePath,
+               string(defaultPath) + "model_and_weights.ini",
+               string(defaultPath) + "labels.dat",
+               string(defaultPath) + "feature_vector_file.dat",
+               decisionThreshold
+       };
+
+       _face_recognition->SetConfig(config);
+}
+
+template <typename T, typename V>
+void FaceRecognitionAdapter<T, V>::prepare()
+{
+       int ret = _face_recognition->Initialize();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to initialize face recognition.");
+}
+
+template <typename T, typename V>
+void FaceRecognitionAdapter<T, V>::setInput(T& t)
+{
+       _source = t;
+}
+
+template <typename T, typename V>
+void FaceRecognitionAdapter<T, V>::perform()
+{
+       if (_source.mode == Mv::FaceRecognition::Mode::REGISTER) {
+               for (auto& s : _source.register_src) {
+                       int ret = _face_recognition->RegisterNewFace(s.first, s.second);
+                       if (ret != MEDIA_VISION_ERROR_NONE)
+                               throw InvalidOperation("Fail to register new face.");
+               }
+
+               return;
+       }
+
+       if (_source.mode == Mv::FaceRecognition::Mode::INFERENCE) {
+               int ret = _face_recognition->RecognizeFace(_source.inference_src);
+               if (ret == MEDIA_VISION_ERROR_NO_DATA)
+                       throw NoData("Label not found.");
+
+               return;
+       }
+
+       if (_source.mode == Mv::FaceRecognition::Mode::DELETE) {
+               for (auto& l : _source.labels) {
+                       int ret = _face_recognition->DeleteLabel(l);
+                       if (ret != MEDIA_VISION_ERROR_NONE)
+                               throw InvalidOperation("Fail to unregister a given label.");
+               }
+
+               return;
+       }
+}
+
+template <typename T, typename V>
+V& FaceRecognitionAdapter<T, V>::getOutput()
+{
+       return _face_recognition->GetResult();
+}
+
+template class FaceRecognitionAdapter<mv_face_recognition_input_s, mv_face_recognition_result_s>;
+}
+}
\ No newline at end of file
index ef5b8c1..d34b699 100644 (file)
 #include <dlog.h>
 #include <memory>
 
-#include "face_recognition.h"
-#include "feature_vector_manager.h"
-#include "backbone_model_info.h"
+#include "face_recognition_adapter.h"
 #include "mv_face_recognition_open.h"
 #include "machine_learning_exception.h"
+#include "context.h"
 
 using namespace std;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning;
+using namespace Mv::FaceRecognition;
 using namespace Mediavision::MachineLearning::Exception;
 
 int mv_face_recognition_create_open(mv_face_recognition_h *handle)
@@ -34,12 +36,31 @@ int mv_face_recognition_create_open(mv_face_recognition_h *handle)
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       (*handle) = static_cast<mv_face_recognition_h>(new (std::nothrow)FaceRecognition());
-       if (*handle == NULL) {
-               LOGE("Failed to create face recognition handle");
+       Context *context = new (nothrow)Context();
+       if (!context) {
+               LOGE("Fail to allocate a context.");
                return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
        }
 
+       ITask<mv_face_recognition_input_s, mv_face_recognition_result_s> *itask =
+               new (nothrow)FaceRecognitionAdapter<mv_face_recognition_input_s, mv_face_recognition_result_s>();
+       if (!itask) {
+               delete context;
+               LOGE("Fail to allocate a itask.");
+               return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+       }
+
+       pair<map<string, void *>::iterator, bool> result;
+
+       result = context->__itasks.insert(pair<string, void *>("face_recognition", itask));
+       if (!result.second) {
+               delete context;
+               LOGE("Fail to register a new task. Same task already exists.");
+               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+       }
+
+       *handle = static_cast<mv_face_recognition_h>(context);
+
        LOGD("face recognition handle [%p] has been created", *handle);
 
        return MEDIA_VISION_ERROR_NONE;
@@ -52,8 +73,16 @@ int mv_face_recognition_destroy_open(mv_face_recognition_h handle)
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       LOGD("Destroying face recognition handle [%p]", handle);
-       delete static_cast<FaceRecognition *>(handle);
+       Context *context = static_cast<Context *>(handle);
+       map<string, void *>::iterator iter;
+
+       for (iter = context->__itasks.begin(); iter != context->__itasks.end(); ++iter) {
+               auto itask = static_cast<ITask<mv_face_recognition_input_s, mv_face_recognition_result_s> *>(iter->second);
+               delete itask;
+       }
+
+       delete context;
+
        LOGD("Face recognition handle has been destroyed");
 
        return MEDIA_VISION_ERROR_NONE;
@@ -68,77 +97,15 @@ int mv_face_recognition_prepare_open(mv_face_recognition_h handle)
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       mv_engine_config_h cfg_handle;
-
-       int ret = mv_create_engine_config(&cfg_handle);
-       if (ret != MEDIA_VISION_ERROR_NONE) {
-               LOGE("Fail to create engine configuration handle.");
-               return ret;
-       }
-
-       char *backboneModelFilePath = NULL;
-
-       ret = mv_engine_config_get_string_attribute(cfg_handle, MV_FACE_RECOGNITION_BACKBONE_MODEL_FILE_PATH, &backboneModelFilePath);
-       if (ret != MEDIA_VISION_ERROR_NONE) {
-               LOGE("Fail to get backbone model file path");
-               mv_destroy_engine_config(cfg_handle);
-               return ret;
-       }
-
-       LOGD("Backbone model file path : %s", backboneModelFilePath);
-
-       char *defaultPath = NULL;
-
-       ret = mv_engine_config_get_string_attribute(cfg_handle, MV_FACE_RECOGNITION_DEFAULT_PATH, &defaultPath);
-       if (ret != MEDIA_VISION_ERROR_NONE) {
-               LOGE("Fail to get default path.");
-               free(backboneModelFilePath);
-               mv_destroy_engine_config(cfg_handle);
-               return ret;
-       }
+       Context *context = static_cast<Context *>(handle);
+       auto itask = static_cast<ITask<mv_face_recognition_input_s, mv_face_recognition_result_s> *>(context->__itasks["face_recognition"]);
 
-       LOGD("Default path : %s", defaultPath);
-
-       double decisionThreshold = 0.0f;
-
-       ret = mv_engine_config_get_double_attribute(cfg_handle, MV_FACE_RECOGNITION_DECISION_THRESHOLD, &decisionThreshold);
-       if (ret != MEDIA_VISION_ERROR_NONE) {
-               LOGE("Fail to get default decision threshold file path.");
-               free(backboneModelFilePath);
-               free(defaultPath);
-               mv_destroy_engine_config(cfg_handle);
-               return ret;
-       }
-
-       FaceRecognitionConfig config = {
-               MV_INFERENCE_TARGET_DEVICE_CPU, // not used and default type is used. See TrainingModel()
-               MV_INFERENCE_BACKEND_NNTRAINER, // not used and default type is used. See TrainingModel()
-               MV_INFERENCE_TARGET_DEVICE_CPU,
-               MV_INFERENCE_BACKEND_NNTRAINER,
-               MV_INFERENCE_TARGET_DEVICE_CPU,
-               MV_INFERENCE_BACKEND_TFLITE,
-               backboneModelFilePath,
-               string(defaultPath) + "model_and_weights.ini",
-               string(defaultPath) + "labels.dat",
-               string(defaultPath) + "feature_vector_file.dat",
-               decisionThreshold
-       };
-
-       FaceRecognition *pFace = static_cast<FaceRecognition *>(handle);
-       pFace->SetConfig(config);
-
-       ret = pFace->Initialize();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               LOGE("Fail to initialize face recognition.");
-
-       free(backboneModelFilePath);
-       free(defaultPath);
-
-       mv_destroy_engine_config(cfg_handle);
+       itask->configure();
+       itask->prepare();
 
        LOGD("LEAVE");
 
-       return ret;
+       return MEDIA_VISION_ERROR_NONE;
 }
 
 int mv_face_recognition_register_open(mv_face_recognition_h handle, mv_source_h source, const char *label)
@@ -150,15 +117,24 @@ int mv_face_recognition_register_open(mv_face_recognition_h handle, mv_source_h
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       FaceRecognition *pFace = static_cast<FaceRecognition *>(handle);
+       try {
+               Context *context = static_cast<Context *>(handle);
+               auto itask = static_cast<ITask<mv_face_recognition_input_s, mv_face_recognition_result_s> *>(context->__itasks["face_recognition"]);
+
+               mv_face_recognition_input_s input = { Mode::REGISTER };
 
-       int ret = pFace->RegisterNewFace(source, string(label));
-       if (ret != MEDIA_VISION_ERROR_NONE)
+               input.register_src.clear();
+               input.register_src.insert(make_pair(source, string(label)));
+               itask->setInput(input);
+               itask->perform();
+       } catch (const BaseException& e) {
                LOGE("Fail to register new face.");
+               return e.getError();
+       }
 
        LOGD("LEAVE");
 
-       return ret;
+       return MEDIA_VISION_ERROR_NONE;
 }
 
 int mv_face_recognition_unregister_open(mv_face_recognition_h handle, const char *label)
@@ -170,15 +146,24 @@ int mv_face_recognition_unregister_open(mv_face_recognition_h handle, const char
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       FaceRecognition *pFace = static_cast<FaceRecognition *>(handle);
+       try {
+               Context *context = static_cast<Context *>(handle);
+               auto itask = static_cast<ITask<mv_face_recognition_input_s, mv_face_recognition_result_s> *>(context->__itasks["face_recognition"]);
 
-       int ret = pFace->DeleteLabel(string(label));
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               LOGE("Fail to register new face.");
+               mv_face_recognition_input_s input = { Mode::DELETE };
+
+               input.labels.clear();
+               input.labels.push_back(string(label));
+               itask->setInput(input);
+               itask->perform();
+       } catch (const BaseException& e) {
+               LOGE("Fail to unregister a given label.");
+               return e.getError();
+       }
 
        LOGD("LEAVE");
 
-       return ret;
+       return MEDIA_VISION_ERROR_NONE;
 }
 
 int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h source)
@@ -190,20 +175,23 @@ int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       FaceRecognition *pFace = static_cast<FaceRecognition *>(handle);
+       try {
+               Context *context = static_cast<Context *>(handle);
+               auto itask = static_cast<ITask<mv_face_recognition_input_s, mv_face_recognition_result_s> *>(context->__itasks["face_recognition"]);
 
-       int ret = pFace->RecognizeFace(source);
-       if (ret == MEDIA_VISION_ERROR_NO_DATA) {
-               LOGW("Label not found.");
-               return ret;
-       }
+               mv_face_recognition_input_s input = { Mode::INFERENCE };
 
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               LOGE("Fail to recognize face.");
+               input.inference_src = source;
+               itask->setInput(input);
+               itask->perform();
+       } catch (const BaseException& e) {
+               LOGE("Fail to recognize a face.");
+               return e.getError();
+       }
 
        LOGD("LEAVE");
 
-       return ret;
+       return MEDIA_VISION_ERROR_NONE;
 }
 
 int mv_face_recognition_get_label_open(mv_face_recognition_h handle, const char **out_label)
@@ -215,12 +203,14 @@ int mv_face_recognition_get_label_open(mv_face_recognition_h handle, const char
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
 
-       FaceRecognition *pFace = static_cast<FaceRecognition *>(handle);
+       try {
+               Context *context = static_cast<Context *>(handle);
+               auto itask = static_cast<ITask<mv_face_recognition_input_s, mv_face_recognition_result_s> *>(context->__itasks["face_recognition"]);
 
-       int ret = pFace->GetLabel(out_label);
-       if (ret != MEDIA_VISION_ERROR_NONE) {
+               *out_label = itask->getOutput().label.c_str();
+       } catch (const BaseException& e) {
                LOGE("Fail to get label.");
-               return ret;
+               return e.getError();
        }
 
        LOGD("LEAVE");
index b5a958e..5ac71bd 100644 (file)
@@ -317,6 +317,7 @@ find . -name '*.gcno' -exec cp --parents '{}' "$gcno_obj_dir" ';'
 %files machine_learning
 %manifest %{name}.manifest
 %license LICENSE.APLv2
+%{_datadir}/%{name}/face_recognition.json
 %{_libdir}/libmv_inference*.so
 %{_libdir}/libmv_training.so
 %{_libdir}/libmv_face_recognition.so