mv_machine_learning: introduce ObjectDetectionExternal class
authorInki Dae <inki.dae@samsung.com>
Mon, 12 Jun 2023 08:16:36 +0000 (17:16 +0900)
committerKwanghoon Son <k.son@samsung.com>
Tue, 4 Jul 2023 05:08:39 +0000 (14:08 +0900)
[Issue type] : new feature

Introduce ObjectDetectionExternal class which loads, unloads and manages
external plugin module provided as separate package.

If model name is given as "od_plugin" then object detection task group
will bind external plugin module and use it through ObjectDetectionExternal
class instead of internal behavior class, ObjectDetetion class.

Change-Id: If73ef7bb24e011b4375850100186f7a952ffca99
Signed-off-by: Inki Dae <inki.dae@samsung.com>
mv_machine_learning/object_detection/include/object_detection_external.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/object_detection_type.h
mv_machine_learning/object_detection/src/object_detection_adapter.cpp
mv_machine_learning/object_detection/src/object_detection_external.cpp [new file with mode: 0644]

diff --git a/mv_machine_learning/object_detection/include/object_detection_external.h b/mv_machine_learning/object_detection/include/object_detection_external.h
new file mode 100644 (file)
index 0000000..3768be7
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * 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_EXTERNAL_H__
+#define __OBJECT_DETECTION_EXTERNAL_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+#include <opencv2/core.hpp>
+#include <opencv2/imgproc.hpp>
+
+#include "object_detection_type.h"
+#include "iobject_detection.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ObjectDetectionExternal : public IObjectDetection
+{
+private:
+       void *_plugin_handle;
+       IObjectDetection *_object_detection_plugin;
+       ObjectDetectionTaskType _task_type {};
+       ObjectDetectionResult _current_result {};
+
+public:
+       ObjectDetectionExternal(ObjectDetectionTaskType task_type);
+       virtual ~ObjectDetectionExternal();
+       void preDestroy() override;
+       ObjectDetectionTaskType getTaskType() override;
+       void setUserModel(std::string model_file, std::string meta_file, std::string label_file) override;
+       void setEngineInfo(std::string engine_type, std::string device_type) override;
+       void getNumberOfEngines(unsigned int *number_of_engines) override;
+       void getEngineType(unsigned int engine_index, char **engine_type) override;
+       void getNumberOfDevices(const char *engine_type, unsigned int *number_of_devices) override;
+       void getDeviceType(const char *engine_type, const unsigned int device_index, char **device_type) override;
+       void configure(std::string configFile) override;
+       void prepare() override;
+       void perform(mv_source_h &mv_src) override;
+       void performAsync(ObjectDetectionInput &input) override;
+       ObjectDetectionResult &getOutput() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
index 4153ee5010777c03beaaa4c8892a5ece409d6bd6..bbd1fd5f82afe89c7e190803913e29d715b875d2 100644 (file)
@@ -62,7 +62,9 @@ enum class ObjectDetectionTaskType {
        OBJECT_DETECTION_TASK_NONE = 0,
        MOBILENET_V1_SSD,
        MOBILENET_V2_SSD,
-       FD_MOBILENET_V1_SSD
+       FD_MOBILENET_V1_SSD,
+       OD_PLUGIN,
+       FD_PLUGIN
        // TODO
 };
 
index d53250fe5a6d2841f028cef0bd3e89f67d9a2248..c6fde978cd7ca84ff7d2e4b83efe0fac732b40ad 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "machine_learning_exception.h"
 #include "object_detection_adapter.h"
+#include "object_detection_external.h"
 
 using namespace std;
 using namespace MediaVision::Common;
@@ -53,6 +54,8 @@ template<typename T, typename V> void ObjectDetectionAdapter<T, V>::create(int t
                _object_detection = make_unique<MobilenetV1Ssd>(task_type);
        else if (task_type == ObjectDetectionTaskType::MOBILENET_V2_SSD)
                _object_detection = make_unique<MobilenetV2Ssd>(task_type);
+       else if (task_type == ObjectDetectionTaskType::OD_PLUGIN)
+               _object_detection = make_unique<ObjectDetectionExternal>(task_type);
        // TODO.
 }
 
@@ -67,15 +70,25 @@ void ObjectDetectionAdapter<T, V>::setModelInfo(const char *model_file, const ch
 
                int model_type = 0;
 
-               if (model_name_str == string("MOBILENET_V1_SSD"))
+               if (model_name_str == "OD_PLUGIN") {
+                       model_type = static_cast<int>(ObjectDetectionTaskType::OD_PLUGIN);
+
+                       // In case of using plugin module, model information will be managed by the plugin module.
+                       // Therefore, create plugin instance now.
+                       create(model_type);
+                       return;
+               }
+
+               if (model_name_str == string("MOBILENET_V1_SSD")) {
                        model_type = static_cast<int>(ObjectDetectionTaskType::MOBILENET_V1_SSD);
-               else if (model_name_str == string("MOBILENET_V2_SSD"))
+               } else if (model_name_str == string("MOBILENET_V2_SSD")) {
                        model_type = static_cast<int>(ObjectDetectionTaskType::MOBILENET_V2_SSD);
-               // TODO.
-               else
+                       // TODO.
+               } else {
                        throw InvalidParameter("Invalid object detection model name.");
+               }
 
-               create(static_cast<int>(model_type));
+               create(model_type);
        }
 
        _model_file = string(model_file);
diff --git a/mv_machine_learning/object_detection/src/object_detection_external.cpp b/mv_machine_learning/object_detection/src/object_detection_external.cpp
new file mode 100644 (file)
index 0000000..e19a331
--- /dev/null
@@ -0,0 +1,142 @@
+/**
+ * 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 <dlfcn.h>
+#include <sys/stat.h>
+
+#include "mv_private.h"
+
+#include "machine_learning_exception.h"
+#include "object_detection_external.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+typedef IObjectDetection *create_t(void);
+typedef void destroy_t(IObjectDetection *);
+
+ObjectDetectionExternal::ObjectDetectionExternal(ObjectDetectionTaskType task_type)
+               : _plugin_handle(), _object_detection_plugin()
+{
+       // TODO. plugin module name will be given by configuration file later.
+       const char *module_name = "libobject-detection-plugin.so";
+
+       // Load external object detection library.
+       LOGI("lib: %s", module_name);
+       _plugin_handle = dlopen(module_name, RTLD_NOW);
+
+       if (!_plugin_handle)
+               throw InvalidOperation("Fail to open plugin library.");
+
+       create_t *createPlugin = (create_t *) dlsym(_plugin_handle, "createPlugin");
+       if (createPlugin == NULL) {
+               dlclose(_plugin_handle);
+               createPlugin = NULL;
+               throw InvalidOperation("Fail to get symbol from plugin library.");
+       }
+
+       _object_detection_plugin = createPlugin();
+       if (_object_detection_plugin == NULL) {
+               dlclose(_plugin_handle);
+               _plugin_handle = NULL;
+               throw InvalidOperation("Fail to create plugin module.");
+       }
+}
+
+ObjectDetectionExternal::~ObjectDetectionExternal()
+{
+       if (_plugin_handle) {
+               destroy_t *destroyPlugin = (destroy_t *) dlsym(_plugin_handle, "destroyPlugin");
+
+               destroyPlugin(_object_detection_plugin);
+               dlclose(_plugin_handle);
+               _object_detection_plugin = nullptr;
+               _plugin_handle = nullptr;
+       }
+}
+
+void ObjectDetectionExternal::preDestroy()
+{
+       _object_detection_plugin->preDestroy();
+}
+
+ObjectDetectionTaskType ObjectDetectionExternal::getTaskType()
+{
+       return _object_detection_plugin->getTaskType();
+}
+
+void ObjectDetectionExternal::setUserModel(std::string model_file, std::string meta_file, std::string label_file)
+{
+       _object_detection_plugin->setUserModel(model_file, meta_file, label_file);
+}
+
+void ObjectDetectionExternal::setEngineInfo(std::string engine_type, std::string device_type)
+{
+       _object_detection_plugin->setEngineInfo(engine_type, device_type);
+}
+
+void ObjectDetectionExternal::getNumberOfEngines(unsigned int *number_of_engines)
+{
+       _object_detection_plugin->getNumberOfEngines(number_of_engines);
+}
+
+void ObjectDetectionExternal::getEngineType(unsigned int engine_index, char **engine_type)
+{
+       _object_detection_plugin->getEngineType(engine_index, engine_type);
+}
+
+void ObjectDetectionExternal::getNumberOfDevices(const char *engine_type, unsigned int *number_of_devices)
+{
+       _object_detection_plugin->getNumberOfDevices(engine_type, number_of_devices);
+}
+
+void ObjectDetectionExternal::getDeviceType(const char *engine_type, const unsigned int device_index,
+                                                                                       char **device_type)
+{
+       _object_detection_plugin->getDeviceType(engine_type, device_index, device_type);
+}
+
+void ObjectDetectionExternal::configure(std::string configFile)
+{
+       _object_detection_plugin->configure(configFile);
+}
+
+void ObjectDetectionExternal::prepare()
+{
+       _object_detection_plugin->prepare();
+}
+
+void ObjectDetectionExternal::perform(mv_source_h &mv_src)
+{
+       _object_detection_plugin->perform(mv_src);
+}
+
+void ObjectDetectionExternal::performAsync(ObjectDetectionInput &input)
+{
+       _object_detection_plugin->performAsync(input);
+}
+
+ObjectDetectionResult &ObjectDetectionExternal::getOutput()
+{
+       return _object_detection_plugin->getOutput();
+}
+
+}
+}
\ No newline at end of file