From: Inki Dae Date: Fri, 1 Jul 2022 06:44:32 +0000 (+0900) Subject: mv_machine_learning: introduce Context, ITask and adapter classes X-Git-Tag: submit/tizen/20220720.053259~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=42f56e7cbdaf642496628f657a0006774fc03bc9;p=platform%2Fcore%2Fapi%2Fmediavision.git mv_machine_learning: introduce Context, ITask and adapter classes [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 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 70501325..bbc17359 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}") diff --git a/media-vision-config.json b/media-vision-config.json index b12a4905..99876233 100644 --- a/media-vision-config.json +++ b/media-vision-config.json @@ -247,26 +247,6 @@ "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 index 00000000..518fbe42 --- /dev/null +++ b/mv_machine_learning/common/include/context.h @@ -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 + +namespace mediavision +{ +namespace common +{ +class Context { +public: + Context() { } + ~Context() { } + + std::map __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 index 00000000..cacf8274 --- /dev/null +++ b/mv_machine_learning/common/include/itask.h @@ -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 +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 diff --git a/mv_machine_learning/face_recognition/include/face_recognition.h b/mv_machine_learning/face_recognition/include/face_recognition.h index bb79825a..f4d65a88 100644 --- a/mv_machine_learning/face_recognition/include/face_recognition.h +++ b/mv_machine_learning/face_recognition/include/face_recognition.h @@ -17,6 +17,7 @@ #ifndef __FACE_RECOGNITION_H__ #define __FACE_RECOGNITION_H__ +#include #include #include @@ -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 register_src; + mv_source_h inference_src; + std::vector 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 index 00000000..f5a4ad09 --- /dev/null +++ b/mv_machine_learning/face_recognition/include/face_recognition_adapter.h @@ -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 + +#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 +class FaceRecognitionAdapter : public mediavision::common::ITask { +private: + std::unique_ptr _face_recognition; + mv_face_recognition_input_s _source; + std::unique_ptr _config; + +public: + FaceRecognitionAdapter(); + ~FaceRecognitionAdapter(); + + std::unique_ptr& 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 diff --git a/mv_machine_learning/face_recognition/include/mv_face_recognition_open.h b/mv_machine_learning/face_recognition/include/mv_face_recognition_open.h index 1f17b1f0..5055ec5b 100644 --- a/mv_machine_learning/face_recognition/include/mv_face_recognition_open.h +++ b/mv_machine_learning/face_recognition/include/mv_face_recognition_open.h @@ -21,39 +21,6 @@ #include #include -/** - * @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 index 00000000..db563ac2 --- /dev/null +++ b/mv_machine_learning/face_recognition/meta/face_recognition.json @@ -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 + } + ] +} diff --git a/mv_machine_learning/face_recognition/src/face_recognition.cpp b/mv_machine_learning/face_recognition/src/face_recognition.cpp index ecf0d268..11ad1a2a 100644 --- a/mv_machine_learning/face_recognition/src/face_recognition.cpp +++ b/mv_machine_learning/face_recognition/src/face_recognition.cpp @@ -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 index 00000000..de0abb95 --- /dev/null +++ b/mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp @@ -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 +FaceRecognitionAdapter::FaceRecognitionAdapter() +{ + _face_recognition = make_unique(); +} + +template +FaceRecognitionAdapter::~FaceRecognitionAdapter() +{ + +} + +template +void FaceRecognitionAdapter::configure() +{ + _config = make_unique(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 +void FaceRecognitionAdapter::prepare() +{ + int ret = _face_recognition->Initialize(); + if (ret != MEDIA_VISION_ERROR_NONE) + throw InvalidOperation("Fail to initialize face recognition."); +} + +template +void FaceRecognitionAdapter::setInput(T& t) +{ + _source = t; +} + +template +void FaceRecognitionAdapter::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 +V& FaceRecognitionAdapter::getOutput() +{ + return _face_recognition->GetResult(); +} + +template class FaceRecognitionAdapter; +} +} \ No newline at end of file diff --git a/mv_machine_learning/face_recognition/src/mv_face_recognition_open.cpp b/mv_machine_learning/face_recognition/src/mv_face_recognition_open.cpp index ef5b8c1a..d34b699e 100644 --- a/mv_machine_learning/face_recognition/src/mv_face_recognition_open.cpp +++ b/mv_machine_learning/face_recognition/src/mv_face_recognition_open.cpp @@ -18,13 +18,15 @@ #include #include -#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(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 *itask = + new (nothrow)FaceRecognitionAdapter(); + if (!itask) { + delete context; + LOGE("Fail to allocate a itask."); + return MEDIA_VISION_ERROR_OUT_OF_MEMORY; + } + + pair::iterator, bool> result; + + result = context->__itasks.insert(pair("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(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(handle); + Context *context = static_cast(handle); + map::iterator iter; + + for (iter = context->__itasks.begin(); iter != context->__itasks.end(); ++iter) { + auto itask = static_cast *>(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(handle); + auto itask = static_cast *>(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(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(handle); + try { + Context *context = static_cast(handle); + auto itask = static_cast *>(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(handle); + try { + Context *context = static_cast(handle); + auto itask = static_cast *>(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(handle); + try { + Context *context = static_cast(handle); + auto itask = static_cast *>(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(handle); + try { + Context *context = static_cast(handle); + auto itask = static_cast *>(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"); diff --git a/packaging/capi-media-vision.spec b/packaging/capi-media-vision.spec index b5a958e9..5ac71bde 100644 --- a/packaging/capi-media-vision.spec +++ b/packaging/capi-media-vision.spec @@ -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