From d8ab87ec9c01e38d1aaf9bd7d2bcacd058abc36c Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Wed, 25 Oct 2023 20:07:07 +0900 Subject: [PATCH] mv_machine_learning: use DEFAULT_MODEL_NAME for landmark detection task group [Issue type] : new feature Use the meta file for landmark detection tasks to set the default model With this patch, a proper concrete class object will be created at the constructor of FacialLandmarkAdapter and PoseLandmarkAdapter classes according to the default model names which are parsed from each meta file, facial_landmark.json and pose_landmark.json files. And also this patch calls the member function, create, to create the concrete class object corresponding to the default model name instead of creating a default concrete class object directly. Finally, we can create user-desired concrete class object without rebuilding by simply modifying the meta files. Change-Id: I4ef045fe1ae24177ae4ebc7a3f48ae6e136c01dc Signed-off-by: Inki Dae --- .../include/facial_landmark_adapter.h | 2 + .../include/landmark_detection_type.h | 2 - .../include/mv_landmark_detection_config.h | 8 +++ .../include/pose_landmark_adapter.h | 2 + .../landmark_detection/meta/facial_landmark.json | 5 ++ .../landmark_detection/meta/pose_landmark.json | 5 ++ .../src/facial_landmark_adapter.cpp | 65 ++++++++++++--------- .../src/pose_landmark_adapter.cpp | 68 +++++++++++++--------- 8 files changed, 103 insertions(+), 54 deletions(-) diff --git a/mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h b/mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h index 82f8e1c..5061e75 100644 --- a/mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h +++ b/mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h @@ -36,8 +36,10 @@ private: std::string _model_file; std::string _meta_file; std::string _label_file; + const std::string _config_file_name = "facial_landmark.json"; void create(LandmarkDetectionTaskType task_type); + LandmarkDetectionTaskType convertToTaskType(std::string model_name); public: FacialLandmarkAdapter(); diff --git a/mv_machine_learning/landmark_detection/include/landmark_detection_type.h b/mv_machine_learning/landmark_detection/include/landmark_detection_type.h index 66464c0..13ce7c5 100644 --- a/mv_machine_learning/landmark_detection/include/landmark_detection_type.h +++ b/mv_machine_learning/landmark_detection/include/landmark_detection_type.h @@ -28,7 +28,6 @@ namespace machine_learning { struct LandmarkDetectionInput { mv_source_h inference_src; - // TODO. }; struct LandmarkDetectionResult { @@ -44,7 +43,6 @@ enum class LandmarkDetectionTaskType { LANDMARK_DETECTION_TASK_NONE = 0, FLD_TWEAK_CNN, PLD_CPM - // TODO }; } diff --git a/mv_machine_learning/landmark_detection/include/mv_landmark_detection_config.h b/mv_machine_learning/landmark_detection/include/mv_landmark_detection_config.h index 2266bcf..cb8a3b7 100644 --- a/mv_machine_learning/landmark_detection/include/mv_landmark_detection_config.h +++ b/mv_machine_learning/landmark_detection/include/mv_landmark_detection_config.h @@ -34,6 +34,14 @@ #define MV_LANDMARK_DETECTION_MODEL_FILE_PATH "MODEL_FILE_NAME" /** + * @brief Defines #MV_LANDMARK_DETECTION_DEFAULT_MODEL_NAME + * to set the landmark detection default model name. + * + * @since_tizen 8.0 + */ +#define MV_LANDMARK_DETECTION_DEFAULT_MODEL_NAME "DEFAULT_MODEL_NAME" + +/** * @brief Defines #MV_LANDMARK_DETECTION_MODEL_META_FILE_PATH to set inference * models's metadata file attribute of the engine configuration. * @details The file includes inference model's metadata such as input and output diff --git a/mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h b/mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h index b9659f1..e8879b6 100644 --- a/mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h +++ b/mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h @@ -36,8 +36,10 @@ private: std::string _model_file; std::string _meta_file; std::string _label_file; + const std::string _config_file_name = "pose_landmark.json"; void create(LandmarkDetectionTaskType task_type); + LandmarkDetectionTaskType convertToTaskType(std::string model_name); public: PoseLandmarkAdapter(); diff --git a/mv_machine_learning/landmark_detection/meta/facial_landmark.json b/mv_machine_learning/landmark_detection/meta/facial_landmark.json index 2c5cc69..ad7f7b8 100644 --- a/mv_machine_learning/landmark_detection/meta/facial_landmark.json +++ b/mv_machine_learning/landmark_detection/meta/facial_landmark.json @@ -12,6 +12,11 @@ "value" : "fld_tweakcnn_128x128.tflite" }, { + "name" : "DEFAULT_MODEL_NAME", + "type" : "string", + "value" : "FLD_TWEAK_CNN" + }, + { "name" : "META_FILE_NAME", "type" : "string", "value" : "fld_tweakcnn_128x128.json" diff --git a/mv_machine_learning/landmark_detection/meta/pose_landmark.json b/mv_machine_learning/landmark_detection/meta/pose_landmark.json index 787b3a8..a8637f8 100644 --- a/mv_machine_learning/landmark_detection/meta/pose_landmark.json +++ b/mv_machine_learning/landmark_detection/meta/pose_landmark.json @@ -12,6 +12,11 @@ "value" : "pld_cpm_192x192.tflite" }, { + "name" : "DEFAULT_MODEL_NAME", + "type" : "string", + "value" : "PLD_CPM" + }, + { "name" : "META_FILE_NAME", "type" : "string", "value" : "pld_cpm_192x192.json" diff --git a/mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp b/mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp index 58677e9..5f649d7 100644 --- a/mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp +++ b/mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp @@ -16,6 +16,7 @@ #include "machine_learning_exception.h" #include "facial_landmark_adapter.h" +#include "mv_landmark_detection_config.h" using namespace std; using namespace MediaVision::Common; @@ -28,10 +29,15 @@ namespace machine_learning { template FacialLandmarkAdapter::FacialLandmarkAdapter() : _source() { - // In default, Mobilenet v1 ssd model will be used. - // If other model is set by user then strategy pattern will be used - // to create its corresponding concrete class by calling create(). - _landmark_detection = make_unique(LandmarkDetectionTaskType::FLD_TWEAK_CNN); + auto config = make_unique(MV_CONFIG_PATH + _config_file_name); + + string defaultModelName; + + int ret = config->getStringAttribute(MV_LANDMARK_DETECTION_DEFAULT_MODEL_NAME, &defaultModelName); + if (ret != MEDIA_VISION_ERROR_NONE) + throw InvalidOperation("Fail to get default model name."); + + create(convertToTaskType(defaultModelName)); } template FacialLandmarkAdapter::~FacialLandmarkAdapter() @@ -41,40 +47,47 @@ template FacialLandmarkAdapter::~FacialLandmarkAda template void FacialLandmarkAdapter::create(LandmarkDetectionTaskType task_type) { - // If default task type is same as a given one then skip. - if (_landmark_detection->getTaskType() == task_type) - return; - - _landmark_detection.reset(); + if (_landmark_detection) { + // If current task type is same as a given one then skip. + if (_landmark_detection->getTaskType() == task_type) + return; + } if (task_type == LandmarkDetectionTaskType::FLD_TWEAK_CNN) _landmark_detection = make_unique(task_type); - // TODO. } template -void FacialLandmarkAdapter::setModelInfo(const char *model_file, const char *meta_file, const char *label_file, - const char *model_name) +LandmarkDetectionTaskType FacialLandmarkAdapter::convertToTaskType(string model_name) { - string model_name_str(model_name); + if (model_name.empty()) + throw InvalidParameter("model name is empty."); - if (!model_name_str.empty()) { - transform(model_name_str.begin(), model_name_str.end(), model_name_str.begin(), ::toupper); + transform(model_name.begin(), model_name.end(), model_name.begin(), ::toupper); - LandmarkDetectionTaskType task_type = LandmarkDetectionTaskType::LANDMARK_DETECTION_TASK_NONE; + if (model_name == "FLD_TWEAK_CNN") + return LandmarkDetectionTaskType::FLD_TWEAK_CNN; + // TODO. - if (model_name_str == string("FLD_TWEAK_CNN")) - task_type = LandmarkDetectionTaskType::FLD_TWEAK_CNN; - // TODO. - else - throw InvalidParameter("Invalid landmark detection model name."); + throw InvalidParameter("Invalid facial detection model name."); +} - create(task_type); +template +void FacialLandmarkAdapter::setModelInfo(const char *model_file, const char *meta_file, const char *label_file, + const char *model_name) +{ + try { + create(convertToTaskType(model_name)); + } catch (const BaseException &e) { + LOGW("A given model name is invalid so default task type will be used."); } - _model_file = string(model_file); - _meta_file = string(meta_file); - _label_file = string(label_file); + if (model_file) + _model_file = model_file; + if (meta_file) + _meta_file = meta_file; + if (label_file) + _label_file = label_file; if (_model_file.empty() && _meta_file.empty()) { LOGW("Given model info is invalid so default model info will be used instead."); @@ -92,7 +105,7 @@ void FacialLandmarkAdapter::setEngineInfo(const char *engine_type, const c template void FacialLandmarkAdapter::configure() { - _landmark_detection->configure("facial_landmark.json"); + _landmark_detection->configure(_config_file_name); } template void FacialLandmarkAdapter::getNumberOfEngines(unsigned int *number_of_engines) diff --git a/mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp b/mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp index c1a3fa1..2bd4bc3 100644 --- a/mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp +++ b/mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp @@ -16,6 +16,7 @@ #include "machine_learning_exception.h" #include "pose_landmark_adapter.h" +#include "mv_landmark_detection_config.h" using namespace std; using namespace MediaVision::Common; @@ -28,10 +29,15 @@ namespace machine_learning { template PoseLandmarkAdapter::PoseLandmarkAdapter() : _source() { - // In default, Mobilenet v1 ssd model will be used. - // If other model is set by user then strategy pattern will be used - // to create its corresponding concrete class by calling create(). - _landmark_detection = make_unique(LandmarkDetectionTaskType::PLD_CPM); + auto config = make_unique(MV_CONFIG_PATH + _config_file_name); + + string defaultModelName; + + int ret = config->getStringAttribute(MV_LANDMARK_DETECTION_DEFAULT_MODEL_NAME, &defaultModelName); + if (ret != MEDIA_VISION_ERROR_NONE) + throw InvalidOperation("Fail to get default model name."); + + create(convertToTaskType(defaultModelName)); } template PoseLandmarkAdapter::~PoseLandmarkAdapter() @@ -41,40 +47,50 @@ template PoseLandmarkAdapter::~PoseLandmarkAdapter template void PoseLandmarkAdapter::create(LandmarkDetectionTaskType task_type) { - // If default task type is same as a given one then skip. - if (_landmark_detection->getTaskType() == task_type) - return; - - _landmark_detection.reset(); + // If a concrete class object created already exists, reset the object + // so that other concrete class object can be created again according to a given task_type. + if (_landmark_detection) { + // If default task type is same as a given one then skip. + if (_landmark_detection->getTaskType() == task_type) + return; + } if (task_type == LandmarkDetectionTaskType::PLD_CPM) _landmark_detection = make_unique(task_type); - // TODO. } template -void PoseLandmarkAdapter::setModelInfo(const char *model_file, const char *meta_file, const char *label_file, - const char *model_name) +LandmarkDetectionTaskType PoseLandmarkAdapter::convertToTaskType(string model_name) { - string model_name_str(model_name); + if (model_name.empty()) + throw InvalidParameter("model name is empty."); + + transform(model_name.begin(), model_name.end(), model_name.begin(), ::toupper); - if (!model_name_str.empty()) { - transform(model_name_str.begin(), model_name_str.end(), model_name_str.begin(), ::toupper); + LandmarkDetectionTaskType task_type = LandmarkDetectionTaskType::LANDMARK_DETECTION_TASK_NONE; - LandmarkDetectionTaskType task_type = LandmarkDetectionTaskType::LANDMARK_DETECTION_TASK_NONE; + if (model_name == "PLD_CPM") + return LandmarkDetectionTaskType::PLD_CPM; - if (model_name_str == string("PLD_CPM")) - task_type = LandmarkDetectionTaskType::PLD_CPM; - // TODO. - else - throw InvalidParameter("Invalid landmark detection model name."); + throw InvalidParameter("Invalid pose landmark model name."); +} - create(task_type); +template +void PoseLandmarkAdapter::setModelInfo(const char *model_file, const char *meta_file, const char *label_file, + const char *model_name) +{ + try { + create(convertToTaskType(model_name)); + } catch (const BaseException &e) { + LOGW("A given model name is invalid so default task type will be used."); } - _model_file = string(model_file); - _meta_file = string(meta_file); - _label_file = string(label_file); + if (model_file) + _model_file = model_file; + if (meta_file) + _meta_file = meta_file; + if (label_file) + _label_file = label_file; if (_model_file.empty() && _meta_file.empty()) { LOGW("Given model info is invalid so default model info will be used instead."); @@ -92,7 +108,7 @@ void PoseLandmarkAdapter::setEngineInfo(const char *engine_type, const cha template void PoseLandmarkAdapter::configure() { - _landmark_detection->configure("pose_landmark.json"); + _landmark_detection->configure(_config_file_name); } template void PoseLandmarkAdapter::getNumberOfEngines(unsigned int *number_of_engines) -- 2.7.4