mv_machine_learning: drop parsing dependency from object detection 3d
authorInki Dae <inki.dae@samsung.com>
Mon, 6 Nov 2023 07:05:46 +0000 (16:05 +0900)
committerInki Dae <inki.dae@samsung.com>
Tue, 14 Nov 2023 07:40:17 +0000 (16:40 +0900)
[Issue type] : code refactoring

Drop the configuration and meta file parsing dependency from ObjectDetection3d
class.

Until now, the concrete class of each task group got the task group
configuration information from its own configuration file, and also
included a MetaParser class object to get the tensor information,
which is corresponding to a given model file.

However, these dependencies led code smell, divergent change[1] even though
the concrete class has no any dependency from parsing the configuration and
meta files - needed only information after parsed.

As a first refactoring work, this patch extracts parsing portion from
ObjectDetection3d class and introduces as a new class, ObjectDetection3dConfig
class.

With this, adapter classes of the object detection 3d task group will parse
the configuration and meta files before creating ObjectDetection3d class.
And then it will create ObjectDetection3d class with needed information.
As a result, we could manage the ObjectDetection3d class without any
dependency on parsing work.

[1] https://refactoring.guru/smells/divergent-change

Change-Id: Ia3955a841179c802437f175e783762affc258b4d
Signed-off-by: Inki Dae <inki.dae@samsung.com>
mv_machine_learning/object_detection_3d/include/mv_object_detection_3d_config.h
mv_machine_learning/object_detection_3d/include/object_detection_3d.h
mv_machine_learning/object_detection_3d/include/object_detection_3d_adapter.h
mv_machine_learning/object_detection_3d/include/object_detection_3d_config.h [new file with mode: 0644]
mv_machine_learning/object_detection_3d/include/objectron.h
mv_machine_learning/object_detection_3d/meta/object_detection_3d.json
mv_machine_learning/object_detection_3d/src/object_detection_3d.cpp
mv_machine_learning/object_detection_3d/src/object_detection_3d_adapter.cpp
mv_machine_learning/object_detection_3d/src/object_detection_3d_config.cpp [new file with mode: 0644]
mv_machine_learning/object_detection_3d/src/objectron.cpp

index 8dd8e37..02518b7 100644 (file)
 #define MV_OBJECT_DETECTION_3D_MODEL_FILE_PATH "MODEL_FILE_NAME"
 
 /**
+ * @brief Defines #MV_OBJECT_DETECTION_3D_DEFAULT_MODEL_NAME
+ *        to set the landmark detection default model name.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_OBJECT_DETECTION_3D_DEFAULT_MODEL_NAME "DEFAULT_MODEL_NAME"
+
+/**
  * @brief Defines #MV_OBJECT_DETECTION_3D_3D_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
@@ -64,6 +72,4 @@
 
 #define MV_OBJECT_DETECTION_3D_3D_MAX_NUM_OF_EDGES "MAX_NUM_OF_EDGES"
 
-#define MV_OBJECT_DETECTION_3D_META_FILE_NAME "object_detection_3d.json"
-
 #endif /* __MEDIA_VISION_INFERENCE_OPEN_H__ */
index e4401bb..8397797 100644 (file)
@@ -25,7 +25,9 @@
 #include "inference_engine_common_impl.h"
 #include "Inference.h"
 #include "object_detection_3d_type.h"
+#include "MetaParser.h"
 #include "ObjectDetection3dParser.h"
+#include "object_detection_3d_config.h"
 #include "machine_learning_preprocess.h"
 
 namespace mediavision
@@ -35,25 +37,19 @@ namespace machine_learning
 class ObjectDetection3d
 {
 private:
+       ObjectDetection3dTaskType _task_type;
+
+       void loadLabel();
        void getEngineList();
        void getDeviceList(const char *engine_type);
 
-       ObjectDetection3dTaskType _task_type;
-
 protected:
        std::unique_ptr<mediavision::inference::Inference> _inference;
-       std::unique_ptr<MediaVision::Common::EngineConfig> _config;
-       std::unique_ptr<MetaParser> _parser;
+       std::shared_ptr<ObjectDetection3dConfig> _config;
        std::vector<std::string> _labels;
        std::vector<std::string> _valid_backends;
        std::vector<std::string> _valid_devices;
        Preprocess _preprocess;
-       std::string _modelFilePath;
-       std::string _modelMetaFilePath;
-       std::string _modelDefaultPath;
-       std::string _modelLabelFilePath;
-       int _backendType;
-       int _targetDeviceType;
 
        void getOutputNames(std::vector<std::string> &names);
        void getOutputTensor(std::string &target_name, std::vector<float> &tensor);
@@ -62,18 +58,17 @@ protected:
        template<typename T> void inference(std::vector<std::vector<T> > &inputVectors);
 
 public:
-       ObjectDetection3d(ObjectDetection3dTaskType task_type);
+       ObjectDetection3d(ObjectDetection3dTaskType task_type, std::shared_ptr<ObjectDetection3dConfig> config);
        virtual ~ObjectDetection3d() = default;
 
        ObjectDetection3dTaskType getTaskType();
        void setUserModel(std::string model_file, std::string meta_file, std::string label_file);
-       void setEngineInfo(std::string engine_type, std::string device_type);
+       void setEngineInfo(std::string engine_type_name, std::string device_type_name);
        void getNumberOfEngines(unsigned int *number_of_engines);
        void getEngineType(unsigned int engine_index, char **engine_type);
        void getNumberOfDevices(const char *engine_type, unsigned int *number_of_devices);
        void getDeviceType(const char *engine_type, const unsigned int device_index, char **device_type);
        std::shared_ptr<MetaInfo> getInputMetaInfo();
-       void parseMetaFile();
        void configure();
        void prepare();
        template<typename T> void perform(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo);
index 192dca8..edfff67 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "EngineConfig.h"
 #include "itask.h"
+#include "object_detection_3d_config.h"
 #include "objectron.h"
 
 namespace mediavision
@@ -31,13 +32,12 @@ template<typename T, typename V> class ObjectDetection3dAdapter : public mediavi
 {
 private:
        std::unique_ptr<ObjectDetection3d> _object_detection_3d;
+       std::shared_ptr<ObjectDetection3dConfig> _config;
        T _source;
-       std::string _model_name;
-       std::string _model_file;
-       std::string _meta_file;
-       std::string _label_file;
+       const std::string _config_file_name = "object_detection_3d.json";
 
        void create(ObjectDetection3dTaskType task_type);
+       ObjectDetection3dTaskType convertToTaskType(std::string model_name);
 
 public:
        ObjectDetection3dAdapter();
diff --git a/mv_machine_learning/object_detection_3d/include/object_detection_3d_config.h b/mv_machine_learning/object_detection_3d/include/object_detection_3d_config.h
new file mode 100644 (file)
index 0000000..0c427ab
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * 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 __OBJECT_DETECTION_3D_CONFIG_H__
+#define __OBJECT_DETECTION_3D_CONFIG_H__
+
+#include <mv_common.h>
+#include "mv_private.h"
+#include "EngineConfig.h"
+
+#include "MetaParser.h"
+#include "object_detection_3d_type.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ObjectDetection3dConfig
+{
+private:
+       std::unique_ptr<MetaParser> _parser;
+       std::string _defaultModelName;
+       std::string _modelFilePath;
+       std::string _modelMetaFilePath;
+       std::string _modelDefaultPath;
+       std::string _modelLabelFilePath;
+       int _backendType {};
+       int _targetDeviceType {};
+       double _confidence_threshold {};
+
+public:
+       ObjectDetection3dConfig();
+       virtual ~ObjectDetection3dConfig() = default;
+
+       void setUserModel(const std::string &model_file, const std::string &meta_file, const std::string &label_file);
+       void parseConfigFile(const std::string &configFilePath);
+       void parseMetaFile();
+       void setBackendType(int backend_type);
+       void setTargetDeviceType(int device_type);
+       const std::string &getDefaultModelName() const;
+       const std::string &getModelFilePath() const;
+       const std::string &getLabelFilePath() const;
+       MetaMap &getInputMetaMap() const;
+       MetaMap &getOutputMetaMap() const;
+       double getConfidenceThreshold() const;
+       int getBackendType() const;
+       int getTargetDeviceType() const;
+       void loadMetaFile();
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
index 9512009..8fb83f7 100644 (file)
@@ -34,7 +34,7 @@ private:
        ObjectDetection3dResult _result;
 
 public:
-       Objectron(ObjectDetection3dTaskType task_type);
+       Objectron(ObjectDetection3dTaskType task_type, std::shared_ptr<ObjectDetection3dConfig> config);
        ~Objectron();
 
        ObjectDetection3dResult &result() override;
index ff63bc1..27adcad 100644 (file)
             "value" : "object_detection_3d_cup.tflite"
         },
         {
+            "name"  : "DEFAULT_MODEL_NAME",
+            "type"  : "string",
+            "value" : "OBJECTRON"
+        },
+        {
             "name"  : "META_FILE_NAME",
             "type"  : "string",
             "value" : "object_detection_3d_cup.json"
index d620aa9..bddfc16 100644 (file)
  */
 
 #include <string.h>
+#include <fstream>
 #include <map>
 #include <memory>
 #include <algorithm>
 
 #include "machine_learning_exception.h"
 #include "mv_machine_learning_common.h"
-#include "mv_object_detection_3d_config.h"
 #include "object_detection_3d.h"
 
 using namespace std;
@@ -34,13 +34,12 @@ namespace mediavision
 {
 namespace machine_learning
 {
-ObjectDetection3d::ObjectDetection3d(ObjectDetection3dTaskType task_type)
-               : _task_type(task_type)
-               , _backendType(MV_INFERENCE_BACKEND_NONE)
-               , _targetDeviceType(MV_INFERENCE_TARGET_DEVICE_NONE)
+ObjectDetection3d::ObjectDetection3d(ObjectDetection3dTaskType task_type,
+                                                                        std::shared_ptr<ObjectDetection3dConfig> config)
+               : _task_type(task_type), _config(config)
 {
        _inference = make_unique<Inference>();
-       _parser = make_unique<ObjectDetection3dParser>();
+       loadLabel();
 }
 
 ObjectDetection3dTaskType ObjectDetection3d::getTaskType()
@@ -68,23 +67,25 @@ void ObjectDetection3d::getDeviceList(const char *engine_type)
        _valid_devices.push_back("gpu");
 }
 
-void ObjectDetection3d::setEngineInfo(std::string engine_type, std::string device_type)
+void ObjectDetection3d::setEngineInfo(std::string engine_type_name, std::string device_type_name)
 {
-       if (engine_type.empty() || device_type.empty())
+       if (engine_type_name.empty() || device_type_name.empty())
                throw InvalidParameter("Invalid engine info.");
 
-       transform(engine_type.begin(), engine_type.end(), engine_type.begin(), ::toupper);
-       transform(device_type.begin(), device_type.end(), device_type.begin(), ::toupper);
+       transform(engine_type_name.begin(), engine_type_name.end(), engine_type_name.begin(), ::toupper);
+       transform(device_type_name.begin(), device_type_name.end(), device_type_name.begin(), ::toupper);
 
-       _backendType = GetBackendType(engine_type);
-       _targetDeviceType = GetDeviceType(device_type);
+       int engine_type = GetBackendType(engine_type_name);
+       int device_type = GetDeviceType(device_type_name);
 
-       LOGI("Engine type : %s => %d, Device type : %s => %d", engine_type.c_str(), GetBackendType(engine_type),
-                device_type.c_str(), GetDeviceType(device_type));
-
-       if (_backendType == MEDIA_VISION_ERROR_INVALID_PARAMETER ||
-               _targetDeviceType == MEDIA_VISION_ERROR_INVALID_PARAMETER)
+       if (engine_type == MEDIA_VISION_ERROR_INVALID_PARAMETER || device_type == MEDIA_VISION_ERROR_INVALID_PARAMETER)
                throw InvalidParameter("backend or target device type not found.");
+
+       _config->setBackendType(engine_type);
+       _config->setTargetDeviceType(device_type);
+
+       LOGI("Engine type : %s => %d, Device type : %s => %d", engine_type_name.c_str(), engine_type,
+                device_type_name.c_str(), device_type);
 }
 
 void ObjectDetection3d::getNumberOfEngines(unsigned int *number_of_engines)
@@ -145,84 +146,42 @@ void ObjectDetection3d::getDeviceType(const char *engine_type, const unsigned in
        *device_type = const_cast<char *>(_valid_devices[device_index].data());
 }
 
-void ObjectDetection3d::setUserModel(string model_file, string meta_file, string label_file)
-{
-       _modelFilePath = model_file;
-       _modelMetaFilePath = meta_file;
-       _modelLabelFilePath = label_file;
-}
-
-static bool IsJsonFile(const string &fileName)
+void ObjectDetection3d::loadLabel()
 {
-       return (!fileName.substr(fileName.find_last_of(".") + 1).compare("json"));
-}
-
-void ObjectDetection3d::parseMetaFile()
-{
-       int ret = MEDIA_VISION_ERROR_NONE;
-       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(MV_OBJECT_DETECTION_3D_META_FILE_NAME));
-
-       if (_backendType == MV_INFERENCE_BACKEND_NONE) {
-               ret = _config->getIntegerAttribute(MV_OBJECT_DETECTION_3D_BACKEND_TYPE, &_backendType);
-               if (ret != MEDIA_VISION_ERROR_NONE)
-                       throw InvalidOperation("Fail to get backend engine type.");
-       }
-
-       if (_targetDeviceType == MV_INFERENCE_TARGET_DEVICE_NONE) {
-               ret = _config->getIntegerAttribute(MV_OBJECT_DETECTION_3D_TARGET_DEVICE_TYPE, &_targetDeviceType);
-               if (ret != MEDIA_VISION_ERROR_NONE)
-                       throw InvalidOperation("Fail to get target device type.");
-       }
-
-       string modelDefaultPath;
-
-       ret = _config->getStringAttribute(MV_OBJECT_DETECTION_3D_MODEL_DEFAULT_PATH, &modelDefaultPath);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model default path");
-
-       if (_modelFilePath.empty()) {
-               ret = _config->getStringAttribute(MV_OBJECT_DETECTION_3D_MODEL_FILE_PATH, &_modelFilePath);
-               if (ret != MEDIA_VISION_ERROR_NONE)
-                       throw InvalidOperation("Fail to get model file path");
-       }
-
-       _modelFilePath = modelDefaultPath + _modelFilePath;
+       if (_config->getLabelFilePath().empty())
+               return;
 
-       if (_modelMetaFilePath.empty()) {
-               ret = _config->getStringAttribute(MV_OBJECT_DETECTION_3D_MODEL_META_FILE_PATH, &_modelMetaFilePath);
-               if (ret != MEDIA_VISION_ERROR_NONE)
-                       throw InvalidOperation("Fail to get model meta file path");
+       ifstream readFile { _config->getLabelFilePath() };
 
-               if (_modelMetaFilePath.empty())
-                       throw InvalidOperation("Model meta file doesn't exist.");
+       _labels.clear();
 
-               if (!IsJsonFile(_modelMetaFilePath))
-                       throw InvalidOperation("Model meta file should be json");
-       }
+       if (readFile.fail())
+               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
 
-       _modelMetaFilePath = modelDefaultPath + _modelMetaFilePath;
+       string line;
 
-       _parser->load(_modelMetaFilePath);
+       while (getline(readFile, line))
+               _labels.push_back(line);
 }
 
 void ObjectDetection3d::configure()
 {
-       int ret = _inference->bind(_backendType, _targetDeviceType);
+       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to bind a backend engine.");
 }
 
 void ObjectDetection3d::prepare()
 {
-       int ret = _inference->configureInputMetaInfo(_parser->getInputMetaMap());
+       int ret = _inference->configureInputMetaInfo(_config->getInputMetaMap());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to configure input tensor info from meta file.");
 
-       ret = _inference->configureOutputMetaInfo(_parser->getOutputMetaMap());
+       ret = _inference->configureOutputMetaInfo(_config->getOutputMetaMap());
        if (ret != MEDIA_VISION_ERROR_NONE)
                throw InvalidOperation("Fail to configure output tensor info from meta file.");
 
-       _inference->configureModelFiles("", _modelFilePath, "");
+       _inference->configureModelFiles("", _config->getModelFilePath(), "");
 
        // Request to load model files to a backend engine.
        ret = _inference->load();
@@ -242,7 +201,7 @@ shared_ptr<MetaInfo> ObjectDetection3d::getInputMetaInfo()
        auto tensor_buffer_iter = tensor_info_map.begin();
 
        // Get the meta information corresponding to a given input tensor name.
-       return _parser->getInputMetaMap()[tensor_buffer_iter->first];
+       return _config->getInputMetaMap()[tensor_buffer_iter->first];
 }
 
 template<typename T>
index 4c0ca5c..7a292e9 100644 (file)
@@ -28,42 +28,56 @@ namespace machine_learning
 {
 template<typename T, typename V> ObjectDetection3dAdapter<T, V>::ObjectDetection3dAdapter() : _source()
 {
-       _object_detection_3d = make_unique<Objectron>(ObjectDetection3dTaskType::OBJECTRON);
+       _config = make_shared<ObjectDetection3dConfig>();
+       _config->parseConfigFile(_config_file_name);
+       create(convertToTaskType(_config->getDefaultModelName()));
 }
 
 template<typename T, typename V> ObjectDetection3dAdapter<T, V>::~ObjectDetection3dAdapter()
 {}
 
 template<typename T, typename V> void ObjectDetection3dAdapter<T, V>::create(ObjectDetection3dTaskType task_type)
-{}
+{
+       if (_object_detection_3d) {
+               // If current task type is same as a given one then skip.
+               if (_object_detection_3d->getTaskType() == task_type)
+                       return;
+       }
+
+       // if model name is changed by user then reallocate the parser and reload the meta file corresponding to the model name.
+       _config->loadMetaFile();
+
+       if (task_type == ObjectDetection3dTaskType::OBJECTRON)
+               _object_detection_3d = make_unique<Objectron>(task_type, _config);
+}
 
 template<typename T, typename V>
-void ObjectDetection3dAdapter<T, V>::setModelInfo(const char *model_file, const char *meta_file, const char *label_file,
-                                                                                                 const char *model_name)
+ObjectDetection3dTaskType ObjectDetection3dAdapter<T, V>::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);
 
-               ObjectDetection3dTaskType task_type = ObjectDetection3dTaskType::OBJECT_DETECTION_3D_TASK_NONE;
+       if (model_name == "OBJECTRON")
+               return ObjectDetection3dTaskType::OBJECTRON;
 
-               if (model_name_str == string("OBJECTRON"))
-                       task_type = ObjectDetection3dTaskType::OBJECTRON;
-               else
-                       throw InvalidParameter("Invalid object detection 3d model name.");
+       throw InvalidParameter("Invalid object detection 3d model name.");
+}
 
-               create(task_type);
+template<typename T, typename V>
+void ObjectDetection3dAdapter<T, V>::setModelInfo(const char *model_file, const char *meta_file, const char *label_file,
+                                                                                                 const char *model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               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.empty() && _meta_file.empty() && _label_file.empty())
+       if (!model_file && !meta_file)
                throw InvalidParameter("Model info not invalid.");
-
-       _object_detection_3d->setUserModel(_model_file, _meta_file, _label_file);
 }
 
 template<typename T, typename V>
@@ -74,7 +88,6 @@ void ObjectDetection3dAdapter<T, V>::setEngineInfo(const char *engine_type, cons
 
 template<typename T, typename V> void ObjectDetection3dAdapter<T, V>::configure()
 {
-       _object_detection_3d->parseMetaFile();
        _object_detection_3d->configure();
 }
 
diff --git a/mv_machine_learning/object_detection_3d/src/object_detection_3d_config.cpp b/mv_machine_learning/object_detection_3d/src/object_detection_3d_config.cpp
new file mode 100644 (file)
index 0000000..3f8c804
--- /dev/null
@@ -0,0 +1,152 @@
+/**
+ * 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 "machine_learning_exception.h"
+#include "mv_object_detection_3d_config.h"
+#include "ObjectDetection3dParser.h"
+#include "object_detection_3d_config.h"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+ObjectDetection3dConfig::ObjectDetection3dConfig()
+{}
+
+void ObjectDetection3dConfig::setBackendType(int backend_type)
+{
+       _backendType = backend_type;
+}
+
+void ObjectDetection3dConfig::setTargetDeviceType(int device_type)
+{
+       _targetDeviceType = device_type;
+}
+
+const std::string &ObjectDetection3dConfig::getDefaultModelName() const
+{
+       return _defaultModelName;
+}
+
+const std::string &ObjectDetection3dConfig::getModelFilePath() const
+{
+       return _modelFilePath;
+}
+
+const std::string &ObjectDetection3dConfig::getLabelFilePath() const
+{
+       return _modelLabelFilePath;
+}
+
+MetaMap &ObjectDetection3dConfig::getInputMetaMap() const
+{
+       return _parser->getInputMetaMap();
+}
+
+MetaMap &ObjectDetection3dConfig::getOutputMetaMap() const
+{
+       return _parser->getOutputMetaMap();
+}
+
+double ObjectDetection3dConfig::getConfidenceThreshold() const
+{
+       return _confidence_threshold;
+}
+
+int ObjectDetection3dConfig::getBackendType() const
+{
+       return _backendType;
+}
+
+int ObjectDetection3dConfig::getTargetDeviceType() const
+{
+       return _targetDeviceType;
+}
+
+void ObjectDetection3dConfig::setUserModel(const string &model_file, const string &meta_file, const string &label_file)
+{
+       if (!model_file.empty())
+               _modelFilePath = _modelDefaultPath + model_file;
+       if (!meta_file.empty())
+               _modelMetaFilePath = _modelDefaultPath + meta_file;
+       if (!label_file.empty())
+               _modelLabelFilePath = _modelDefaultPath + label_file;
+}
+
+static bool IsJsonFile(const string &fileName)
+{
+       return (!fileName.substr(fileName.find_last_of(".") + 1).compare("json"));
+}
+
+void ObjectDetection3dConfig::parseConfigFile(const std::string &configFilePath)
+{
+       auto config = make_unique<EngineConfig>(MV_CONFIG_PATH + configFilePath);
+
+       int ret = config->getStringAttribute(MV_OBJECT_DETECTION_3D_DEFAULT_MODEL_NAME, &_defaultModelName);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get default model name.");
+
+       if (_backendType == MV_INFERENCE_BACKEND_NONE) {
+               ret = config->getIntegerAttribute(MV_OBJECT_DETECTION_3D_BACKEND_TYPE, &_backendType);
+               if (ret != MEDIA_VISION_ERROR_NONE)
+                       throw InvalidOperation("Fail to get backend engine type.");
+       }
+
+       if (_targetDeviceType == MV_INFERENCE_TARGET_DEVICE_NONE) {
+               ret = config->getIntegerAttribute(MV_OBJECT_DETECTION_3D_TARGET_DEVICE_TYPE, &_targetDeviceType);
+               if (ret != MEDIA_VISION_ERROR_NONE)
+                       throw InvalidOperation("Fail to get target device type.");
+       }
+
+       ret = config->getStringAttribute(MV_OBJECT_DETECTION_3D_MODEL_DEFAULT_PATH, &_modelDefaultPath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model default path");
+
+       if (_modelFilePath.empty()) {
+               ret = config->getStringAttribute(MV_OBJECT_DETECTION_3D_MODEL_FILE_PATH, &_modelFilePath);
+               if (ret != MEDIA_VISION_ERROR_NONE)
+                       throw InvalidOperation("Fail to get model file path");
+       }
+
+       _modelFilePath = _modelDefaultPath + _modelFilePath;
+
+       ret = config->getStringAttribute(MV_OBJECT_DETECTION_3D_MODEL_META_FILE_PATH, &_modelMetaFilePath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model meta file path");
+
+       if (_modelMetaFilePath.empty())
+               throw InvalidOperation("Model meta file doesn't exist.");
+
+       if (!IsJsonFile(_modelMetaFilePath))
+               throw InvalidOperation("Model meta file should be json");
+
+       _modelMetaFilePath = _modelDefaultPath + _modelMetaFilePath;
+       LOGI("meta file path = %s", _modelMetaFilePath.c_str());
+}
+
+void ObjectDetection3dConfig::loadMetaFile()
+{
+       _parser = make_unique<ObjectDetection3dParser>();
+       _parser->load(_modelMetaFilePath);
+}
+
+}
+}
\ No newline at end of file
index c32f2f5..22964b5 100644 (file)
@@ -30,7 +30,8 @@ namespace mediavision
 {
 namespace machine_learning
 {
-Objectron::Objectron(ObjectDetection3dTaskType task_type) : ObjectDetection3d(task_type), _result()
+Objectron::Objectron(ObjectDetection3dTaskType task_type, std::shared_ptr<ObjectDetection3dConfig> config)
+               : ObjectDetection3d(task_type, config), _result()
 {}
 
 Objectron::~Objectron()
@@ -70,7 +71,7 @@ ObjectDetection3dResult &Objectron::result()
 
        try {
                // names[1] is "Identity_1"
-               auto metaInfo = _parser->getOutputMetaMap().at(names[1]);
+               auto metaInfo = _config->getOutputMetaMap().at(names[1]);
                auto decodingBox = static_pointer_cast<DecodingBox>(metaInfo->decodingTypeMap[DecodingType::BOX]);
 
                for (size_t idx = 0; idx < decodingBox->edges.size(); idx += 2)