mv_machine_learning: rename file names
authorInki Dae <inki.dae@samsung.com>
Wed, 10 Jan 2024 06:36:35 +0000 (15:36 +0900)
committerInki Dae <inki.dae@samsung.com>
Wed, 17 Jan 2024 04:19:59 +0000 (13:19 +0900)
[Issue type] code clean

Rename file names of mv_machine_learning according to Tizen coding style
document.[1]

Below are rules used in this patch,
  - Class module refered by external modules uses "NanespaceClassname.*"
  - Class module used internally uses "Classname.*"
    . If "Classname" is duplicated with other task group then sub directory
  name can be added as a prefix.
  - Non class file referred by external modules uses "namespace_filename.*"
  - Non class file used internally uses "filename.*"
    . If "filename" is duplicated with other task group then sub directory
  name can be added as a prefix.

[1] https://wiki.tizen.org/Native_Platform_Coding_Idiom_and_Style_Guide

Change-Id: I0fe3a95a1b5b88b294e2d00ad1fe489143d6cd7d
Signed-off-by: Inki Dae <inki.dae@samsung.com>
193 files changed:
mv_machine_learning/common/CMakeLists.txt
mv_machine_learning/common/include/AsyncManager.h [new file with mode: 0644]
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/common/include/MachineLearningNative.h [deleted file]
mv_machine_learning/common/include/MachineLearningType.h [deleted file]
mv_machine_learning/common/include/MvMlConfig.h [new file with mode: 0644]
mv_machine_learning/common/include/MvMlException.h [new file with mode: 0644]
mv_machine_learning/common/include/async_manager.h [deleted file]
mv_machine_learning/common/include/common.h [new file with mode: 0644]
mv_machine_learning/common/include/context.h [deleted file]
mv_machine_learning/common/include/itask.h [deleted file]
mv_machine_learning/common/include/keys.h [new file with mode: 0644]
mv_machine_learning/common/include/machine_learning_config.h [deleted file]
mv_machine_learning/common/include/machine_learning_exception.h [deleted file]
mv_machine_learning/common/include/machine_learning_key.h [deleted file]
mv_machine_learning/common/include/mv_machine_learning_common.h [deleted file]
mv_machine_learning/common/include/mv_ml_types.h [new file with mode: 0644]
mv_machine_learning/common/include/native_capi.h [new file with mode: 0644]
mv_machine_learning/common/meta/include/MvMlPreprocess.h [new file with mode: 0644]
mv_machine_learning/common/meta/include/common.h [deleted file]
mv_machine_learning/common/meta/include/machine_learning_preprocess.h [deleted file]
mv_machine_learning/common/meta/include/meta_common.h [new file with mode: 0644]
mv_machine_learning/common/meta/src/MetaParser.cpp
mv_machine_learning/common/meta/src/MvMlPreprocess.cpp [new file with mode: 0644]
mv_machine_learning/common/meta/src/PostprocessParser.cpp
mv_machine_learning/common/meta/src/machine_learning_preprocess.cpp [deleted file]
mv_machine_learning/common/src/MachineLearningNative.cpp [deleted file]
mv_machine_learning/common/src/MvMlConfig.cpp [new file with mode: 0644]
mv_machine_learning/common/src/machine_learning_config.cpp [deleted file]
mv_machine_learning/common/src/native_capi.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/include/FaceRecognition.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/FaceRecognitionAdapter.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/FaceRecognitionDSM.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/FaceRecognitionFVM.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/Facenet.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/FacenetAdapter.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/FacenetParser.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/SimpleShot.h [new file with mode: 0644]
mv_machine_learning/face_recognition/include/face_recognition.h [deleted file]
mv_machine_learning/face_recognition/include/face_recognition_adapter.h [deleted file]
mv_machine_learning/face_recognition/include/face_recognition_dsm.h [deleted file]
mv_machine_learning/face_recognition/include/face_recognition_fvm.h [deleted file]
mv_machine_learning/face_recognition/include/facenet.h [deleted file]
mv_machine_learning/face_recognition/include/facenet_adapter.h [deleted file]
mv_machine_learning/face_recognition/include/facenet_parser.h [deleted file]
mv_machine_learning/face_recognition/include/simple_shot.h [deleted file]
mv_machine_learning/face_recognition/src/FaceRecognition.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/FaceRecognitionAdapter.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/FaceRecognitionDSM.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/FaceRecognitionFVM.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/Facenet.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/FacenetAdapter.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/FacenetParser.cpp [new file with mode: 0644]
mv_machine_learning/face_recognition/src/face_recognition.cpp [deleted file]
mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp [deleted file]
mv_machine_learning/face_recognition/src/face_recognition_dsm.cpp [deleted file]
mv_machine_learning/face_recognition/src/face_recognition_fvm.cpp [deleted file]
mv_machine_learning/face_recognition/src/facenet.cpp [deleted file]
mv_machine_learning/face_recognition/src/facenet_adapter.cpp [deleted file]
mv_machine_learning/face_recognition/src/facenet_parser.cpp [deleted file]
mv_machine_learning/face_recognition/src/mv_face_recognition.cpp
mv_machine_learning/face_recognition/src/simple_shot.cpp
mv_machine_learning/image_classification/include/IImageClassification.h [new file with mode: 0644]
mv_machine_learning/image_classification/include/ImageClassification.h [new file with mode: 0644]
mv_machine_learning/image_classification/include/ImageClassificationAdapter.h [new file with mode: 0644]
mv_machine_learning/image_classification/include/ImageClassificationDefault.h [new file with mode: 0644]
mv_machine_learning/image_classification/include/iimage_classification.h [deleted file]
mv_machine_learning/image_classification/include/image_classification.h [deleted file]
mv_machine_learning/image_classification/include/image_classification_adapter.h [deleted file]
mv_machine_learning/image_classification/include/image_classification_default.h [deleted file]
mv_machine_learning/image_classification/include/image_classification_type.h
mv_machine_learning/image_classification/src/ImageClassification.cpp [new file with mode: 0644]
mv_machine_learning/image_classification/src/ImageClassificationAdapter.cpp [new file with mode: 0644]
mv_machine_learning/image_classification/src/ImageClassificationDefault.cpp [new file with mode: 0644]
mv_machine_learning/image_classification/src/ImageClassificationParser.cpp
mv_machine_learning/image_classification/src/image_classification.cpp [deleted file]
mv_machine_learning/image_classification/src/image_classification_adapter.cpp [deleted file]
mv_machine_learning/image_classification/src/image_classification_default.cpp [deleted file]
mv_machine_learning/image_classification/src/mv_image_classification.cpp
mv_machine_learning/image_segmentation/CMakeLists.txt
mv_machine_learning/image_segmentation/include/IImageSegmentation.h [new file with mode: 0644]
mv_machine_learning/image_segmentation/include/ImageSegmentation.h [new file with mode: 0644]
mv_machine_learning/image_segmentation/include/ImageSegmentationAdapter.h [new file with mode: 0644]
mv_machine_learning/image_segmentation/include/ImageSegmentationExternal.h [new file with mode: 0644]
mv_machine_learning/image_segmentation/include/ImageSegmentationParser.h [new file with mode: 0644]
mv_machine_learning/image_segmentation/include/iimage_segmentation.h [deleted file]
mv_machine_learning/image_segmentation/include/image_segmentation.h [deleted file]
mv_machine_learning/image_segmentation/include/image_segmentation_external.h [deleted file]
mv_machine_learning/image_segmentation/include/image_segmentation_parser.h [deleted file]
mv_machine_learning/image_segmentation/include/image_segmentation_type.h
mv_machine_learning/image_segmentation/include/selfie_segmentation_adapter.h [deleted file]
mv_machine_learning/image_segmentation/src/ImageSegmentation.cpp [new file with mode: 0644]
mv_machine_learning/image_segmentation/src/ImageSegmentationAdapter.cpp [new file with mode: 0644]
mv_machine_learning/image_segmentation/src/ImageSegmentationExternal.cpp [new file with mode: 0644]
mv_machine_learning/image_segmentation/src/ImageSegmentationParser.cpp [new file with mode: 0644]
mv_machine_learning/image_segmentation/src/image_segmentation.cpp [deleted file]
mv_machine_learning/image_segmentation/src/image_segmentation_external.cpp [deleted file]
mv_machine_learning/image_segmentation/src/image_segmentation_parser.cpp [deleted file]
mv_machine_learning/image_segmentation/src/mv_selfie_segmentation.cpp
mv_machine_learning/image_segmentation/src/selfie_segmentation_adapter.cpp [deleted file]
mv_machine_learning/landmark_detection/include/FacialLandmarkAdapter.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/FldTweakCnn.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/ILandmarkDetection.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/LandmarkDetection.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/PldCpm.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/PoseLandmarkAdapter.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h [deleted file]
mv_machine_learning/landmark_detection/include/fld_tweak_cnn.h [deleted file]
mv_machine_learning/landmark_detection/include/ilandmark_detection.h [deleted file]
mv_machine_learning/landmark_detection/include/landmark_detection.h [deleted file]
mv_machine_learning/landmark_detection/include/landmark_detection_type.h
mv_machine_learning/landmark_detection/include/pld_cpm.h [deleted file]
mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h [deleted file]
mv_machine_learning/landmark_detection/src/FacialLandmarkAdapter.cpp [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/FldTweakCnn.cpp [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/LandmarkDetection.cpp [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/LandmarkDetectionParser.cpp
mv_machine_learning/landmark_detection/src/PldCpm.cpp [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/PoseLandmarkAdapter.cpp [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp [deleted file]
mv_machine_learning/landmark_detection/src/fld_tweak_cnn.cpp [deleted file]
mv_machine_learning/landmark_detection/src/landmark_detection.cpp [deleted file]
mv_machine_learning/landmark_detection/src/mv_facial_landmark.cpp
mv_machine_learning/landmark_detection/src/mv_pose_landmark.cpp
mv_machine_learning/landmark_detection/src/pld_cpm.cpp [deleted file]
mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp [deleted file]
mv_machine_learning/object_detection/CMakeLists.txt
mv_machine_learning/object_detection/include/FaceDetectionAdapter.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/IObjectDetection.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/MobilenetV1Ssd.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/MobilenetV2Ssd.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/ObjectDetection.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/ObjectDetectionAdapter.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/ObjectDetectionExternal.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/face_detection_adapter.h [deleted file]
mv_machine_learning/object_detection/include/iobject_detection.h [deleted file]
mv_machine_learning/object_detection/include/mobilenet_v1_ssd.h [deleted file]
mv_machine_learning/object_detection/include/mobilenet_v2_ssd.h [deleted file]
mv_machine_learning/object_detection/include/object_detection.h [deleted file]
mv_machine_learning/object_detection/include/object_detection_adapter.h [deleted file]
mv_machine_learning/object_detection/include/object_detection_external.h [deleted file]
mv_machine_learning/object_detection/include/object_detection_type.h
mv_machine_learning/object_detection/src/FaceDetectionAdapter.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/MobilenetV1Ssd.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/MobilenetV2AnchorParser.cpp
mv_machine_learning/object_detection/src/MobilenetV2Ssd.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/ObjectDetection.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/ObjectDetectionAdapter.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/ObjectDetectionExternal.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/ObjectDetectionParser.cpp
mv_machine_learning/object_detection/src/face_detection_adapter.cpp [deleted file]
mv_machine_learning/object_detection/src/mobilenet_v1_ssd.cpp [deleted file]
mv_machine_learning/object_detection/src/mobilenet_v2_ssd.cpp [deleted file]
mv_machine_learning/object_detection/src/mv_face_detection.cpp
mv_machine_learning/object_detection/src/mv_object_detection.cpp
mv_machine_learning/object_detection/src/object_detection.cpp [deleted file]
mv_machine_learning/object_detection/src/object_detection_adapter.cpp [deleted file]
mv_machine_learning/object_detection/src/object_detection_external.cpp [deleted file]
mv_machine_learning/object_detection_3d/include/IObjectDetection3d.h [new file with mode: 0644]
mv_machine_learning/object_detection_3d/include/ObjectDetection3d.h [new file with mode: 0644]
mv_machine_learning/object_detection_3d/include/ObjectDetection3dAdapter.h [new file with mode: 0644]
mv_machine_learning/object_detection_3d/include/Objectron.h [new file with mode: 0644]
mv_machine_learning/object_detection_3d/include/iobject_detection_3d.h [deleted file]
mv_machine_learning/object_detection_3d/include/object_detection_3d.h [deleted file]
mv_machine_learning/object_detection_3d/include/object_detection_3d_adapter.h [deleted file]
mv_machine_learning/object_detection_3d/include/object_detection_3d_type.h
mv_machine_learning/object_detection_3d/include/objectron.h [deleted file]
mv_machine_learning/object_detection_3d/src/ObjectDetection3d.cpp [new file with mode: 0644]
mv_machine_learning/object_detection_3d/src/ObjectDetection3dAdapter.cpp [new file with mode: 0644]
mv_machine_learning/object_detection_3d/src/ObjectDetection3dParser.cpp
mv_machine_learning/object_detection_3d/src/Objectron.cpp [new file with mode: 0644]
mv_machine_learning/object_detection_3d/src/mv_object_detection_3d.cpp
mv_machine_learning/object_detection_3d/src/object_detection_3d.cpp [deleted file]
mv_machine_learning/object_detection_3d/src/object_detection_3d_adapter.cpp [deleted file]
mv_machine_learning/object_detection_3d/src/objectron.cpp [deleted file]
mv_machine_learning/training/include/DataSetManager.h [new file with mode: 0644]
mv_machine_learning/training/include/FeatureVectorManager.h [new file with mode: 0644]
mv_machine_learning/training/include/LabelManager.h [new file with mode: 0644]
mv_machine_learning/training/include/TrainingModel.h [new file with mode: 0644]
mv_machine_learning/training/include/data_set_manager.h [deleted file]
mv_machine_learning/training/include/feature_vector_manager.h [deleted file]
mv_machine_learning/training/include/label_manager.h [deleted file]
mv_machine_learning/training/include/training_model.h [deleted file]
mv_machine_learning/training/src/DataSetManager.cpp [new file with mode: 0644]
mv_machine_learning/training/src/FeatureVectorManager.cpp [new file with mode: 0644]
mv_machine_learning/training/src/LabelManager.cpp [new file with mode: 0644]
mv_machine_learning/training/src/TrainingModel.cpp [new file with mode: 0644]
mv_machine_learning/training/src/data_set_manager.cpp [deleted file]
mv_machine_learning/training/src/feature_vector_manager.cpp [deleted file]
mv_machine_learning/training/src/label_manager.cpp [deleted file]
mv_machine_learning/training/src/training_model.cpp [deleted file]
packaging/capi-media-vision.spec

index c19274556173061a3aa6c7be8ae3c83e2a9cee17..ba81c4e9e374540803c13ca0f01914ce9a6f2f35 100644 (file)
@@ -10,9 +10,9 @@ target_include_directories(${PROJECT_NAME} PRIVATE include meta/include ../../in
 target_include_directories(${PROJECT_NAME} PUBLIC ${${PROJECT_NAME}_DEP_INCLUDE_DIRS})
 install(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
 install(
-    FILES ${PROJECT_SOURCE_DIR}/include/machine_learning_exception.h
-          ${PROJECT_SOURCE_DIR}/include/machine_learning_config.h
-          ${PROJECT_SOURCE_DIR}/include/MachineLearningType.h
-          ${PROJECT_SOURCE_DIR}/meta/include/machine_learning_preprocess.h
+    FILES ${PROJECT_SOURCE_DIR}/include/MvMlException.h
+          ${PROJECT_SOURCE_DIR}/include/MvMlConfig.h
+          ${PROJECT_SOURCE_DIR}/include/mv_ml_types.h
+          ${PROJECT_SOURCE_DIR}/meta/include/MvMlPreprocess.h
     DESTINATION include/media
 )
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/AsyncManager.h b/mv_machine_learning/common/include/AsyncManager.h
new file mode 100644 (file)
index 0000000..4e02752
--- /dev/null
@@ -0,0 +1,221 @@
+/**
+ * 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 __ASYNC_MANAGER_H__
+#define __ASYNC_MANAGER_H__
+
+#include <queue>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <atomic>
+#include <functional>
+#include <algorithm>
+#include <chrono>
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+#include "MvMlException.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "TIZEN_MEDIA_VISION"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> struct AsyncInputQueue {
+       unsigned long frame_number {};
+       std::vector<std::vector<T> > inputs;
+};
+
+template<typename T, typename R> class AsyncManager
+{
+private:
+       using CallbackType = std::function<void()>;
+
+       const std::chrono::seconds _INPUT_QUEUE_WAIT_TIME_SEC { 1 };
+       const std::chrono::seconds _OUTPUT_QUEUE_WAIT_TIME_SEC { 3 };
+       std::queue<AsyncInputQueue<T> > _incoming_queue;
+       std::queue<R> _outgoing_queue;
+       std::mutex _incoming_queue_mutex;
+       std::mutex _outgoing_queue_mutex;
+       std::unique_ptr<std::thread> _thread_handle;
+       std::atomic<bool> _exit_thread { false };
+       std::condition_variable _outgoing_queue_event;
+       std::condition_variable _incoming_queue_event;
+       unsigned long _input_frame_number {};
+       CallbackType _callback;
+
+       void pushToInput(AsyncInputQueue<T> &inputQueue)
+       {
+               std::lock_guard<std::mutex> lock(_incoming_queue_mutex);
+
+               _incoming_queue.push(inputQueue);
+               _incoming_queue_event.notify_one();
+       }
+       bool isInputQueueEmpty()
+       {
+               std::lock_guard<std::mutex> lock(_incoming_queue_mutex);
+
+               return _incoming_queue.empty();
+       }
+       R popFromOutput()
+       {
+               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
+               R output = _outgoing_queue.front();
+
+               _outgoing_queue.pop();
+
+               return output;
+       }
+       void inferenceThreadLoop()
+       {
+               // If user called destroy API then this thread loop will be terminated.
+               while (!_exit_thread) {
+                       // Wait for input data.
+                       auto inputExist = waitforInputQueue();
+                       if (!inputExist) {
+                               LOGW("Input queue is empty");
+                               break;
+                       }
+
+                       // Exit this thread loop if user called destroy API while in thread loop.
+                       if (_exit_thread)
+                               break;
+
+                       // What the callback function has to do is to,
+                       // 1. Get input data from input queue.
+                       // 2. Run inference.
+                       // 3. Put output data to output queue.
+                       _callback();
+               }
+
+               // waitforOutputQueue function could wait for the notify event after while loop is exited.
+               // So make sure to call notify_one() here.
+               _outgoing_queue_event.notify_one();
+       }
+       void invoke()
+       {
+               if (!_thread_handle)
+                       _thread_handle = std::make_unique<std::thread>(&AsyncManager::inferenceThreadLoop, this);
+       }
+       bool waitforInputQueue()
+       {
+               std::unique_lock<std::mutex> lock(_incoming_queue_mutex);
+
+               auto result = _incoming_queue_event.wait_for(lock, _INPUT_QUEUE_WAIT_TIME_SEC,
+                                                                                                        [this] { return !_incoming_queue.empty(); });
+               if (!result) {
+                       LOGW("Waiting for input queue has been timed out.");
+                       return false;
+               }
+
+               return true;
+       }
+       bool isOutputQueueEmpty()
+       {
+               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
+
+               return _outgoing_queue.empty();
+       }
+       void waitforOutputQueue()
+       {
+               std::unique_lock<std::mutex> lock(_outgoing_queue_mutex);
+
+               if (!_outgoing_queue_event.wait_for(lock, _OUTPUT_QUEUE_WAIT_TIME_SEC, [this] {
+                               if (_exit_thread)
+                                       throw exception::InvalidOperation("thread is exited already.");
+
+                               return !_outgoing_queue.empty();
+                       })) {
+                       throw exception::InvalidOperation("Waiting for output queue has been timed out.");
+               }
+       }
+
+public:
+       AsyncManager(const CallbackType &cb) : _callback(cb)
+       {}
+       virtual ~AsyncManager() = default;
+
+       bool isWorking()
+       {
+               if (_exit_thread)
+                       return false;
+
+               return true;
+       }
+       void stop()
+       {
+               // Make sure to wait for the completion of all inference requests in the incoming queue.
+               _exit_thread = true;
+
+               _thread_handle->join();
+               _thread_handle = nullptr;
+
+               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
+               std::queue<R> empty;
+
+               swap(_outgoing_queue, empty);
+       }
+       AsyncInputQueue<T> popFromInput()
+       {
+               std::lock_guard<std::mutex> lock(_incoming_queue_mutex);
+               AsyncInputQueue<T> inputQueue = _incoming_queue.front();
+
+               _incoming_queue.pop();
+
+               return inputQueue;
+       }
+       void pushToOutput(R &output)
+       {
+               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
+
+               _outgoing_queue.push(output);
+               _outgoing_queue_event.notify_one();
+       }
+       void push(std::vector<std::vector<T> > &inputs)
+       {
+               _input_frame_number++;
+
+               if (!isInputQueueEmpty()) {
+                       LOGD("input frame number(%ld) has been skipped.", _input_frame_number);
+                       return;
+               }
+
+               AsyncInputQueue<T> in_queue = { _input_frame_number, inputs };
+
+               pushToInput(in_queue);
+
+               LOGD("Pushed : input frame number = %lu", in_queue.frame_number);
+
+               invoke();
+       }
+       R pop()
+       {
+               waitforOutputQueue();
+
+               return popFromOutput();
+       }
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
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..ea6c654
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ * 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 <map>
+#include "ITask.h"
+
+namespace mediavision
+{
+namespace common
+{
+class Context
+{
+public:
+       Context()
+       {}
+       ~Context()
+       {}
+
+       std::map<std::string, ITask *> __tasks;
+};
+} // 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..ee68dd2
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * 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__
+
+#include "mv_ml_types.h"
+#include <string>
+
+namespace mediavision
+{
+namespace common
+{
+class ITask
+{
+public:
+       virtual ~ITask() {};
+       virtual void setModelInfo(const std::string &model_file, const std::string &meta_file,
+                                                         const std::string &label_file, const std::string &model_name = "") = 0;
+       virtual void setEngineInfo(const std::string &engine_type, const std::string &device_type) = 0;
+       virtual void configure() = 0;
+       virtual unsigned int getNumberOfEngines() = 0;
+       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
+       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
+       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
+       virtual void prepare() = 0;
+       virtual void perform(mediavision::machine_learning::InputBaseType &input) = 0;
+       virtual void performAsync(mediavision::machine_learning::InputBaseType &input) = 0;
+       virtual mediavision::machine_learning::OutputBaseType &getOutput() = 0;
+       virtual mediavision::machine_learning::OutputBaseType &getOutputCache() = 0;
+};
+} // namespace
+} // namespace
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/MachineLearningNative.h b/mv_machine_learning/common/include/MachineLearningNative.h
deleted file mode 100644 (file)
index 9086a83..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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 __MACHINE_LEARNING_NATIVE_H__
-#define __MACHINE_LEARNING_NATIVE_H__
-
-#include <memory>
-#include <string>
-
-#include "context.h"
-#include "itask.h"
-#include "mv_private.h"
-
-#include "MachineLearningType.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-void *machine_learning_native_create();
-void machine_learning_native_add(void *handle, const std::string &task_name, mediavision::common::ITask *task);
-void machine_learning_native_destory(void *handle);
-void machine_learning_native_configure(void *handle, const std::string &task_name);
-void machine_learning_native_prepare(void *handle, const std::string &task_name);
-void machine_learning_native_inference(void *handle, const std::string &task_name, InputBaseType &input);
-void machine_learning_native_inference_async(void *handle, const std::string &task_name, InputBaseType &input);
-OutputBaseType &machine_learning_native_get_result(void *handle, const std::string &task_name);
-OutputBaseType &machine_learning_native_get_result_cache(void *handle, const std::string &task_name);
-void machine_learning_native_set_model(void *handle, const std::string &task_name, const char *model_file,
-                                                                          const char *meta_file, const char *label_file, const char *model_name = "");
-void machine_learning_native_set_engine(void *handle, const std::string &task_name, const char *backend_type,
-                                                                               const char *device_type);
-void machine_learning_native_get_engine_count(void *handle, const std::string &task_name, unsigned int *engine_count);
-void machine_learning_native_get_engine_type(void *handle, const std::string &task_name,
-                                                                                        const unsigned int engine_index, char **engine_type);
-void machine_learning_native_get_device_count(void *handle, const std::string &task_name, const char *engine_type,
-                                                                                         unsigned int *device_count);
-void machine_learning_native_get_device_type(void *handle, const std::string &task_name, const char *engine_type,
-                                                                                        const unsigned int device_index, char **device_type);
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/MachineLearningType.h b/mv_machine_learning/common/include/MachineLearningType.h
deleted file mode 100644 (file)
index d9c8aea..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * 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 __MACHINE_LEARNING_TYPE_H__
-#define __MACHINE_LEARNING_TYPE_H__
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-
-namespace mediavision
-{
-namespace machine_learning
-{
-struct InputBaseType {
-       mv_source_h inference_src {};
-       InputBaseType(mv_source_h src = NULL) : inference_src(src)
-       {}
-       virtual ~InputBaseType()
-       {}
-};
-
-struct OutputBaseType {
-       unsigned long frame_number {};
-       virtual ~OutputBaseType()
-       {}
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/MvMlConfig.h b/mv_machine_learning/common/include/MvMlConfig.h
new file mode 100644 (file)
index 0000000..c8e038a
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * 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 __MV_ML_CONFIG_H__
+#define __MV_ML_CONFIG_H__
+
+#include <mv_common.h>
+#include "mv_private.h"
+#include "EngineConfig.h"
+
+#include "MetaParser.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class Config
+{
+private:
+       std::unique_ptr<MetaParser> _parser;
+       std::string _defaultModelName;
+       std::string _modelFilePath;
+       std::string _modelMetaFilePath;
+       std::string _modelDefaultPath;
+       std::string _modelLabelFilePath;
+       std::string _pluginFileName;
+       bool _usePlugin {};
+       int _backendType {};
+       int _targetDeviceType {};
+       double _confidence_threshold {};
+
+public:
+       Config();
+       virtual ~Config() = 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 parsePluginConfigFile(const std::string &pluginConfigFilePath);
+       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;
+       const std::string &getPluginFileName() const;
+       MetaMap &getInputMetaMap() const;
+       MetaMap &getOutputMetaMap() const;
+       double getConfidenceThreshold() const;
+       int getBackendType() const;
+       int getTargetDeviceType() const;
+       bool isPluginUsed() const;
+       void loadMetaFile(std::unique_ptr<MetaParser> parser);
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/MvMlException.h b/mv_machine_learning/common/include/MvMlException.h
new file mode 100644 (file)
index 0000000..6ebc0e8
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+ * 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 __MV_ML_EXCEPTION_H__
+#define __MV_ML_EXCEPTION_H__
+
+#include <exception>
+#include <string>
+
+#include <mv_common.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+namespace exception
+{
+class BaseException : public std::exception
+{
+private:
+       std::string _msg;
+       int _errorType;
+
+public:
+       BaseException(std::string msg, int errorType) : _msg(msg), _errorType(errorType)
+       {}
+       ~BaseException() override = default;
+
+       const char *what() const noexcept override
+       {
+               return _msg.c_str();
+       }
+       int getError() const
+       {
+               return _errorType;
+       }
+};
+
+class InvalidParameter : public BaseException
+{
+public:
+       InvalidParameter(std::string msg) : BaseException("Invalid parameter: " + msg, MEDIA_VISION_ERROR_INVALID_PARAMETER)
+       {}
+       ~InvalidParameter() override = default;
+};
+
+class InvalidOperation : public BaseException
+{
+public:
+       InvalidOperation(std::string msg, int errorType = MEDIA_VISION_ERROR_INVALID_OPERATION)
+                       : BaseException("Invalid operation: " + msg, errorType)
+       {}
+       ~InvalidOperation() final = default;
+};
+
+class OutOfMemory : public BaseException
+{
+public:
+       OutOfMemory(std::string msg) : BaseException("Out of memory: " + msg, MEDIA_VISION_ERROR_OUT_OF_MEMORY)
+       {}
+       ~OutOfMemory() final = default;
+};
+
+class NoData : public BaseException
+{
+public:
+       NoData(std::string msg) : BaseException("No Data: " + msg, MEDIA_VISION_ERROR_NO_DATA)
+       {}
+       ~NoData() final = default;
+};
+
+}; // Exception
+}; // MachineLearning
+}; // Mediavision
+
+#endif // __MV_ML_EXCEPTION_H__
diff --git a/mv_machine_learning/common/include/async_manager.h b/mv_machine_learning/common/include/async_manager.h
deleted file mode 100644 (file)
index 0ae85c3..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/**
- * 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 __ASYNC_MANAGER_H__
-#define __ASYNC_MANAGER_H__
-
-#include <queue>
-#include <thread>
-#include <mutex>
-#include <condition_variable>
-#include <atomic>
-#include <functional>
-#include <algorithm>
-#include <chrono>
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-#include "machine_learning_exception.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "TIZEN_MEDIA_VISION"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> struct AsyncInputQueue {
-       unsigned long frame_number {};
-       std::vector<std::vector<T> > inputs;
-};
-
-template<typename T, typename R> class AsyncManager
-{
-private:
-       using CallbackType = std::function<void()>;
-
-       const std::chrono::seconds _INPUT_QUEUE_WAIT_TIME_SEC { 1 };
-       const std::chrono::seconds _OUTPUT_QUEUE_WAIT_TIME_SEC { 3 };
-       std::queue<AsyncInputQueue<T> > _incoming_queue;
-       std::queue<R> _outgoing_queue;
-       std::mutex _incoming_queue_mutex;
-       std::mutex _outgoing_queue_mutex;
-       std::unique_ptr<std::thread> _thread_handle;
-       std::atomic<bool> _exit_thread { false };
-       std::condition_variable _outgoing_queue_event;
-       std::condition_variable _incoming_queue_event;
-       unsigned long _input_frame_number {};
-       CallbackType _callback;
-
-       void pushToInput(AsyncInputQueue<T> &inputQueue)
-       {
-               std::lock_guard<std::mutex> lock(_incoming_queue_mutex);
-
-               _incoming_queue.push(inputQueue);
-               _incoming_queue_event.notify_one();
-       }
-       bool isInputQueueEmpty()
-       {
-               std::lock_guard<std::mutex> lock(_incoming_queue_mutex);
-
-               return _incoming_queue.empty();
-       }
-       R popFromOutput()
-       {
-               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
-               R output = _outgoing_queue.front();
-
-               _outgoing_queue.pop();
-
-               return output;
-       }
-       void inferenceThreadLoop()
-       {
-               // If user called destroy API then this thread loop will be terminated.
-               while (!_exit_thread) {
-                       // Wait for input data.
-                       auto inputExist = waitforInputQueue();
-                       if (!inputExist) {
-                               LOGW("Input queue is empty");
-                               break;
-                       }
-
-                       // Exit this thread loop if user called destroy API while in thread loop.
-                       if (_exit_thread)
-                               break;
-
-                       // What the callback function has to do is to,
-                       // 1. Get input data from input queue.
-                       // 2. Run inference.
-                       // 3. Put output data to output queue.
-                       _callback();
-               }
-
-               // waitforOutputQueue function could wait for the notify event after while loop is exited.
-               // So make sure to call notify_one() here.
-               _outgoing_queue_event.notify_one();
-       }
-       void invoke()
-       {
-               if (!_thread_handle)
-                       _thread_handle = std::make_unique<std::thread>(&AsyncManager::inferenceThreadLoop, this);
-       }
-       bool waitforInputQueue()
-       {
-               std::unique_lock<std::mutex> lock(_incoming_queue_mutex);
-
-               auto result = _incoming_queue_event.wait_for(lock, _INPUT_QUEUE_WAIT_TIME_SEC,
-                                                                                                        [this] { return !_incoming_queue.empty(); });
-               if (!result) {
-                       LOGW("Waiting for input queue has been timed out.");
-                       return false;
-               }
-
-               return true;
-       }
-       bool isOutputQueueEmpty()
-       {
-               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
-
-               return _outgoing_queue.empty();
-       }
-       void waitforOutputQueue()
-       {
-               std::unique_lock<std::mutex> lock(_outgoing_queue_mutex);
-
-               if (!_outgoing_queue_event.wait_for(lock, _OUTPUT_QUEUE_WAIT_TIME_SEC, [this] {
-                               if (_exit_thread)
-                                       throw exception::InvalidOperation("thread is exited already.");
-
-                               return !_outgoing_queue.empty();
-                       })) {
-                       throw exception::InvalidOperation("Waiting for output queue has been timed out.");
-               }
-       }
-
-public:
-       AsyncManager(const CallbackType &cb) : _callback(cb)
-       {}
-       virtual ~AsyncManager() = default;
-
-       bool isWorking()
-       {
-               if (_exit_thread)
-                       return false;
-
-               return true;
-       }
-       void stop()
-       {
-               // Make sure to wait for the completion of all inference requests in the incoming queue.
-               _exit_thread = true;
-
-               _thread_handle->join();
-               _thread_handle = nullptr;
-
-               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
-               std::queue<R> empty;
-
-               swap(_outgoing_queue, empty);
-       }
-       AsyncInputQueue<T> popFromInput()
-       {
-               std::lock_guard<std::mutex> lock(_incoming_queue_mutex);
-               AsyncInputQueue<T> inputQueue = _incoming_queue.front();
-
-               _incoming_queue.pop();
-
-               return inputQueue;
-       }
-       void pushToOutput(R &output)
-       {
-               std::lock_guard<std::mutex> lock(_outgoing_queue_mutex);
-
-               _outgoing_queue.push(output);
-               _outgoing_queue_event.notify_one();
-       }
-       void push(std::vector<std::vector<T> > &inputs)
-       {
-               _input_frame_number++;
-
-               if (!isInputQueueEmpty()) {
-                       LOGD("input frame number(%ld) has been skipped.", _input_frame_number);
-                       return;
-               }
-
-               AsyncInputQueue<T> in_queue = { _input_frame_number, inputs };
-
-               pushToInput(in_queue);
-
-               LOGD("Pushed : input frame number = %lu", in_queue.frame_number);
-
-               invoke();
-       }
-       R pop()
-       {
-               waitforOutputQueue();
-
-               return popFromOutput();
-       }
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/common.h b/mv_machine_learning/common/include/common.h
new file mode 100644 (file)
index 0000000..0cebba2
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * 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 __COMMON_H__
+#define __COMMON_H__
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include "mv_inference_type.h"
+
+namespace mediavision
+{
+namespace common
+{
+static std::map<std::string, int> gBackendTypeTable = {
+       { "OPENCV", MV_INFERENCE_BACKEND_OPENCV },               { "TFLITE", MV_INFERENCE_BACKEND_TFLITE },
+       { "ARMNN", MV_INFERENCE_BACKEND_ARMNN },                 { "ONE", MV_INFERENCE_BACKEND_ONE },
+       { "NNTRAINER", MV_INFERENCE_BACKEND_NNTRAINER }, { "SNPE", MV_INFERENCE_BACKEND_SNPE }
+};
+
+static std::map<std::string, int> gDeviceTypeTable = { { "CPU", MV_INFERENCE_TARGET_DEVICE_CPU },
+                                                                                                          { "GPU", MV_INFERENCE_TARGET_DEVICE_GPU },
+                                                                                                          { "NPU", MV_INFERENCE_TARGET_DEVICE_CUSTOM } };
+
+static int GetBackendType(std::string backend_type)
+{
+       auto item = gBackendTypeTable.find(backend_type);
+       if (item != gBackendTypeTable.end())
+               return item->second;
+
+       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+}
+
+static int GetDeviceType(std::string device_type)
+{
+       auto item = gDeviceTypeTable.find(device_type);
+       if (item != gDeviceTypeTable.end())
+               return item->second;
+
+       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+}
+
+} // namespace
+} // namespace
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/context.h b/mv_machine_learning/common/include/context.h
deleted file mode 100644 (file)
index f2b7b3d..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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 <map>
-#include "itask.h"
-
-namespace mediavision
-{
-namespace common
-{
-class Context
-{
-public:
-       Context()
-       {}
-       ~Context()
-       {}
-
-       std::map<std::string, ITask *> __tasks;
-};
-} // 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
deleted file mode 100644 (file)
index a55865c..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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__
-
-#include "MachineLearningType.h"
-#include <string>
-
-namespace mediavision
-{
-namespace common
-{
-class ITask
-{
-public:
-       virtual ~ITask() {};
-       virtual void setModelInfo(const std::string &model_file, const std::string &meta_file,
-                                                         const std::string &label_file, const std::string &model_name = "") = 0;
-       virtual void setEngineInfo(const std::string &engine_type, const std::string &device_type) = 0;
-       virtual void configure() = 0;
-       virtual unsigned int getNumberOfEngines() = 0;
-       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
-       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
-       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
-       virtual void prepare() = 0;
-       virtual void perform(mediavision::machine_learning::InputBaseType &input) = 0;
-       virtual void performAsync(mediavision::machine_learning::InputBaseType &input) = 0;
-       virtual mediavision::machine_learning::OutputBaseType &getOutput() = 0;
-       virtual mediavision::machine_learning::OutputBaseType &getOutputCache() = 0;
-};
-} // namespace
-} // namespace
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/keys.h b/mv_machine_learning/common/include/keys.h
new file mode 100644 (file)
index 0000000..730958f
--- /dev/null
@@ -0,0 +1,101 @@
+/**
+ * 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 __KEYS_H__
+#define __KEYS_H__
+
+/**
+ * @brief Defines #MV_MODEL_DEFAULT_PATH
+ *        to set the model default path.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_MODEL_DEFAULT_PATH "MODEL_DEFAULT_PATH"
+
+/**
+ * @brief Defines #MV_MODEL_FILE_NAME
+ *        to set the model file path.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_MODEL_FILE_NAME "MODEL_FILE_NAME"
+
+/**
+ * @brief Defines #MV_DEFAULT_MODEL_NAME
+ *        to set the default model name.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_DEFAULT_MODEL_NAME "DEFAULT_MODEL_NAME"
+
+/**
+ * @brief Defines #MV_MODEL_META_FILE_NAME 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
+ *          node names, input tensor's width and height,
+ *          mean and standard deviation values for pre-processing.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_MODEL_META_FILE_NAME "MODEL_META_FILE_NAME"
+
+/**
+ * @brief Defines #MV_MODEL_LABEL_FILE_NAME to set inference
+ *        models's label file attribute of the engine configuration.
+ * @details The file includes inference model's label file.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_MODEL_LABEL_FILE_NAME "MODEL_LABEL_FILE_NAME"
+
+/**
+ * @brief Defines #MV_MODEL_CONFIDENCE_THRESHOLD to set inference
+ *        models's confidence threshold value of the engine configuration.
+ * @details The file includes inference model's confidence threshold value.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_MODEL_CONFIDENCE_THRESHOLD "CONFIDENCE_THRESHOLD"
+
+/**
+ * @brief Defines #MV_BACKEND_TYPE
+ *        to set inference backend engine type. In default, tensorflow lite is used.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_BACKEND_TYPE "BACKEND_TYPE"
+
+/**
+ * @brief Defines #MV_TARGET_DEVICE_TYPE
+ *        to set inference target device type. In default, CPU device is used.
+ *
+ * @since_tizen 8.0
+ */
+#define MV_TARGET_DEVICE_TYPE "TARGET_DEVICE_TYPE"
+
+/**
+ * @brief Defines #MV_PLUGIN_NAME
+ *        to set plugin library name for using external plugin.
+ */
+#define MV_PLUGIN_NAME "PLUGIN_NAME"
+
+/**
+ * @brief Defines #MV_USE_PLUGIN
+ *        to indicate whether extern plugin is used or not for a given task type.
+ */
+#define MV_USE_PLUGIN "USE_PLUGIN"
+
+#endif /* __KEYS_H__ */
diff --git a/mv_machine_learning/common/include/machine_learning_config.h b/mv_machine_learning/common/include/machine_learning_config.h
deleted file mode 100644 (file)
index edf0b79..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * 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 __MACHINE_LEARNING_CONFIG_H__
-#define __MACHINE_LEARNING_CONFIG_H__
-
-#include <mv_common.h>
-#include "mv_private.h"
-#include "EngineConfig.h"
-
-#include "MetaParser.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class MachineLearningConfig
-{
-private:
-       std::unique_ptr<MetaParser> _parser;
-       std::string _defaultModelName;
-       std::string _modelFilePath;
-       std::string _modelMetaFilePath;
-       std::string _modelDefaultPath;
-       std::string _modelLabelFilePath;
-       std::string _pluginFileName;
-       bool _usePlugin {};
-       int _backendType {};
-       int _targetDeviceType {};
-       double _confidence_threshold {};
-
-public:
-       MachineLearningConfig();
-       virtual ~MachineLearningConfig() = 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 parsePluginConfigFile(const std::string &pluginConfigFilePath);
-       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;
-       const std::string &getPluginFileName() const;
-       MetaMap &getInputMetaMap() const;
-       MetaMap &getOutputMetaMap() const;
-       double getConfidenceThreshold() const;
-       int getBackendType() const;
-       int getTargetDeviceType() const;
-       bool isPluginUsed() const;
-       void loadMetaFile(std::unique_ptr<MetaParser> parser);
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/machine_learning_exception.h b/mv_machine_learning/common/include/machine_learning_exception.h
deleted file mode 100644 (file)
index 6bb857b..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * 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 __MACHINE_LEARNING_EXCEPTION_H__
-#define __MACHINE_LEARNING_EXCEPTION_H__
-
-#include <exception>
-#include <string>
-
-#include <mv_common.h>
-
-namespace mediavision
-{
-namespace machine_learning
-{
-namespace exception
-{
-class BaseException : public std::exception
-{
-private:
-       std::string _msg;
-       int _errorType;
-
-public:
-       BaseException(std::string msg, int errorType) : _msg(msg), _errorType(errorType)
-       {}
-       ~BaseException() override = default;
-
-       const char *what() const noexcept override
-       {
-               return _msg.c_str();
-       }
-       int getError() const
-       {
-               return _errorType;
-       }
-};
-
-class InvalidParameter : public BaseException
-{
-public:
-       InvalidParameter(std::string msg) : BaseException("Invalid parameter: " + msg, MEDIA_VISION_ERROR_INVALID_PARAMETER)
-       {}
-       ~InvalidParameter() override = default;
-};
-
-class InvalidOperation : public BaseException
-{
-public:
-       InvalidOperation(std::string msg, int errorType = MEDIA_VISION_ERROR_INVALID_OPERATION)
-                       : BaseException("Invalid operation: " + msg, errorType)
-       {}
-       ~InvalidOperation() final = default;
-};
-
-class OutOfMemory : public BaseException
-{
-public:
-       OutOfMemory(std::string msg) : BaseException("Out of memory: " + msg, MEDIA_VISION_ERROR_OUT_OF_MEMORY)
-       {}
-       ~OutOfMemory() final = default;
-};
-
-class NoData : public BaseException
-{
-public:
-       NoData(std::string msg) : BaseException("No Data: " + msg, MEDIA_VISION_ERROR_NO_DATA)
-       {}
-       ~NoData() final = default;
-};
-
-}; // Exception
-}; // MachineLearning
-}; // Mediavision
-
-#endif // __MACHINE_LEARNING_EXCEPTION_H__
diff --git a/mv_machine_learning/common/include/machine_learning_key.h b/mv_machine_learning/common/include/machine_learning_key.h
deleted file mode 100644 (file)
index 9283258..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/**
- * 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 __MACHINE_LEARNING_KEY_H__
-#define __MACHINE_LEARNING_KEY_H__
-
-/**
- * @brief Defines #MV_MODEL_DEFAULT_PATH
- *        to set the model default path.
- *
- * @since_tizen 8.0
- */
-#define MV_MODEL_DEFAULT_PATH "MODEL_DEFAULT_PATH"
-
-/**
- * @brief Defines #MV_MODEL_FILE_NAME
- *        to set the model file path.
- *
- * @since_tizen 8.0
- */
-#define MV_MODEL_FILE_NAME "MODEL_FILE_NAME"
-
-/**
- * @brief Defines #MV_DEFAULT_MODEL_NAME
- *        to set the default model name.
- *
- * @since_tizen 8.0
- */
-#define MV_DEFAULT_MODEL_NAME "DEFAULT_MODEL_NAME"
-
-/**
- * @brief Defines #MV_MODEL_META_FILE_NAME 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
- *          node names, input tensor's width and height,
- *          mean and standard deviation values for pre-processing.
- *
- * @since_tizen 8.0
- */
-#define MV_MODEL_META_FILE_NAME "MODEL_META_FILE_NAME"
-
-/**
- * @brief Defines #MV_MODEL_LABEL_FILE_NAME to set inference
- *        models's label file attribute of the engine configuration.
- * @details The file includes inference model's label file.
- *
- * @since_tizen 8.0
- */
-#define MV_MODEL_LABEL_FILE_NAME "MODEL_LABEL_FILE_NAME"
-
-/**
- * @brief Defines #MV_MODEL_CONFIDENCE_THRESHOLD to set inference
- *        models's confidence threshold value of the engine configuration.
- * @details The file includes inference model's confidence threshold value.
- *
- * @since_tizen 8.0
- */
-#define MV_MODEL_CONFIDENCE_THRESHOLD "CONFIDENCE_THRESHOLD"
-
-/**
- * @brief Defines #MV_BACKEND_TYPE
- *        to set inference backend engine type. In default, tensorflow lite is used.
- *
- * @since_tizen 8.0
- */
-#define MV_BACKEND_TYPE "BACKEND_TYPE"
-
-/**
- * @brief Defines #MV_TARGET_DEVICE_TYPE
- *        to set inference target device type. In default, CPU device is used.
- *
- * @since_tizen 8.0
- */
-#define MV_TARGET_DEVICE_TYPE "TARGET_DEVICE_TYPE"
-
-/**
- * @brief Defines #MV_PLUGIN_NAME
- *        to set plugin library name for using external plugin.
- */
-#define MV_PLUGIN_NAME "PLUGIN_NAME"
-
-/**
- * @brief Defines #MV_USE_PLUGIN
- *        to indicate whether extern plugin is used or not for a given task type.
- */
-#define MV_USE_PLUGIN "USE_PLUGIN"
-
-#endif /* __MACHINE_LEARNING_KEY_H__ */
diff --git a/mv_machine_learning/common/include/mv_machine_learning_common.h b/mv_machine_learning/common/include/mv_machine_learning_common.h
deleted file mode 100644 (file)
index 1491af9..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * 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 __MV_MACHINE_LEARNING_COMMON_H__
-#define __MV_MACHINE_LEARNING_COMMON_H__
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "mv_inference_type.h"
-
-namespace mediavision
-{
-namespace common
-{
-static std::map<std::string, int> gBackendTypeTable = {
-       { "OPENCV", MV_INFERENCE_BACKEND_OPENCV },               { "TFLITE", MV_INFERENCE_BACKEND_TFLITE },
-       { "ARMNN", MV_INFERENCE_BACKEND_ARMNN },                 { "ONE", MV_INFERENCE_BACKEND_ONE },
-       { "NNTRAINER", MV_INFERENCE_BACKEND_NNTRAINER }, { "SNPE", MV_INFERENCE_BACKEND_SNPE }
-};
-
-static std::map<std::string, int> gDeviceTypeTable = { { "CPU", MV_INFERENCE_TARGET_DEVICE_CPU },
-                                                                                                          { "GPU", MV_INFERENCE_TARGET_DEVICE_GPU },
-                                                                                                          { "NPU", MV_INFERENCE_TARGET_DEVICE_CUSTOM } };
-
-static int GetBackendType(std::string backend_type)
-{
-       auto item = gBackendTypeTable.find(backend_type);
-       if (item != gBackendTypeTable.end())
-               return item->second;
-
-       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
-}
-
-static int GetDeviceType(std::string device_type)
-{
-       auto item = gDeviceTypeTable.find(device_type);
-       if (item != gDeviceTypeTable.end())
-               return item->second;
-
-       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
-}
-
-} // namespace
-} // namespace
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/mv_ml_types.h b/mv_machine_learning/common/include/mv_ml_types.h
new file mode 100644 (file)
index 0000000..d8aabc0
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * 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 __MV_ML_TYPE_H__
+#define __MV_ML_TYPE_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+struct InputBaseType {
+       mv_source_h inference_src {};
+       InputBaseType(mv_source_h src = NULL) : inference_src(src)
+       {}
+       virtual ~InputBaseType()
+       {}
+};
+
+struct OutputBaseType {
+       unsigned long frame_number {};
+       virtual ~OutputBaseType()
+       {}
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/include/native_capi.h b/mv_machine_learning/common/include/native_capi.h
new file mode 100644 (file)
index 0000000..8c71036
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * 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 __NATIVE_CAPI_H__
+#define __NATIVE_CAPI_H__
+
+#include <memory>
+#include <string>
+
+#include "Context.h"
+#include "ITask.h"
+#include "mv_private.h"
+#include "mv_ml_types.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+void *machine_learning_native_create();
+void machine_learning_native_add(void *handle, const std::string &task_name, mediavision::common::ITask *task);
+void machine_learning_native_destory(void *handle);
+void machine_learning_native_configure(void *handle, const std::string &task_name);
+void machine_learning_native_prepare(void *handle, const std::string &task_name);
+void machine_learning_native_inference(void *handle, const std::string &task_name, InputBaseType &input);
+void machine_learning_native_inference_async(void *handle, const std::string &task_name, InputBaseType &input);
+OutputBaseType &machine_learning_native_get_result(void *handle, const std::string &task_name);
+OutputBaseType &machine_learning_native_get_result_cache(void *handle, const std::string &task_name);
+void machine_learning_native_set_model(void *handle, const std::string &task_name, const char *model_file,
+                                                                          const char *meta_file, const char *label_file, const char *model_name = "");
+void machine_learning_native_set_engine(void *handle, const std::string &task_name, const char *backend_type,
+                                                                               const char *device_type);
+void machine_learning_native_get_engine_count(void *handle, const std::string &task_name, unsigned int *engine_count);
+void machine_learning_native_get_engine_type(void *handle, const std::string &task_name,
+                                                                                        const unsigned int engine_index, char **engine_type);
+void machine_learning_native_get_device_count(void *handle, const std::string &task_name, const char *engine_type,
+                                                                                         unsigned int *device_count);
+void machine_learning_native_get_device_type(void *handle, const std::string &task_name, const char *engine_type,
+                                                                                        const unsigned int device_index, char **device_type);
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/meta/include/MvMlPreprocess.h b/mv_machine_learning/common/meta/include/MvMlPreprocess.h
new file mode 100644 (file)
index 0000000..abbd041
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * 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 __MV_ML_PREPROCESS_H__
+#define __MV_ML_PREPROCESS_H__
+
+#include <string>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <inference_engine_type.h>
+#include <mv_inference_type.h>
+
+#include "mv_common.h"
+
+#include <opencv2/core.hpp>
+#include <opencv2/imgproc.hpp>
+
+/**
+ * @file MvMlPreprocess.h
+ * @brief This file contains the Preprocess class definition which
+ *        provides Preprocess before running inference.
+ */
+
+namespace mediavision
+{
+namespace machine_learning
+{
+struct PreprocessConfig {
+       bool skip_csc {}; /**< It indicates whether color space conversion operation should be skipped or not. */
+       mv_colorspace_e output_format {}; /**< The pixel format of output tensor to be converted. */
+       mv_inference_data_type_e output_data_type {}; /**< The data type of output tensor to be converted. */
+       int output_channel {}; /** The channel size of output tensor te be converted. */
+       int output_width {}; /** The width size of output tensor to be converted. */
+       int output_height {}; /** The height size of output tensor to be converted. */
+       bool normalize {}; /**< It indicates whether normalization to input data should be performed or not. */
+       std::vector<double> mean;
+       std::vector<double> std;
+       bool quantize {}; /**< It indicates whether quantization to input data should be performed or not. */
+       std::vector<double> scale;
+       std::vector<double> zeropoint;
+};
+
+class Preprocess
+{
+public:
+       Preprocess()
+       {}
+       ~Preprocess() = default;
+
+       void setConfig(const PreprocessConfig &config);
+       template<typename T> void run(mv_source_h &mv_src, std::vector<T> &inputVector);
+
+       std::vector<unsigned int> &getImageWidth()
+       {
+               return _vImageWidth;
+       }
+       std::vector<unsigned int> &getImageHeight()
+       {
+               return _vImageHeight;
+       }
+
+private:
+       std::vector<unsigned int> _vImageWidth;
+       std::vector<unsigned int> _vImageHeight;
+       PreprocessConfig _config;
+
+       int convertToCv(int given_type, int ch);
+       void colorConvert(cv::Mat &source, cv::Mat &dest, int sType, int dType);
+       void convertToCvSource(std::vector<mv_source_h> &mv_srcs, std::vector<cv::Mat> &cv_srcs);
+       void normalize(cv::Mat &source, cv::Mat &dest, const std::vector<double> &mean, const std::vector<double> &std);
+       void quantize(cv::Mat &source, cv::Mat &dest, const std::vector<double> &scale,
+                                 const std::vector<double> &zeropoint);
+};
+
+} /* machine_learning */
+} /* mediavision */
+
+#endif /* __MV_ML_PREPROCESS_H__ */
diff --git a/mv_machine_learning/common/meta/include/common.h b/mv_machine_learning/common/meta/include/common.h
deleted file mode 100644 (file)
index cb7d34d..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * 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 __COMMON_H__
-#define __COMMON_H__
-
-#include <string>
-#include <mv_common.h>
-#include <mv_private.h>
-#include <json-glib/json-glib.h>
-#include <inference_engine_type.h>
-#include <dlog.h>
-#include "machine_learning_exception.h"
-#include "mv_inference_type.h"
-#include "types.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T, typename U> T GetSupportedType(JsonObject *in_obj, std::string key, U &in_map)
-{
-       auto supportedType = in_map.find(json_object_get_string_member(in_obj, key.c_str()));
-       if (supportedType == in_map.end()) {
-               throw mediavision::machine_learning::exception::InvalidParameter("invalid type.");
-       }
-
-       LOGI("%s: %d:%s", key.c_str(), static_cast<int>(supportedType->second), supportedType->first.c_str());
-
-       return supportedType->second;
-}
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/common/meta/include/machine_learning_preprocess.h b/mv_machine_learning/common/meta/include/machine_learning_preprocess.h
deleted file mode 100644 (file)
index e530947..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * 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 __MACHINE_LEARNING_PREPROCESS_H__
-#define __MACHINE_LEARNING_PREPROCESS_H__
-
-#include <string>
-#include <map>
-#include <memory>
-#include <vector>
-
-#include <inference_engine_type.h>
-#include <mv_inference_type.h>
-
-#include "mv_common.h"
-
-#include <opencv2/core.hpp>
-#include <opencv2/imgproc.hpp>
-
-/**
- * @file machine_learning_preprocess.h
- * @brief This file contains the Preprocess class definition which
- *        provides Preprocess before running inference.
- */
-
-namespace mediavision
-{
-namespace machine_learning
-{
-struct PreprocessConfig {
-       bool skip_csc {}; /**< It indicates whether color space conversion operation should be skipped or not. */
-       mv_colorspace_e output_format {}; /**< The pixel format of output tensor to be converted. */
-       mv_inference_data_type_e output_data_type {}; /**< The data type of output tensor to be converted. */
-       int output_channel {}; /** The channel size of output tensor te be converted. */
-       int output_width {}; /** The width size of output tensor to be converted. */
-       int output_height {}; /** The height size of output tensor to be converted. */
-       bool normalize {}; /**< It indicates whether normalization to input data should be performed or not. */
-       std::vector<double> mean;
-       std::vector<double> std;
-       bool quantize {}; /**< It indicates whether quantization to input data should be performed or not. */
-       std::vector<double> scale;
-       std::vector<double> zeropoint;
-};
-
-class Preprocess
-{
-public:
-       Preprocess()
-       {}
-       ~Preprocess() = default;
-
-       void setConfig(const PreprocessConfig &config);
-       template<typename T> void run(mv_source_h &mv_src, std::vector<T> &inputVector);
-
-       std::vector<unsigned int> &getImageWidth()
-       {
-               return _vImageWidth;
-       }
-       std::vector<unsigned int> &getImageHeight()
-       {
-               return _vImageHeight;
-       }
-
-private:
-       std::vector<unsigned int> _vImageWidth;
-       std::vector<unsigned int> _vImageHeight;
-       PreprocessConfig _config;
-
-       int convertToCv(int given_type, int ch);
-       void colorConvert(cv::Mat &source, cv::Mat &dest, int sType, int dType);
-       void convertToCvSource(std::vector<mv_source_h> &mv_srcs, std::vector<cv::Mat> &cv_srcs);
-       void normalize(cv::Mat &source, cv::Mat &dest, const std::vector<double> &mean, const std::vector<double> &std);
-       void quantize(cv::Mat &source, cv::Mat &dest, const std::vector<double> &scale,
-                                 const std::vector<double> &zeropoint);
-};
-
-} /* machine_learning */
-} /* mediavision */
-
-#endif /* __MACHINE_LEARNING_PREPROCESS_H__ */
diff --git a/mv_machine_learning/common/meta/include/meta_common.h b/mv_machine_learning/common/meta/include/meta_common.h
new file mode 100644 (file)
index 0000000..24caaf3
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * 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 __COMMON_H__
+#define __COMMON_H__
+
+#include <string>
+#include <mv_common.h>
+#include <mv_private.h>
+#include <json-glib/json-glib.h>
+#include <inference_engine_type.h>
+#include <dlog.h>
+#include "MvMlException.h"
+#include "mv_inference_type.h"
+#include "types.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T, typename U> T GetSupportedType(JsonObject *in_obj, std::string key, U &in_map)
+{
+       auto supportedType = in_map.find(json_object_get_string_member(in_obj, key.c_str()));
+       if (supportedType == in_map.end()) {
+               throw mediavision::machine_learning::exception::InvalidParameter("invalid type.");
+       }
+
+       LOGI("%s: %d:%s", key.c_str(), static_cast<int>(supportedType->second), supportedType->first.c_str());
+
+       return supportedType->second;
+}
+
+}
+}
+
+#endif
\ No newline at end of file
index 5b66500f71e73be4fe59a447c07cc580ceebd875..56aebae6cda575aa2bd766e423731e13f9e819f6 100644 (file)
@@ -18,9 +18,9 @@
 #include <fstream>
 #include <algorithm>
 
-#include "machine_learning_exception.h"
+#include "MvMlException.h"
 #include "MetaParser.h"
-#include "common.h"
+#include "meta_common.h"
 
 using namespace std;
 using namespace mediavision::machine_learning::exception;
diff --git a/mv_machine_learning/common/meta/src/MvMlPreprocess.cpp b/mv_machine_learning/common/meta/src/MvMlPreprocess.cpp
new file mode 100644 (file)
index 0000000..0aa57c0
--- /dev/null
@@ -0,0 +1,202 @@
+/**
+ * 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 <unistd.h>
+#include <fstream>
+#include <string>
+#include <queue>
+#include <algorithm>
+#include "mv_private.h"
+#include "MvMlPreprocess.h"
+#include "MvMlException.h"
+
+constexpr int colorConvertTable[][12] = {
+       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+       { 0, -1, 0, 0, 0, 0, 0, 0, 0, cv::COLOR_GRAY2BGR565, cv::COLOR_GRAY2RGB, cv::COLOR_GRAY2RGBA },
+       { 0, cv::COLOR_YUV2GRAY_I420, -1, 0, 0, 0, 0, 0, 0, 0, cv::COLOR_RGBA2GRAY, cv::COLOR_YUV2RGBA_I420 },
+       { 0, cv::COLOR_YUV2GRAY_NV12, 0, -1, 0, 0, 0, 0, 0, 0, cv::COLOR_YUV2RGB_NV12, cv::COLOR_YUV2RGBA_NV12 },
+       { 0, cv::COLOR_YUV2GRAY_YV12, 0, 0, -1, 0, 0, 0, 0, 0, cv::COLOR_YUV2RGB_YV12, cv::COLOR_YUV2RGBA_YV12 },
+       { 0, cv::COLOR_YUV2GRAY_NV21, 0, 0, 0, -1, 0, 0, 0, 0, cv::COLOR_YUV2RGB_NV21, cv::COLOR_YUV2RGBA_NV21 },
+       { 0, cv::COLOR_YUV2GRAY_YUYV, 0, 0, 0, 0, -1, 0, 0, 0, cv::COLOR_YUV2RGB_YUYV, cv::COLOR_YUV2RGBA_YUYV },
+       { 0, cv::COLOR_YUV2GRAY_UYVY, 0, 0, 0, 0, 0, -1, 0, 0, cv::COLOR_YUV2BGR_UYVY, cv::COLOR_YUV2BGRA_UYVY },
+       { 0, cv::COLOR_YUV2GRAY_Y422, 0, 0, 0, 0, 0, 0, -1, 0, cv::COLOR_YUV2RGB_Y422, cv::COLOR_YUV2RGBA_Y422 },
+       { 0, cv::COLOR_BGR5652GRAY, 0, 0, 0, 0, 0, 0, 0, -1, cv::COLOR_BGR5652BGR, cv::COLOR_BGR5652BGRA },
+       { 0, cv::COLOR_RGB2GRAY, 0, 0, 0, 0, 0, 0, 0, 0, -1, cv::COLOR_RGB2RGBA },
+       { 0, cv::COLOR_RGBA2GRAY, 0, 0, 0, 0, 0, 0, 0, cv::COLOR_BGRA2BGR565, cv::COLOR_RGBA2RGB, -1 }
+};
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+void Preprocess::colorConvert(cv::Mat &source, cv::Mat &dest, int sType, int dType)
+{
+       LOGI("ENTER");
+
+       auto conversionColor = static_cast<int>(colorConvertTable[sType][dType]);
+       if (conversionColor == -1) { /* Don't need conversion */
+               dest = source;
+       } else if (conversionColor > 0) {
+               /* Class for representation the given image as cv::Mat before conversion */
+               cv::cvtColor(source, dest, conversionColor);
+       } else {
+               throw InvalidOperation("Fail to ColorConvert");
+       }
+
+       LOGI("LEAVE");
+}
+
+void Preprocess::normalize(cv::Mat &source, cv::Mat &dest, const vector<double> &mean, const vector<double> &std)
+{
+       LOGI("ENTER");
+
+       try {
+               cv::subtract(source, cv::Scalar(mean[0], mean[1], mean[2]), dest);
+               source = dest;
+               cv::divide(source, cv::Scalar(std[0], std[1], std[2]), dest);
+       } catch (cv::Exception &e) {
+               throw InvalidOperation("Fail to substract/divide");
+       }
+
+       LOGI("LEAVE");
+}
+
+void Preprocess::quantize(cv::Mat &source, cv::Mat &dest, const vector<double> &scale, const vector<double> &zeropoint)
+{
+       LOGI("ENTER");
+
+       try {
+               cv::subtract(source, cv::Scalar(zeropoint[0], zeropoint[1], zeropoint[2]), dest);
+               source = dest;
+               cv::multiply(source, cv::Scalar(scale[0], scale[1], scale[2]), dest);
+       } catch (cv::Exception &e) {
+               throw InvalidOperation("Fail to subtract/multiply");
+       }
+
+       LOGI("LEAVE");
+}
+
+int Preprocess::convertToCv(int given_type, int ch)
+{
+       int type = 0;
+
+       switch (given_type) {
+       case INFERENCE_TENSOR_DATA_TYPE_UINT8:
+       case MV_INFERENCE_DATA_UINT8:
+               LOGI("Type is %d ch with UINT8", ch);
+               type = ch == 1 ? CV_8UC1 : CV_8UC3;
+               break;
+       case INFERENCE_TENSOR_DATA_TYPE_FLOAT32:
+       case MV_INFERENCE_DATA_FLOAT32:
+               LOGI("Type is %d ch with FLOAT32", ch);
+               type = ch == 1 ? CV_32FC1 : CV_32FC3;
+               break;
+       default:
+               LOGI("unknown data type so FLOAT32 data type will be used in default");
+               type = ch == 1 ? CV_32FC1 : CV_32FC3;
+               break;
+       }
+
+       return type;
+}
+
+void Preprocess::convertToCvSource(vector<mv_source_h> &mv_srcs, vector<cv::Mat> &cv_srcs)
+{
+       for (auto &mv_src : mv_srcs) {
+               mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+               unsigned int width = 0, height = 0;
+               unsigned int bufferSize = 0;
+               unsigned char *buffer = NULL;
+
+               if (mv_source_get_width(mv_src, &width) != MEDIA_VISION_ERROR_NONE ||
+                       mv_source_get_height(mv_src, &height) != MEDIA_VISION_ERROR_NONE ||
+                       mv_source_get_colorspace(mv_src, &colorspace) != MEDIA_VISION_ERROR_NONE ||
+                       mv_source_get_buffer(mv_src, &buffer, &bufferSize))
+                       throw InvalidParameter("Invalid Parameter.");
+
+               _vImageWidth.push_back(width);
+               _vImageHeight.push_back(height);
+
+               // TODO. Let's support various color spaces.
+
+               if (colorspace != MEDIA_VISION_COLORSPACE_RGB888)
+                       throw InvalidOperation("Not Supported format.");
+
+               /* convert mv_source to cv::Mat */
+               cv::Mat cvSource = cv::Mat(cv::Size(width, height), CV_MAKETYPE(CV_8U, 3), buffer).clone();
+
+               cv_srcs.push_back(cvSource);
+               LOGI("Size: w:%u, h:%u", cvSource.size().width, cvSource.size().height);
+       }
+}
+
+void Preprocess::setConfig(const PreprocessConfig &config)
+{
+       _config = config;
+}
+
+template<typename T> void Preprocess::run(mv_source_h &mv_src, vector<T> &inputVector)
+{
+       LOGI("ENTER");
+
+       vector<cv::Mat> oriCvSources;
+       vector<mv_source_h> mv_srcs = { mv_src };
+
+       _vImageWidth.clear();
+       _vImageHeight.clear();
+       convertToCvSource(mv_srcs, oriCvSources);
+
+       inputVector.resize(_config.output_height * _config.output_width * _config.output_channel);
+
+       int data_type = convertToCv(_config.output_data_type, _config.output_channel);
+       // dest is a wrapper of the buffer.
+       cv::Mat dest(cv::Size(_config.output_width, _config.output_height), data_type, inputVector.data());
+       cv::Mat cvSource, cvDest;
+
+       // cvSource has new allocation with dest.size()
+       cv::resize(oriCvSources[0], cvSource, dest.size());
+
+       if (_config.skip_csc) {
+               cvSource.convertTo(dest, dest.type());
+       } else {
+               mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
+               int ret = mv_source_get_colorspace(mv_srcs[0], &colorspace);
+               if (ret != MEDIA_VISION_ERROR_NONE)
+                       throw InvalidOperation("Fail to get color space.");
+
+               // cvDest is allocated if colorspace is not RGB888, and
+               // cvDest shares the data with cvSource if the colorspace is RGB888.
+               colorConvert(cvSource, cvDest, colorspace, _config.output_format);
+               cvDest.convertTo(dest, dest.type());
+       }
+
+       if (_config.normalize)
+               normalize(dest, dest, _config.mean, _config.std);
+
+       if (_config.quantize)
+               quantize(dest, dest, _config.scale, _config.zeropoint);
+
+       LOGI("LEAVE");
+}
+
+template void Preprocess::run<float>(mv_source_h &mv_src, vector<float> &inputVector);
+template void Preprocess::run<unsigned char>(mv_source_h &mv_src, vector<unsigned char> &inputVector);
+
+} /* machine_learning */
+} /* mediavision */
index fb4effac3945d6e34a359a67c38135cae69935de..cacc2f61977e64d88abcf922166fe952d68e28f8 100644 (file)
@@ -18,9 +18,9 @@
 #include <string>
 #include <queue>
 #include <algorithm>
-#include "machine_learning_exception.h"
+#include "MvMlException.h"
 #include "PostprocessParser.h"
-#include "common.h"
+#include "meta_common.h"
 
 using namespace std;
 using namespace mediavision::machine_learning::exception;
diff --git a/mv_machine_learning/common/meta/src/machine_learning_preprocess.cpp b/mv_machine_learning/common/meta/src/machine_learning_preprocess.cpp
deleted file mode 100644 (file)
index f729ec5..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * 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 <unistd.h>
-#include <fstream>
-#include <string>
-#include <queue>
-#include <algorithm>
-#include "mv_private.h"
-#include "machine_learning_preprocess.h"
-#include "machine_learning_exception.h"
-
-constexpr int colorConvertTable[][12] = {
-       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
-       { 0, -1, 0, 0, 0, 0, 0, 0, 0, cv::COLOR_GRAY2BGR565, cv::COLOR_GRAY2RGB, cv::COLOR_GRAY2RGBA },
-       { 0, cv::COLOR_YUV2GRAY_I420, -1, 0, 0, 0, 0, 0, 0, 0, cv::COLOR_RGBA2GRAY, cv::COLOR_YUV2RGBA_I420 },
-       { 0, cv::COLOR_YUV2GRAY_NV12, 0, -1, 0, 0, 0, 0, 0, 0, cv::COLOR_YUV2RGB_NV12, cv::COLOR_YUV2RGBA_NV12 },
-       { 0, cv::COLOR_YUV2GRAY_YV12, 0, 0, -1, 0, 0, 0, 0, 0, cv::COLOR_YUV2RGB_YV12, cv::COLOR_YUV2RGBA_YV12 },
-       { 0, cv::COLOR_YUV2GRAY_NV21, 0, 0, 0, -1, 0, 0, 0, 0, cv::COLOR_YUV2RGB_NV21, cv::COLOR_YUV2RGBA_NV21 },
-       { 0, cv::COLOR_YUV2GRAY_YUYV, 0, 0, 0, 0, -1, 0, 0, 0, cv::COLOR_YUV2RGB_YUYV, cv::COLOR_YUV2RGBA_YUYV },
-       { 0, cv::COLOR_YUV2GRAY_UYVY, 0, 0, 0, 0, 0, -1, 0, 0, cv::COLOR_YUV2BGR_UYVY, cv::COLOR_YUV2BGRA_UYVY },
-       { 0, cv::COLOR_YUV2GRAY_Y422, 0, 0, 0, 0, 0, 0, -1, 0, cv::COLOR_YUV2RGB_Y422, cv::COLOR_YUV2RGBA_Y422 },
-       { 0, cv::COLOR_BGR5652GRAY, 0, 0, 0, 0, 0, 0, 0, -1, cv::COLOR_BGR5652BGR, cv::COLOR_BGR5652BGRA },
-       { 0, cv::COLOR_RGB2GRAY, 0, 0, 0, 0, 0, 0, 0, 0, -1, cv::COLOR_RGB2RGBA },
-       { 0, cv::COLOR_RGBA2GRAY, 0, 0, 0, 0, 0, 0, 0, cv::COLOR_BGRA2BGR565, cv::COLOR_RGBA2RGB, -1 }
-};
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-void Preprocess::colorConvert(cv::Mat &source, cv::Mat &dest, int sType, int dType)
-{
-       LOGI("ENTER");
-
-       auto conversionColor = static_cast<int>(colorConvertTable[sType][dType]);
-       if (conversionColor == -1) { /* Don't need conversion */
-               dest = source;
-       } else if (conversionColor > 0) {
-               /* Class for representation the given image as cv::Mat before conversion */
-               cv::cvtColor(source, dest, conversionColor);
-       } else {
-               throw InvalidOperation("Fail to ColorConvert");
-       }
-
-       LOGI("LEAVE");
-}
-
-void Preprocess::normalize(cv::Mat &source, cv::Mat &dest, const vector<double> &mean, const vector<double> &std)
-{
-       LOGI("ENTER");
-
-       try {
-               cv::subtract(source, cv::Scalar(mean[0], mean[1], mean[2]), dest);
-               source = dest;
-               cv::divide(source, cv::Scalar(std[0], std[1], std[2]), dest);
-       } catch (cv::Exception &e) {
-               throw InvalidOperation("Fail to substract/divide");
-       }
-
-       LOGI("LEAVE");
-}
-
-void Preprocess::quantize(cv::Mat &source, cv::Mat &dest, const vector<double> &scale, const vector<double> &zeropoint)
-{
-       LOGI("ENTER");
-
-       try {
-               cv::subtract(source, cv::Scalar(zeropoint[0], zeropoint[1], zeropoint[2]), dest);
-               source = dest;
-               cv::multiply(source, cv::Scalar(scale[0], scale[1], scale[2]), dest);
-       } catch (cv::Exception &e) {
-               throw InvalidOperation("Fail to subtract/multiply");
-       }
-
-       LOGI("LEAVE");
-}
-
-int Preprocess::convertToCv(int given_type, int ch)
-{
-       int type = 0;
-
-       switch (given_type) {
-       case INFERENCE_TENSOR_DATA_TYPE_UINT8:
-       case MV_INFERENCE_DATA_UINT8:
-               LOGI("Type is %d ch with UINT8", ch);
-               type = ch == 1 ? CV_8UC1 : CV_8UC3;
-               break;
-       case INFERENCE_TENSOR_DATA_TYPE_FLOAT32:
-       case MV_INFERENCE_DATA_FLOAT32:
-               LOGI("Type is %d ch with FLOAT32", ch);
-               type = ch == 1 ? CV_32FC1 : CV_32FC3;
-               break;
-       default:
-               LOGI("unknown data type so FLOAT32 data type will be used in default");
-               type = ch == 1 ? CV_32FC1 : CV_32FC3;
-               break;
-       }
-
-       return type;
-}
-
-void Preprocess::convertToCvSource(vector<mv_source_h> &mv_srcs, vector<cv::Mat> &cv_srcs)
-{
-       for (auto &mv_src : mv_srcs) {
-               mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
-               unsigned int width = 0, height = 0;
-               unsigned int bufferSize = 0;
-               unsigned char *buffer = NULL;
-
-               if (mv_source_get_width(mv_src, &width) != MEDIA_VISION_ERROR_NONE ||
-                       mv_source_get_height(mv_src, &height) != MEDIA_VISION_ERROR_NONE ||
-                       mv_source_get_colorspace(mv_src, &colorspace) != MEDIA_VISION_ERROR_NONE ||
-                       mv_source_get_buffer(mv_src, &buffer, &bufferSize))
-                       throw InvalidParameter("Invalid Parameter.");
-
-               _vImageWidth.push_back(width);
-               _vImageHeight.push_back(height);
-
-               // TODO. Let's support various color spaces.
-
-               if (colorspace != MEDIA_VISION_COLORSPACE_RGB888)
-                       throw InvalidOperation("Not Supported format.");
-
-               /* convert mv_source to cv::Mat */
-               cv::Mat cvSource = cv::Mat(cv::Size(width, height), CV_MAKETYPE(CV_8U, 3), buffer).clone();
-
-               cv_srcs.push_back(cvSource);
-               LOGI("Size: w:%u, h:%u", cvSource.size().width, cvSource.size().height);
-       }
-}
-
-void Preprocess::setConfig(const PreprocessConfig &config)
-{
-       _config = config;
-}
-
-template<typename T> void Preprocess::run(mv_source_h &mv_src, vector<T> &inputVector)
-{
-       LOGI("ENTER");
-
-       vector<cv::Mat> oriCvSources;
-       vector<mv_source_h> mv_srcs = { mv_src };
-
-       _vImageWidth.clear();
-       _vImageHeight.clear();
-       convertToCvSource(mv_srcs, oriCvSources);
-
-       inputVector.resize(_config.output_height * _config.output_width * _config.output_channel);
-
-       int data_type = convertToCv(_config.output_data_type, _config.output_channel);
-       // dest is a wrapper of the buffer.
-       cv::Mat dest(cv::Size(_config.output_width, _config.output_height), data_type, inputVector.data());
-       cv::Mat cvSource, cvDest;
-
-       // cvSource has new allocation with dest.size()
-       cv::resize(oriCvSources[0], cvSource, dest.size());
-
-       if (_config.skip_csc) {
-               cvSource.convertTo(dest, dest.type());
-       } else {
-               mv_colorspace_e colorspace = MEDIA_VISION_COLORSPACE_INVALID;
-               int ret = mv_source_get_colorspace(mv_srcs[0], &colorspace);
-               if (ret != MEDIA_VISION_ERROR_NONE)
-                       throw InvalidOperation("Fail to get color space.");
-
-               // cvDest is allocated if colorspace is not RGB888, and
-               // cvDest shares the data with cvSource if the colorspace is RGB888.
-               colorConvert(cvSource, cvDest, colorspace, _config.output_format);
-               cvDest.convertTo(dest, dest.type());
-       }
-
-       if (_config.normalize)
-               normalize(dest, dest, _config.mean, _config.std);
-
-       if (_config.quantize)
-               quantize(dest, dest, _config.scale, _config.zeropoint);
-
-       LOGI("LEAVE");
-}
-
-template void Preprocess::run<float>(mv_source_h &mv_src, vector<float> &inputVector);
-template void Preprocess::run<unsigned char>(mv_source_h &mv_src, vector<unsigned char> &inputVector);
-
-} /* machine_learning */
-} /* mediavision */
diff --git a/mv_machine_learning/common/src/MachineLearningNative.cpp b/mv_machine_learning/common/src/MachineLearningNative.cpp
deleted file mode 100644 (file)
index d361edb..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * 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 "mv_private.h"
-
-#include "MachineLearningNative.h"
-#include "machine_learning_exception.h"
-
-using namespace std;
-using namespace mediavision::common;
-using namespace mediavision::machine_learning;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-inline ITask *get_task(void *handle, const std::string &name)
-{
-       auto context = static_cast<Context *>(handle);
-
-       return context->__tasks.at(name);
-}
-
-void *machine_learning_native_create()
-{
-       return static_cast<void *>(new Context());
-}
-
-void machine_learning_native_add(void *handle, const string &task_name, ITask *task)
-{
-       auto context = static_cast<Context *>(handle);
-
-       context->__tasks.insert(make_pair(task_name, task));
-}
-
-void machine_learning_native_destory(void *handle)
-{
-       auto context = static_cast<Context *>(handle);
-
-       for (auto &m : context->__tasks)
-               delete m.second;
-
-       delete context;
-}
-
-void machine_learning_native_configure(void *handle, const string &task_name)
-{
-       auto task = get_task(handle, task_name);
-
-       task->configure();
-}
-
-void machine_learning_native_prepare(void *handle, const string &task_name)
-{
-       auto task = get_task(handle, task_name);
-
-       task->prepare();
-}
-
-void machine_learning_native_inference(void *handle, const string &task_name, InputBaseType &input)
-{
-       auto task = get_task(handle, task_name);
-
-       task->perform(input);
-}
-
-void machine_learning_native_inference_async(void *handle, const string &task_name, InputBaseType &input)
-{
-       auto task = get_task(handle, task_name);
-
-       task->performAsync(input);
-}
-
-OutputBaseType &machine_learning_native_get_result(void *handle, const string &task_name)
-{
-       auto task = get_task(handle, task_name);
-
-       return task->getOutput();
-}
-
-OutputBaseType &machine_learning_native_get_result_cache(void *handle, const string &task_name)
-{
-       auto task = get_task(handle, task_name);
-
-       return task->getOutputCache();
-}
-
-void machine_learning_native_set_model(void *handle, const string &task_name, const char *model_file,
-                                                                          const char *meta_file, const char *label_file, const char *model_name)
-{
-       auto task = get_task(handle, task_name);
-
-       task->setModelInfo(model_file, meta_file, label_file, model_name);
-}
-
-void machine_learning_native_set_engine(void *handle, const string &task_name, const char *backend_type,
-                                                                               const char *device_type)
-{
-       auto task = get_task(handle, task_name);
-
-       task->setEngineInfo(backend_type, device_type);
-}
-
-void machine_learning_native_get_engine_count(void *handle, const string &task_name, unsigned int *engine_count)
-{
-       auto task = get_task(handle, task_name);
-
-       *engine_count = task->getNumberOfEngines();
-}
-
-void machine_learning_native_get_engine_type(void *handle, const string &task_name, const unsigned int engine_index,
-                                                                                        char **engine_type)
-{
-       auto task = get_task(handle, task_name);
-
-       *engine_type = (char *) task->getEngineType(engine_index).c_str();
-}
-
-void machine_learning_native_get_device_count(void *handle, const string &task_name, const char *engine_type,
-                                                                                         unsigned int *device_count)
-{
-       auto task = get_task(handle, task_name);
-
-       *device_count = task->getNumberOfDevices(engine_type);
-}
-
-void machine_learning_native_get_device_type(void *handle, const string &task_name, const char *engine_type,
-                                                                                        const unsigned int device_index, char **device_type)
-{
-       auto task = get_task(handle, task_name);
-
-       *device_type = (char *) task->getDeviceType(engine_type, device_index).c_str();
-}
-
-}
-}
diff --git a/mv_machine_learning/common/src/MvMlConfig.cpp b/mv_machine_learning/common/src/MvMlConfig.cpp
new file mode 100644 (file)
index 0000000..e44a3d3
--- /dev/null
@@ -0,0 +1,186 @@
+/**
+ * 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 "MvMlException.h"
+#include "MvMlConfig.h"
+#include "keys.h"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+Config::Config()
+{}
+
+void Config::setBackendType(int backend_type)
+{
+       _backendType = backend_type;
+}
+
+void Config::setTargetDeviceType(int device_type)
+{
+       _targetDeviceType = device_type;
+}
+
+const std::string &Config::getDefaultModelName() const
+{
+       return _defaultModelName;
+}
+
+const std::string &Config::getModelFilePath() const
+{
+       return _modelFilePath;
+}
+
+const std::string &Config::getLabelFilePath() const
+{
+       return _modelLabelFilePath;
+}
+
+const std::string &Config::getPluginFileName() const
+{
+       return _pluginFileName;
+}
+
+MetaMap &Config::getInputMetaMap() const
+{
+       return _parser->getInputMetaMap();
+}
+
+MetaMap &Config::getOutputMetaMap() const
+{
+       return _parser->getOutputMetaMap();
+}
+
+double Config::getConfidenceThreshold() const
+{
+       return _confidence_threshold;
+}
+
+int Config::getBackendType() const
+{
+       return _backendType;
+}
+
+int Config::getTargetDeviceType() const
+{
+       return _targetDeviceType;
+}
+
+bool Config::isPluginUsed() const
+{
+       return _usePlugin;
+}
+
+void Config::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 Config::parseConfigFile(const std::string &configFilePath)
+{
+       auto config = make_unique<EngineConfig>(MV_CONFIG_PATH + configFilePath);
+
+       int ret = config->getStringAttribute(MV_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_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_TARGET_DEVICE_TYPE, &_targetDeviceType);
+               if (ret != MEDIA_VISION_ERROR_NONE)
+                       throw InvalidOperation("Fail to get target device type.");
+       }
+
+       ret = config->getStringAttribute(MV_MODEL_DEFAULT_PATH, &_modelDefaultPath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model default path");
+
+       ret = config->getStringAttribute(MV_MODEL_FILE_NAME, &_modelFilePath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model file path");
+
+       _modelFilePath = _modelDefaultPath + _modelFilePath;
+
+       ret = config->getStringAttribute(MV_MODEL_META_FILE_NAME, &_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());
+
+       ret = config->getStringAttribute(MV_MODEL_LABEL_FILE_NAME, &_modelLabelFilePath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model label file path");
+
+       _modelLabelFilePath = _modelDefaultPath + _modelLabelFilePath;
+
+       ret = config->getDoubleAttribute(MV_MODEL_CONFIDENCE_THRESHOLD, &_confidence_threshold);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               LOGW("threshold value doesn't exist.");
+}
+
+void Config::parsePluginConfigFile(const std::string &pluginConfigFilePath)
+{
+       auto config = make_unique<EngineConfig>(MV_CONFIG_PATH + pluginConfigFilePath);
+
+       int ret = config->getStringAttribute(MV_PLUGIN_NAME, &_pluginFileName);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model plugin file name");
+
+       ret = config->getStringAttribute(MV_DEFAULT_MODEL_NAME, &_defaultModelName);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get default model name.");
+
+       ret = config->getBooleanAttribute(MV_USE_PLUGIN, &_usePlugin);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get use_plugin value");
+}
+
+void Config::loadMetaFile(unique_ptr<MetaParser> parser)
+{
+       _parser = move(parser);
+       _parser->load(_modelMetaFilePath);
+}
+
+}
+}
diff --git a/mv_machine_learning/common/src/machine_learning_config.cpp b/mv_machine_learning/common/src/machine_learning_config.cpp
deleted file mode 100644 (file)
index bc7ff99..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * 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 "machine_learning_config.h"
-#include "machine_learning_key.h"
-
-using namespace std;
-using namespace MediaVision::Common;
-using namespace mediavision::machine_learning;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-MachineLearningConfig::MachineLearningConfig()
-{}
-
-void MachineLearningConfig::setBackendType(int backend_type)
-{
-       _backendType = backend_type;
-}
-
-void MachineLearningConfig::setTargetDeviceType(int device_type)
-{
-       _targetDeviceType = device_type;
-}
-
-const std::string &MachineLearningConfig::getDefaultModelName() const
-{
-       return _defaultModelName;
-}
-
-const std::string &MachineLearningConfig::getModelFilePath() const
-{
-       return _modelFilePath;
-}
-
-const std::string &MachineLearningConfig::getLabelFilePath() const
-{
-       return _modelLabelFilePath;
-}
-
-const std::string &MachineLearningConfig::getPluginFileName() const
-{
-       return _pluginFileName;
-}
-
-MetaMap &MachineLearningConfig::getInputMetaMap() const
-{
-       return _parser->getInputMetaMap();
-}
-
-MetaMap &MachineLearningConfig::getOutputMetaMap() const
-{
-       return _parser->getOutputMetaMap();
-}
-
-double MachineLearningConfig::getConfidenceThreshold() const
-{
-       return _confidence_threshold;
-}
-
-int MachineLearningConfig::getBackendType() const
-{
-       return _backendType;
-}
-
-int MachineLearningConfig::getTargetDeviceType() const
-{
-       return _targetDeviceType;
-}
-
-bool MachineLearningConfig::isPluginUsed() const
-{
-       return _usePlugin;
-}
-
-void MachineLearningConfig::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 MachineLearningConfig::parseConfigFile(const std::string &configFilePath)
-{
-       auto config = make_unique<EngineConfig>(MV_CONFIG_PATH + configFilePath);
-
-       int ret = config->getStringAttribute(MV_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_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_TARGET_DEVICE_TYPE, &_targetDeviceType);
-               if (ret != MEDIA_VISION_ERROR_NONE)
-                       throw InvalidOperation("Fail to get target device type.");
-       }
-
-       ret = config->getStringAttribute(MV_MODEL_DEFAULT_PATH, &_modelDefaultPath);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model default path");
-
-       ret = config->getStringAttribute(MV_MODEL_FILE_NAME, &_modelFilePath);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model file path");
-
-       _modelFilePath = _modelDefaultPath + _modelFilePath;
-
-       ret = config->getStringAttribute(MV_MODEL_META_FILE_NAME, &_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());
-
-       ret = config->getStringAttribute(MV_MODEL_LABEL_FILE_NAME, &_modelLabelFilePath);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model label file path");
-
-       _modelLabelFilePath = _modelDefaultPath + _modelLabelFilePath;
-
-       ret = config->getDoubleAttribute(MV_MODEL_CONFIDENCE_THRESHOLD, &_confidence_threshold);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               LOGW("threshold value doesn't exist.");
-}
-
-void MachineLearningConfig::parsePluginConfigFile(const std::string &pluginConfigFilePath)
-{
-       auto config = make_unique<EngineConfig>(MV_CONFIG_PATH + pluginConfigFilePath);
-
-       int ret = config->getStringAttribute(MV_PLUGIN_NAME, &_pluginFileName);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model plugin file name");
-
-       ret = config->getStringAttribute(MV_DEFAULT_MODEL_NAME, &_defaultModelName);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get default model name.");
-
-       ret = config->getBooleanAttribute(MV_USE_PLUGIN, &_usePlugin);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get use_plugin value");
-}
-
-void MachineLearningConfig::loadMetaFile(unique_ptr<MetaParser> parser)
-{
-       _parser = move(parser);
-       _parser->load(_modelMetaFilePath);
-}
-
-}
-}
diff --git a/mv_machine_learning/common/src/native_capi.cpp b/mv_machine_learning/common/src/native_capi.cpp
new file mode 100644 (file)
index 0000000..daa3b6d
--- /dev/null
@@ -0,0 +1,150 @@
+/**
+ * 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 "mv_private.h"
+
+#include "native_capi.h"
+#include "MvMlException.h"
+
+using namespace std;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+inline ITask *get_task(void *handle, const std::string &name)
+{
+       auto context = static_cast<Context *>(handle);
+
+       return context->__tasks.at(name);
+}
+
+void *machine_learning_native_create()
+{
+       return static_cast<void *>(new Context());
+}
+
+void machine_learning_native_add(void *handle, const string &task_name, ITask *task)
+{
+       auto context = static_cast<Context *>(handle);
+
+       context->__tasks.insert(make_pair(task_name, task));
+}
+
+void machine_learning_native_destory(void *handle)
+{
+       auto context = static_cast<Context *>(handle);
+
+       for (auto &m : context->__tasks)
+               delete m.second;
+
+       delete context;
+}
+
+void machine_learning_native_configure(void *handle, const string &task_name)
+{
+       auto task = get_task(handle, task_name);
+
+       task->configure();
+}
+
+void machine_learning_native_prepare(void *handle, const string &task_name)
+{
+       auto task = get_task(handle, task_name);
+
+       task->prepare();
+}
+
+void machine_learning_native_inference(void *handle, const string &task_name, InputBaseType &input)
+{
+       auto task = get_task(handle, task_name);
+
+       task->perform(input);
+}
+
+void machine_learning_native_inference_async(void *handle, const string &task_name, InputBaseType &input)
+{
+       auto task = get_task(handle, task_name);
+
+       task->performAsync(input);
+}
+
+OutputBaseType &machine_learning_native_get_result(void *handle, const string &task_name)
+{
+       auto task = get_task(handle, task_name);
+
+       return task->getOutput();
+}
+
+OutputBaseType &machine_learning_native_get_result_cache(void *handle, const string &task_name)
+{
+       auto task = get_task(handle, task_name);
+
+       return task->getOutputCache();
+}
+
+void machine_learning_native_set_model(void *handle, const string &task_name, const char *model_file,
+                                                                          const char *meta_file, const char *label_file, const char *model_name)
+{
+       auto task = get_task(handle, task_name);
+
+       task->setModelInfo(model_file, meta_file, label_file, model_name);
+}
+
+void machine_learning_native_set_engine(void *handle, const string &task_name, const char *backend_type,
+                                                                               const char *device_type)
+{
+       auto task = get_task(handle, task_name);
+
+       task->setEngineInfo(backend_type, device_type);
+}
+
+void machine_learning_native_get_engine_count(void *handle, const string &task_name, unsigned int *engine_count)
+{
+       auto task = get_task(handle, task_name);
+
+       *engine_count = task->getNumberOfEngines();
+}
+
+void machine_learning_native_get_engine_type(void *handle, const string &task_name, const unsigned int engine_index,
+                                                                                        char **engine_type)
+{
+       auto task = get_task(handle, task_name);
+
+       *engine_type = (char *) task->getEngineType(engine_index).c_str();
+}
+
+void machine_learning_native_get_device_count(void *handle, const string &task_name, const char *engine_type,
+                                                                                         unsigned int *device_count)
+{
+       auto task = get_task(handle, task_name);
+
+       *device_count = task->getNumberOfDevices(engine_type);
+}
+
+void machine_learning_native_get_device_type(void *handle, const string &task_name, const char *engine_type,
+                                                                                        const unsigned int device_index, char **device_type)
+{
+       auto task = get_task(handle, task_name);
+
+       *device_type = (char *) task->getDeviceType(engine_type, device_index).c_str();
+}
+
+}
+}
diff --git a/mv_machine_learning/face_recognition/include/FaceRecognition.h b/mv_machine_learning/face_recognition/include/FaceRecognition.h
new file mode 100644 (file)
index 0000000..5f2bdfa
--- /dev/null
@@ -0,0 +1,109 @@
+/**
+ * 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_H__
+#define __FACE_RECOGNITION_H__
+
+#include <unordered_map>
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+#include "training_engine_error.h"
+#include "training_engine_common_impl.h"
+#include "inference_engine_common_impl.h"
+#include "mv_ml_types.h"
+#include "Inference.h"
+#include "LabelManager.h"
+#include "FeatureVectorManager.h"
+#include "DataSetManager.h"
+#include "SimpleShot.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+namespace face_recognition
+{
+enum class WorkingStatus { NONE, INITIALIZED, TRAINED, INFERENCED };
+
+enum class RequestMode { REGISTER, INFERENCE, DELETE };
+}
+
+struct FaceRecognitionInput : public InputBaseType {
+       FaceRecognitionInput(mv_source_h src = nullptr) : InputBaseType(src)
+       {}
+       face_recognition::RequestMode mode {};
+       std::vector<std::vector<float> > inputs;
+       std::vector<std::string> labels;
+};
+
+/**
+ * @brief The face recognition result structure.
+ * @details Contains face recognition result such as label, label index, raw data,
+ *          and raw data count.
+ */
+struct FaceRecognitionResult : public OutputBaseType {
+       unsigned int label_idx {}; /**< label index of label file. */
+       std::vector<float> raw_data; /**< raw data to each label. */
+       std::vector<std::string> labels;
+       std::string label; /**< label string. */
+       bool is_valid {}; /**< inference result is valid or not. */
+};
+
+struct FaceRecognitionConfig {
+       training_target_type_e training_target_device_type { TRAINING_TARGET_NONE };
+       training_backend_type_e training_engine_backend_type { TRAINING_BACKEND_NONE };
+       mv_inference_target_device_e inference_target_device_type { MV_INFERENCE_TARGET_DEVICE_NONE };
+       mv_inference_backend_type_e inference_engine_backend_type { MV_INFERENCE_BACKEND_NONE };
+       std::string internal_model_file_path;
+       std::string label_file_path;
+       std::string feature_vector_file_path;
+       double decision_threshold {};
+       std::vector<size_t> input_tensor_shape;
+};
+
+class FaceRecognition
+{
+private:
+       face_recognition::WorkingStatus _status { face_recognition::WorkingStatus::NONE };
+       std::unique_ptr<mediavision::inference::Inference> _internal;
+       std::unique_ptr<mediavision::inference::Inference> _backbone;
+       std::unique_ptr<TrainingModel> _training_model;
+       std::unique_ptr<LabelManager> _label_manager;
+       FaceRecognitionConfig _config;
+       FaceRecognitionResult _result;
+
+       void checkFeatureVectorFile(std::string fv_file_name, std::string new_fv_file_name);
+       void storeDataSet(std::unique_ptr<DataSetManager> &data_set, unsigned int label_cnt);
+       void checkResult();
+       void trainModel();
+
+public:
+       FaceRecognition() = default;
+       ~FaceRecognition() = default;
+
+       int initialize();
+       void setConfig(FaceRecognitionConfig &config);
+       int registerNewFace(std::vector<float> &input_vec, std::string label_name);
+       int recognizeFace(std::vector<float> &input_vec);
+       int deleteLabel(std::string label_name);
+       FaceRecognitionResult &result();
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
diff --git a/mv_machine_learning/face_recognition/include/FaceRecognitionAdapter.h b/mv_machine_learning/face_recognition/include/FaceRecognitionAdapter.h
new file mode 100644 (file)
index 0000000..f45a565
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * 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 "FaceRecognition.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FaceRecognitionAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<FaceRecognition> _face_recognition;
+       std::unique_ptr<MediaVision::Common::EngineConfig> _config;
+
+public:
+       FaceRecognitionAdapter();
+       ~FaceRecognitionAdapter();
+
+       std::unique_ptr<MediaVision::Common::EngineConfig> &getConfig()
+       {
+               return _config;
+       }
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/FaceRecognitionDSM.h b/mv_machine_learning/face_recognition/include/FaceRecognitionDSM.h
new file mode 100644 (file)
index 0000000..196b965
--- /dev/null
@@ -0,0 +1,40 @@
+/**
+ * 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_DSM_H__
+#define __FACE_RECOGNITION_DSM_H__
+
+#include <string>
+
+#include "FeatureVectorManager.h"
+#include "DataSetManager.h"
+
+class FaceRecognitionDSM : public DataSetManager
+{
+private:
+       void printHeader(FeaVecHeader &fvh);
+       bool isHeaderValid(const FeaVecHeader &fvh);
+
+public:
+       FaceRecognitionDSM();
+       ~FaceRecognitionDSM() = default;
+
+       bool isFeatureVectorAllowed(unsigned int label_idx) override;
+       void loadDataSet(const std::string &file_name, unsigned int new_label_cnt) override;
+       void addDataSet(std::vector<float> &feature_vec, unsigned int label_idx, unsigned int label_cnt) override;
+};
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/FaceRecognitionFVM.h b/mv_machine_learning/face_recognition/include/FaceRecognitionFVM.h
new file mode 100644 (file)
index 0000000..ff14faa
--- /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 __FACE_RECOGNITION_FVM_H__
+#define __FACE_RECOGNITION_FVM_H__
+
+#include <string.h>
+#include <vector>
+
+#include "FeatureVectorManager.h"
+#include "file_util.h"
+
+class FaceRecognitionFVM : public FeatureVectorManager
+{
+public:
+       FaceRecognitionFVM(const std::string feature_vector_file = "feature_vector_file.dat");
+       ~FaceRecognitionFVM() = default;
+
+       void updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) override;
+       void storeData(std::vector<std::vector<float> > &features_vec, std::vector<unsigned int> &label_index) override;
+       void remove() override;
+};
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/Facenet.h b/mv_machine_learning/face_recognition/include/Facenet.h
new file mode 100644 (file)
index 0000000..a154f51
--- /dev/null
@@ -0,0 +1,77 @@
+/**
+ * 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 __FACENET_H__
+#define __FACENET_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+#include "EngineConfig.h"
+#include "inference_engine_common_impl.h"
+#include "Inference.h"
+#include "FacenetParser.h"
+#include "face_recognition_type.h"
+#include "MvMlPreprocess.h"
+#include "mv_ml_types.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+struct FacenetInput : public InputBaseType {
+       FacenetInput(mv_source_h src = nullptr) : InputBaseType(src)
+       {}
+};
+
+struct FacenetOutput : public OutputBaseType {
+       std::vector<std::vector<float> > outputs;
+};
+
+class Facenet
+{
+protected:
+       std::unique_ptr<mediavision::inference::Inference> _inference;
+       std::unique_ptr<MediaVision::Common::EngineConfig> _config;
+       std::unique_ptr<MetaParser> _parser;
+       FacenetOutput _result;
+       inference_engine_tensor_buffer *_outputTensorBuffer {};
+       Preprocess _preprocess;
+       std::string _modelFileName;
+       std::string _modelMetaFileName;
+       std::string _facenetOutputTensorName;
+       int _backendType {};
+       int _targetDeviceType {};
+
+       template<typename T>
+       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
+       template<typename T> void inference(std::vector<std::vector<T> > &inputVectors);
+
+public:
+       Facenet();
+       virtual ~Facenet() = default;
+       void parseMetaFile();
+       std::shared_ptr<MetaInfo> getInputMetaInfo();
+       void configure();
+       void prepare();
+       template<typename T> void perform(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo);
+       FacenetOutput &result();
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/FacenetAdapter.h b/mv_machine_learning/face_recognition/include/FacenetAdapter.h
new file mode 100644 (file)
index 0000000..b2ef514
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * 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 __FACENET_ADAPTER_H__
+#define __FACENET_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "mv_ml_types.h"
+#include "Facenet.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FacenetAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<Facenet> _facenet;
+
+public:
+       FacenetAdapter();
+       ~FacenetAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/FacenetParser.h b/mv_machine_learning/face_recognition/include/FacenetParser.h
new file mode 100644 (file)
index 0000000..09a2c43
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * 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 __FACENET_PARSER_H__
+#define __FACENET_PARSER_H__
+
+#include "MetaParser.h"
+#include "PostprocessParser.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FacenetParser : public MetaParser
+{
+private:
+       PostprocessParser _postprocessParser;
+
+protected:
+       void parsePostprocess(std::shared_ptr<MetaInfo> meta_info, JsonObject *in_obj) override;
+
+public:
+       FacenetParser(int task_type = 0);
+       ~FacenetParser();
+};
+
+}
+}
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/SimpleShot.h b/mv_machine_learning/face_recognition/include/SimpleShot.h
new file mode 100644 (file)
index 0000000..48ef349
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * 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 __SIMPLE_SHOT_H__
+#define __SIMPLE_SHOT_H__
+
+#include <mv_inference_type.h>
+#include "TrainingModel.h"
+
+class SimpleShot : public TrainingModel
+{
+private:
+       TrainingEngineBackendInfo _engine_info;
+
+private:
+       void saveModel(const std::string file_path) override;
+       void removeModel(const std::string file_path) override;
+
+public:
+       SimpleShot(const training_backend_type_e backend_type, const training_target_type_e target_type,
+                          const std::vector<size_t> input_tensor_shape, const std::string internal_model_file);
+       ~SimpleShot();
+
+       // Configure layers for SimpleShot learning.
+       void configureModel(int num_of_class) override;
+       TrainingEngineBackendInfo &getTrainingEngineInfo() override;
+};
+
+#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
deleted file mode 100644 (file)
index 8f5e15a..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/**
- * 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_H__
-#define __FACE_RECOGNITION_H__
-
-#include <unordered_map>
-#include <mv_common.h>
-#include <mv_inference_type.h>
-
-#include "training_engine_error.h"
-#include "training_engine_common_impl.h"
-#include "inference_engine_common_impl.h"
-#include "MachineLearningType.h"
-#include "Inference.h"
-#include "label_manager.h"
-#include "feature_vector_manager.h"
-#include "data_set_manager.h"
-#include "simple_shot.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-namespace face_recognition
-{
-enum class WorkingStatus { NONE, INITIALIZED, TRAINED, INFERENCED };
-
-enum class RequestMode { REGISTER, INFERENCE, DELETE };
-}
-
-struct FaceRecognitionInput : public InputBaseType {
-       FaceRecognitionInput(mv_source_h src = nullptr) : InputBaseType(src)
-       {}
-       face_recognition::RequestMode mode {};
-       std::vector<std::vector<float> > inputs;
-       std::vector<std::string> labels;
-};
-
-/**
- * @brief The face recognition result structure.
- * @details Contains face recognition result such as label, label index, raw data,
- *          and raw data count.
- */
-struct FaceRecognitionResult : public OutputBaseType {
-       unsigned int label_idx {}; /**< label index of label file. */
-       std::vector<float> raw_data; /**< raw data to each label. */
-       std::vector<std::string> labels;
-       std::string label; /**< label string. */
-       bool is_valid {}; /**< inference result is valid or not. */
-};
-
-struct FaceRecognitionConfig {
-       training_target_type_e training_target_device_type { TRAINING_TARGET_NONE };
-       training_backend_type_e training_engine_backend_type { TRAINING_BACKEND_NONE };
-       mv_inference_target_device_e inference_target_device_type { MV_INFERENCE_TARGET_DEVICE_NONE };
-       mv_inference_backend_type_e inference_engine_backend_type { MV_INFERENCE_BACKEND_NONE };
-       std::string internal_model_file_path;
-       std::string label_file_path;
-       std::string feature_vector_file_path;
-       double decision_threshold {};
-       std::vector<size_t> input_tensor_shape;
-};
-
-class FaceRecognition
-{
-private:
-       face_recognition::WorkingStatus _status { face_recognition::WorkingStatus::NONE };
-       std::unique_ptr<mediavision::inference::Inference> _internal;
-       std::unique_ptr<mediavision::inference::Inference> _backbone;
-       std::unique_ptr<TrainingModel> _training_model;
-       std::unique_ptr<LabelManager> _label_manager;
-       FaceRecognitionConfig _config;
-       FaceRecognitionResult _result;
-
-       void checkFeatureVectorFile(std::string fv_file_name, std::string new_fv_file_name);
-       void storeDataSet(std::unique_ptr<DataSetManager> &data_set, unsigned int label_cnt);
-       void checkResult();
-       void trainModel();
-
-public:
-       FaceRecognition() = default;
-       ~FaceRecognition() = default;
-
-       int initialize();
-       void setConfig(FaceRecognitionConfig &config);
-       int registerNewFace(std::vector<float> &input_vec, std::string label_name);
-       int recognizeFace(std::vector<float> &input_vec);
-       int deleteLabel(std::string label_name);
-       FaceRecognitionResult &result();
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
diff --git a/mv_machine_learning/face_recognition/include/face_recognition_adapter.h b/mv_machine_learning/face_recognition/include/face_recognition_adapter.h
deleted file mode 100644 (file)
index 3487d72..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class FaceRecognitionAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<FaceRecognition> _face_recognition;
-       std::unique_ptr<MediaVision::Common::EngineConfig> _config;
-
-public:
-       FaceRecognitionAdapter();
-       ~FaceRecognitionAdapter();
-
-       std::unique_ptr<MediaVision::Common::EngineConfig> &getConfig()
-       {
-               return _config;
-       }
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/face_recognition_dsm.h b/mv_machine_learning/face_recognition/include/face_recognition_dsm.h
deleted file mode 100644 (file)
index 1151706..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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_DSM_H__
-#define __FACE_RECOGNITION_DSM_H__
-
-#include <string>
-
-#include "feature_vector_manager.h"
-#include "data_set_manager.h"
-
-class FaceRecognitionDSM : public DataSetManager
-{
-private:
-       void printHeader(FeaVecHeader &fvh);
-       bool isHeaderValid(const FeaVecHeader &fvh);
-
-public:
-       FaceRecognitionDSM();
-       ~FaceRecognitionDSM() = default;
-
-       bool isFeatureVectorAllowed(unsigned int label_idx) override;
-       void loadDataSet(const std::string &file_name, unsigned int new_label_cnt) override;
-       void addDataSet(std::vector<float> &feature_vec, unsigned int label_idx, unsigned int label_cnt) override;
-};
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/face_recognition_fvm.h b/mv_machine_learning/face_recognition/include/face_recognition_fvm.h
deleted file mode 100644 (file)
index 1b4cfdc..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * 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_FVM_H__
-#define __FACE_RECOGNITION_FVM_H__
-
-#include <string.h>
-#include <vector>
-
-#include "feature_vector_manager.h"
-#include "file_util.h"
-
-class FaceRecognitionFVM : public FeatureVectorManager
-{
-public:
-       FaceRecognitionFVM(const std::string feature_vector_file = "feature_vector_file.dat");
-       ~FaceRecognitionFVM() = default;
-
-       void updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) override;
-       void storeData(std::vector<std::vector<float> > &features_vec, std::vector<unsigned int> &label_index) override;
-       void remove() override;
-};
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/facenet.h b/mv_machine_learning/face_recognition/include/facenet.h
deleted file mode 100644 (file)
index d5780ca..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * 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 __FACENET_H__
-#define __FACENET_H__
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-
-#include "EngineConfig.h"
-#include "inference_engine_common_impl.h"
-#include "Inference.h"
-#include "facenet_parser.h"
-#include "face_recognition_type.h"
-#include "machine_learning_preprocess.h"
-#include "MachineLearningType.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-struct FacenetInput : public InputBaseType {
-       FacenetInput(mv_source_h src = nullptr) : InputBaseType(src)
-       {}
-};
-
-struct FacenetOutput : public OutputBaseType {
-       std::vector<std::vector<float> > outputs;
-};
-
-class Facenet
-{
-protected:
-       std::unique_ptr<mediavision::inference::Inference> _inference;
-       std::unique_ptr<MediaVision::Common::EngineConfig> _config;
-       std::unique_ptr<MetaParser> _parser;
-       FacenetOutput _result;
-       inference_engine_tensor_buffer *_outputTensorBuffer {};
-       Preprocess _preprocess;
-       std::string _modelFileName;
-       std::string _modelMetaFileName;
-       std::string _facenetOutputTensorName;
-       int _backendType {};
-       int _targetDeviceType {};
-
-       template<typename T>
-       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
-       template<typename T> void inference(std::vector<std::vector<T> > &inputVectors);
-
-public:
-       Facenet();
-       virtual ~Facenet() = default;
-       void parseMetaFile();
-       std::shared_ptr<MetaInfo> getInputMetaInfo();
-       void configure();
-       void prepare();
-       template<typename T> void perform(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo);
-       FacenetOutput &result();
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/facenet_adapter.h b/mv_machine_learning/face_recognition/include/facenet_adapter.h
deleted file mode 100644 (file)
index cfb81ee..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * 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 __FACENET_ADAPTER_H__
-#define __FACENET_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "MachineLearningType.h"
-#include "facenet.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class FacenetAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<Facenet> _facenet;
-
-public:
-       FacenetAdapter();
-       ~FacenetAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/facenet_parser.h b/mv_machine_learning/face_recognition/include/facenet_parser.h
deleted file mode 100644 (file)
index 09a2c43..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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 __FACENET_PARSER_H__
-#define __FACENET_PARSER_H__
-
-#include "MetaParser.h"
-#include "PostprocessParser.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class FacenetParser : public MetaParser
-{
-private:
-       PostprocessParser _postprocessParser;
-
-protected:
-       void parsePostprocess(std::shared_ptr<MetaInfo> meta_info, JsonObject *in_obj) override;
-
-public:
-       FacenetParser(int task_type = 0);
-       ~FacenetParser();
-};
-
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/include/simple_shot.h b/mv_machine_learning/face_recognition/include/simple_shot.h
deleted file mode 100644 (file)
index 804a3e2..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * 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 __SIMPLE_SHOT_H__
-#define __SIMPLE_SHOT_H__
-
-#include <mv_inference_type.h>
-#include "training_model.h"
-
-class SimpleShot : public TrainingModel
-{
-private:
-       TrainingEngineBackendInfo _engine_info;
-
-private:
-       void saveModel(const std::string file_path) override;
-       void removeModel(const std::string file_path) override;
-
-public:
-       SimpleShot(const training_backend_type_e backend_type, const training_target_type_e target_type,
-                          const std::vector<size_t> input_tensor_shape, const std::string internal_model_file);
-       ~SimpleShot();
-
-       // Configure layers for SimpleShot learning.
-       void configureModel(int num_of_class) override;
-       TrainingEngineBackendInfo &getTrainingEngineInfo() override;
-};
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/FaceRecognition.cpp b/mv_machine_learning/face_recognition/src/FaceRecognition.cpp
new file mode 100644 (file)
index 0000000..2af63a2
--- /dev/null
@@ -0,0 +1,428 @@
+/**
+ * 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 <string.h>
+#include <fstream>
+#include <istream>
+#include <tuple>
+#include <map>
+#include <algorithm>
+
+#include <sys/stat.h>
+
+#include <dlog.h>
+#include <mv_common.h>
+#include <mv_private.h>
+
+#include "MvMlException.h"
+#include "TensorBuffer.h"
+#include "FaceRecognition.h"
+#include "FaceRecognitionFVM.h"
+#include "FaceRecognitionDSM.h"
+#include "file_util.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace TrainingEngineInterface::Common;
+using namespace mediavision::machine_learning::face_recognition;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+void FaceRecognition::checkFeatureVectorFile(string fv_file_name, string new_fv_file_name)
+{
+       // Change new feature vector file to existing one in case that current process is terminated just after removing existing feature vector file but
+       // new feature vector file isn't changed to existing one yet.
+       if (FaceRecogUtil::isFileExist(new_fv_file_name) && !FaceRecogUtil::isFileExist(fv_file_name)) {
+               int ret = ::rename(new_fv_file_name.c_str(), fv_file_name.c_str());
+               if (ret)
+                       throw InvalidOperation("Fail to rename new feature vector file to original one.");
+
+               return;
+       }
+
+       // Make sure to remove a temp file in case that current process is terminated just after generating new feature vector file
+       // which is not correct file but existing one isn't removed. In this case, existing file is used again.
+       if (FaceRecogUtil::isFileExist(new_fv_file_name)) {
+               int ret = ::remove(new_fv_file_name.c_str());
+               if (ret)
+                       throw InvalidOperation("Fail to remove new feature vector file.");
+       }
+}
+
+void FaceRecognition::storeDataSet(unique_ptr<DataSetManager> &data_set, unsigned int label_cnt)
+{
+       try {
+               unique_ptr<FeatureVectorManager> fvm = make_unique<FaceRecognitionFVM>(_config.feature_vector_file_path);
+               unique_ptr<FeatureVectorManager> fvm_new =
+                               make_unique<FaceRecognitionFVM>(_config.feature_vector_file_path + ".new");
+
+               // Make sure feature vector file.
+               checkFeatureVectorFile(fvm->getFileName(), fvm_new->getFileName());
+
+               // Write feature vector header.
+               fvm_new->updateHeader(data_set->getFeaVecSize(), label_cnt, data_set->getData().size());
+
+               // Write feature vector and it's label index.
+               fvm_new->storeData(data_set->getData(), data_set->getLabelIdx());
+
+               int ret = 0;
+
+               // Change new data file to existing one.
+               if (FaceRecogUtil::isFileExist(fvm->getFileName())) {
+                       ret = ::remove(fvm->getFileName().c_str());
+                       if (ret)
+                               throw InvalidOperation("Fail to remove feature vector file.");
+               }
+
+               ret = ::rename(fvm_new->getFileName().c_str(), fvm->getFileName().c_str());
+               if (ret)
+                       throw InvalidOperation("Fail to rename new feature vector file to original one.");
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               throw e;
+       }
+}
+
+void FaceRecognition::setConfig(FaceRecognitionConfig &config)
+{
+       _config = config;
+}
+
+int FaceRecognition::initialize()
+{
+       _training_model = make_unique<SimpleShot>(_config.training_engine_backend_type, _config.training_target_device_type,
+                                                                                         _config.input_tensor_shape, _config.internal_model_file_path);
+
+       _internal = make_unique<Inference>();
+       _label_manager = make_unique<LabelManager>(_config.label_file_path, _config.decision_threshold);
+
+       int ret = _internal->bind(_config.inference_engine_backend_type, _config.inference_target_device_type);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               return ret;
+
+       _status = WorkingStatus::INITIALIZED;
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceRecognition::registerNewFace(std::vector<float> &input_vec, string label_name)
+{
+       if (_status < WorkingStatus::INITIALIZED) {
+               LOGE("Initialization not ready yet.");
+               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+       }
+
+       // TODO. consider data augmentation.
+       try {
+               // Store a new label name to label file if the given label doesn't exist.
+               if (!_label_manager->isExist(label_name))
+                       _label_manager->addLabelToFile(label_name);
+
+               // Import label data from a label file.
+               _label_manager->importLabel();
+
+               // Get label index and count.
+               unsigned int label_idx = _label_manager->getLabelIndex(label_name);
+               unsigned int label_cnt = _label_manager->getMaxLabel();
+
+               unique_ptr<DataSetManager> data_set = make_unique<FaceRecognitionDSM>();
+
+               data_set->clear();
+
+               // Load existing feature vectors if the feature vector file exists.
+               if (FaceRecogUtil::isFileExist(_config.feature_vector_file_path) == true) {
+                       LOGI("feature vector file already exists so it loads the file first.");
+                       data_set->loadDataSet(_config.feature_vector_file_path, label_cnt);
+               }
+
+               // Add new feature vector only in case that feature vector count of given label_idx is less then 5.
+               // It means that only 5 set of feature vector per a label is valid.
+               // TODO. According to feature vector priority, new feature vector should be added.
+               if (data_set->isFeatureVectorAllowed(label_idx))
+                       data_set->addDataSet(input_vec, label_idx, label_cnt);
+
+               // Store dataset to feature vector file.
+               storeDataSet(data_set, label_cnt);
+               data_set->clear();
+
+               trainModel();
+               _result.is_valid = false;
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+void FaceRecognition::checkResult()
+{
+       // Check decision threshold.
+       if (_result.raw_data[_result.label_idx] < _label_manager->getDecisionThreshold())
+               throw NoData("Not meet decision threshold.");
+
+       float weighted = _result.raw_data[_result.label_idx] * _label_manager->getDecisionWeight();
+
+       // Check decision weight threshold.
+       for (size_t i = 0; i < _result.raw_data.size(); i++) {
+               if (i != _result.label_idx && _result.raw_data[i] > weighted)
+                       throw NoData("Not meet decision weight threshold");
+       }
+}
+
+void FaceRecognition::trainModel()
+{
+       // Load existing feature vectors if the feature vector file exists.
+       if (!FaceRecogUtil::isFileExist(_config.feature_vector_file_path))
+               throw InvalidOperation("Feature vector file does not exist.");
+
+       unsigned int label_cnt = _label_manager->getMaxLabel();
+       unique_ptr<DataSetManager> data_set = make_unique<FaceRecognitionDSM>();
+
+       data_set->loadDataSet(_config.feature_vector_file_path, label_cnt);
+
+       // Configure and train the model
+       // TODO: No need to configure the model again if number of labels don't change
+       _training_model->configureModel(label_cnt);
+       _training_model->applyDataSet(data_set);
+       _training_model->compile();
+       _training_model->train();
+
+       _training_model->clearDataSet();
+
+       _status = WorkingStatus::TRAINED;
+}
+
+int FaceRecognition::recognizeFace(std::vector<float> &input_vec)
+{
+       if (_status == WorkingStatus::NONE) {
+               LOGE("Initialization not ready yet.");
+               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+       }
+
+       // Face Recognition has following steps
+       // ------------------------------------
+       // 1. Import label data to in-memory from a file.
+       // 2. Load internal model.
+       // 3. Do an inference with the internal model to get a label.
+       // 4. Get the label best suitable to the output tensor and return the label.
+
+       try {
+               // Import label data from a label file.
+               _label_manager->importLabel();
+
+               if (_label_manager->isEmpty()) {
+                       _result.is_valid = false;
+                       _status = WorkingStatus::INFERENCED;
+
+                       return MEDIA_VISION_ERROR_NO_DATA;
+               }
+
+               if (!FaceRecogUtil::isFileExist(_config.internal_model_file_path)) {
+                       LOGE("Internal model file(%s) doesn't exist.", _config.internal_model_file_path.c_str());
+                       return MEDIA_VISION_ERROR_NO_DATA;
+               }
+
+               TrainingEngineBackendInfo engine_info = _training_model->getTrainingEngineInfo();
+               vector<string> &input_layers = engine_info.input_layer_names;
+               vector<inference_engine_tensor_info> &input_tensor_info = engine_info.input_tensor_info;
+               vector<string> &output_layers = engine_info.output_layer_names;
+               vector<inference_engine_tensor_info> &output_tensor_info = engine_info.output_tensor_info;
+
+               if (_status != WorkingStatus::INFERENCED) {
+                       // Tensor order is NCHW.
+                       size_t width = input_tensor_info[0].shape[0];
+                       size_t height = input_tensor_info[0].shape[1];
+                       size_t ch = input_tensor_info[0].shape[2];
+
+                       _internal->configureInputInfo(width, height, 1, ch, 1.0f, 0.0f, MV_INFERENCE_DATA_FLOAT32, input_layers);
+
+                       // Output tensor size should be a number of labels so update it.
+                       output_tensor_info[0].shape[0] = _label_manager->getMaxLabel();
+
+                       _internal->configureOutputInfo(output_layers, output_tensor_info);
+                       _internal->configureModelFiles("", _config.internal_model_file_path, "");
+
+                       // Load the trained internal model.
+                       if (_internal->load() != INFERENCE_ENGINE_ERROR_NONE) {
+                               LOGE("Fail to Load.");
+                               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+                       }
+               }
+
+               std::vector<std::vector<float> > input_tensors = { input_vec };
+
+               // Do inference to the internal model.
+               if (_internal->run<float>(input_tensors) != INFERENCE_ENGINE_ERROR_NONE) {
+                       LOGE("fail to inference internal model.");
+                       return MEDIA_VISION_ERROR_INVALID_OPERATION;
+               }
+
+               // output layer size should be 1.
+               TensorBuffer tensorBuffer = _internal->getOutputTensorBuffer();
+               inference_engine_tensor_buffer *internal_output_buffer = tensorBuffer.getTensorBuffer(output_layers[0]);
+               if (!internal_output_buffer) {
+                       LOGE("fail to get internal output tensor buffer.");
+                       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+               }
+
+               auto raw_buffer = static_cast<float *>(internal_output_buffer->buffer);
+
+               // Update the result because user can want to get the result regardless of the decision threshold
+               // to check how many people are registered to the label file.
+               //
+               // TODO. as for this, we may need to introduce a new API to provide the number of people later.
+               _result.raw_data.clear();
+               copy(raw_buffer, raw_buffer + internal_output_buffer->size / sizeof(float), back_inserter(_result.raw_data));
+
+               string result_str;
+
+               for (const auto &r : _result.raw_data)
+                       result_str += to_string(r) + " ";
+
+               LOGD("raw data = %s", result_str.c_str());
+
+               _result.labels.clear();
+               _result.labels = _label_manager->getLabels();
+
+               unsigned int answer_index =
+                               max_element(_result.raw_data.begin(), _result.raw_data.end()) - _result.raw_data.begin();
+               _result.label_idx = answer_index;
+               _result.is_valid = true;
+
+               _status = WorkingStatus::INFERENCED;
+
+               checkResult();
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int FaceRecognition::deleteLabel(string label_name)
+{
+       if (_status < WorkingStatus::INITIALIZED) {
+               LOGE("Initialization not ready yet.");
+               return MEDIA_VISION_ERROR_INVALID_OPERATION;
+       }
+
+       // Deleting a given label is to remove existing registered person from label and feature vector files.
+
+       try {
+               if (!_label_manager->isExist(label_name)) {
+                       LOGE("%s doesn't exist in label file.", label_name.c_str());
+                       return MEDIA_VISION_ERROR_INVALID_OPERATION;
+               }
+
+               // Import label data from a label file.
+               _label_manager->importLabel();
+
+               unsigned int target_label_idx = _label_manager->getLabelIndex(label_name);
+               auto label_cnt_ori = _label_manager->getMaxLabel();
+
+               LOGD("Current label count is %zu", label_cnt_ori);
+               LOGD("The index of label name(%s) is %d", label_name.c_str(), target_label_idx);
+
+               // Get label count after removing a given label from the label file.
+               _label_manager->removeLabel(label_name);
+
+               auto label_cnt = _label_manager->getMaxLabel();
+
+               LOGD("Current label count is %zu after removing the label(%s)", label_cnt, label_name.c_str());
+
+               unique_ptr<DataSetManager> data_set = make_unique<FaceRecognitionDSM>();
+               unique_ptr<DataSetManager> data_set_new = make_unique<FaceRecognitionDSM>();
+
+               // feature vectors corresponding to given label aren't removed yet from feature vector file.
+               // So label_cnt_ori is needed.
+               LOGD("Load the original feature vector data from the feature vector file.");
+               data_set->loadDataSet(_config.feature_vector_file_path, label_cnt_ori);
+
+               vector<vector<float> > feature_vectors_old = data_set->getData();
+               vector<unsigned int> label_idx_vectors_old = data_set->getLabelIdx();
+
+               // Write existing feature vectors and its one-hot encoding table with updated label.
+               for (unsigned int idx = 0; idx < feature_vectors_old.size(); ++idx) {
+                       // Except the data sets with a given target_label_idx.
+                       if (label_idx_vectors_old[idx] == target_label_idx)
+                               continue;
+
+                       // One-hot encoding table should be updated.
+                       // Assume that below label file exists for example,
+                       //     In label file
+                       //     -------------
+                       //     offset 0 : label 1
+                       //     offset 1 : label 2
+                       //     offset 2 : label 3
+                       //
+                       //     One hot encoding table should be updated like below after removing label 1,
+                       //     In label file
+                       //     -------------
+                       //     offset 0 : label 2
+                       //     offset 1 : label 3
+                       //
+                       // So if the index of removed label less than remaining index then decrease each index.
+                       if (label_idx_vectors_old[idx] > target_label_idx)
+                               label_idx_vectors_old[idx]--;
+
+                       data_set_new->addDataSet(feature_vectors_old[idx], label_idx_vectors_old[idx], label_cnt);
+               }
+
+               // Store only in case that feature vectors exist.
+               if (data_set_new->getData().size() > 0) {
+                       storeDataSet(data_set_new, label_cnt);
+                       trainModel();
+               } else {
+                       _training_model->removeModel();
+                       _label_manager->removeFile();
+
+                       LOGD("No training data so removed all relevant files.");
+               }
+
+               _result.is_valid = false;
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+FaceRecognitionResult &FaceRecognition::result()
+{
+       if (!_result.is_valid)
+               throw NoData("Inference result not ready yet.");
+
+       if (!_label_manager)
+               throw NoData("Label file doesn't exist.");
+
+       try {
+               _label_manager->getLabelString(_result.label, _result.label_idx);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               throw e;
+       }
+
+       return _result;
+}
+
+} // machine_learning
+} // mediavision
diff --git a/mv_machine_learning/face_recognition/src/FaceRecognitionAdapter.cpp b/mv_machine_learning/face_recognition/src/FaceRecognitionAdapter.cpp
new file mode 100644 (file)
index 0000000..3e0ae4d
--- /dev/null
@@ -0,0 +1,179 @@
+/**
+ * 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 "MvMlException.h"
+#include "FaceRecognitionAdapter.h"
+#include "face_recognition_type.h"
+#include <app_common.h>
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning::exception;
+using namespace mediavision::machine_learning::face_recognition;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+FaceRecognitionAdapter::FaceRecognitionAdapter()
+{
+       _face_recognition = make_unique<FaceRecognition>();
+}
+
+FaceRecognitionAdapter::~FaceRecognitionAdapter()
+{}
+
+void FaceRecognitionAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                                 const string &model_name)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+void FaceRecognitionAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+void FaceRecognitionAdapter::configure()
+{
+       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(FACE_RECOGNITION_META_FILE_NAME));
+
+       string defaultPath;
+
+       int ret = _config->getStringAttribute(string(MV_FACE_RECOGNITION_DEFAULT_PATH), &defaultPath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get default path.");
+
+       auto trusted_path = app_get_shared_trusted_path();
+
+       if (trusted_path) {
+               defaultPath.insert(0, string(trusted_path));
+               free(trusted_path);
+       } else {
+               defaultPath.insert(0, TEST_RES_PATH "/res/face_recognition/");
+       }
+
+       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.");
+
+       std::vector<int> vecIntValues;
+       ret = _config->getIntegerAttribute(string(MV_FACE_RECOGNITION_INPUT_TENSOR_SHAPE), &vecIntValues);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get input tensor shape.");
+
+       FaceRecognitionConfig config = { TRAINING_TARGET_CPU, // device type for training.
+                                                                        TRAINING_BACKEND_NNTRAINER, // backend type for training.
+                                                                        MV_INFERENCE_TARGET_DEVICE_CPU, // device type for internal model interface.
+                                                                        MV_INFERENCE_BACKEND_NNTRAINER, // backend type for internal model inference.
+                                                                        string(defaultPath) + "model_and_weights.ini",
+                                                                        string(defaultPath) + "labels.dat",
+                                                                        string(defaultPath) + "feature_vector_file.dat",
+                                                                        decisionThreshold };
+
+       for (auto value : vecIntValues)
+               config.input_tensor_shape.push_back(static_cast<size_t>(value));
+
+       _face_recognition->setConfig(config);
+}
+
+unsigned int FaceRecognitionAdapter::getNumberOfEngines()
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+const string &FaceRecognitionAdapter::getEngineType(unsigned int engine_index)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+unsigned int FaceRecognitionAdapter::getNumberOfDevices(const string &engine_type)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+const string &FaceRecognitionAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+void FaceRecognitionAdapter::prepare()
+{
+       int ret = _face_recognition->initialize();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to initialize face recognition.");
+}
+
+void FaceRecognitionAdapter::perform(InputBaseType &input)
+{
+       auto &source = static_cast<FaceRecognitionInput &>(input);
+
+       if (source.mode == RequestMode::REGISTER) {
+               if (source.inputs.size() != source.labels.size())
+                       throw InvalidParameter("The number of inputs and labels are not matched.");
+
+               for (size_t idx = 0; idx < source.inputs.size(); ++idx) {
+                       int ret = _face_recognition->registerNewFace(source.inputs[idx], source.labels[idx]);
+                       if (ret != MEDIA_VISION_ERROR_NONE)
+                               throw InvalidOperation("Fail to register new face.");
+               }
+
+               return;
+       }
+
+       if (source.mode == RequestMode::INFERENCE) {
+               // _source.inputs.size should be 1.
+               int ret = _face_recognition->recognizeFace(source.inputs[0]);
+               if (ret == MEDIA_VISION_ERROR_NO_DATA)
+                       throw NoData("Label not found.");
+
+               if (ret != MEDIA_VISION_ERROR_NONE)
+                       throw InvalidOperation("Fail to request a recognition.");
+
+               return;
+       }
+
+       if (source.mode == RequestMode::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;
+       }
+}
+
+void FaceRecognitionAdapter::performAsync(InputBaseType &input)
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+OutputBaseType &FaceRecognitionAdapter::getOutput()
+{
+       return _face_recognition->result();
+}
+
+OutputBaseType &FaceRecognitionAdapter::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/FaceRecognitionDSM.cpp b/mv_machine_learning/face_recognition/src/FaceRecognitionDSM.cpp
new file mode 100644 (file)
index 0000000..91170a6
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+ * 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 <dlog.h>
+#include <mv_private.h>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "FaceRecognitionDSM.h"
+
+#define MAX_FEATURE_VECTOR_CNT 5
+#define MAX_FEATURE_SIZE 1024
+#define MAX_NUMBER_OF_LABELS 20
+#define MAX_NUMBER_OF_DATA_SETS (MAX_FEATURE_VECTOR_CNT * MAX_NUMBER_OF_LABELS)
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+void FaceRecognitionDSM::printHeader(FeaVecHeader &fvh)
+{
+       LOGD("signature = %u", fvh.signature);
+       LOGD("feature vector size = %zu", fvh.feature_size);
+       LOGD("label count = %zu", fvh.label_cnt);
+       LOGD("data set count = %u", fvh.data_set_cnt);
+}
+
+bool FaceRecognitionDSM::isHeaderValid(const FeaVecHeader &fvh)
+{
+       return !(FeatureVectorManager::feature_vector_signature != fvh.signature || MAX_FEATURE_SIZE < fvh.feature_size ||
+                        MAX_NUMBER_OF_LABELS < fvh.label_cnt || MAX_NUMBER_OF_DATA_SETS < fvh.data_set_cnt);
+}
+
+FaceRecognitionDSM::FaceRecognitionDSM() : DataSetManager()
+{}
+
+bool FaceRecognitionDSM::isFeatureVectorAllowed(unsigned int label_idx)
+{
+       return (_fv_cnt_per_label[label_idx] < MAX_FEATURE_VECTOR_CNT);
+}
+
+void FaceRecognitionDSM::addDataSet(std::vector<float> &feature_vec, unsigned int label_idx, unsigned int label_cnt)
+{
+       _data.push_back(feature_vec);
+       _label_index.push_back(label_idx);
+       _fv_cnt_per_label[label_idx]++;
+
+       vector<float> oneHotEncoding;
+
+       for (size_t num = 0; num < label_cnt; ++num)
+               oneHotEncoding.push_back(label_idx == num ? 1.0f : 0.0f);
+
+       _labels.push_back(oneHotEncoding);
+       _feature_vector_size = feature_vec.size();
+       _label_count = label_cnt;
+}
+
+void FaceRecognitionDSM::loadDataSet(const string &file_name, unsigned int new_label_cnt)
+{
+       std::ifstream inFile(file_name);
+
+       if (!inFile.is_open())
+               throw InvalidOperation("fail to open a file.");
+
+       FeaVecHeader fvh;
+
+       inFile.read((char *) &fvh, sizeof(FeaVecHeader));
+       if (inFile.gcount() != sizeof(FeaVecHeader))
+               throw InvalidOperation("Invalid feature vector file.");
+
+       printHeader(fvh);
+
+       if (!isHeaderValid(fvh))
+               throw InvalidOperation("Wrong feature vector header.");
+
+       /*
+       * stride line format is as follows
+       * ********************************
+       * ____________________________
+       * |feature vector|label index|
+       * ----------------------------
+       */
+       size_t line_size_in_bytes = fvh.feature_size * sizeof(float) + sizeof(unsigned int);
+
+       _feature_vector_size = fvh.feature_size;
+       _label_count = fvh.label_cnt;
+
+       vector<float> line_data(fvh.feature_size + 1);
+
+       for (size_t idx = 0; idx < fvh.data_set_cnt; ++idx) {
+               inFile.read(reinterpret_cast<char *>(line_data.data()), static_cast<streamsize>(line_size_in_bytes));
+
+               vector<float> data;
+
+               copy_n(line_data.begin(), _feature_vector_size, back_inserter(data));
+               _data.push_back(data);
+
+               unsigned int label_idx;
+
+               memcpy(&label_idx, reinterpret_cast<void *>(line_data.data() + _feature_vector_size), sizeof(unsigned int));
+
+               vector<float> label;
+
+               // max label count may be changed so update one hot encoding table.
+               for (size_t num = 0; num < new_label_cnt; ++num)
+                       label.push_back(label_idx == num ? 1.0f : 0.0f);
+
+               _labels.push_back(label);
+               _label_index.push_back(label_idx);
+
+               _fv_cnt_per_label[label_idx]++;
+       }
+}
diff --git a/mv_machine_learning/face_recognition/src/FaceRecognitionFVM.cpp b/mv_machine_learning/face_recognition/src/FaceRecognitionFVM.cpp
new file mode 100644 (file)
index 0000000..e93326f
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * 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 <fstream>
+#include <unistd.h>
+
+#include "MvMlException.h"
+#include "FaceRecognitionFVM.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+FaceRecognitionFVM::FaceRecognitionFVM(const string feature_vector_file) : FeatureVectorManager(feature_vector_file)
+{}
+
+void FaceRecognitionFVM::updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt)
+{
+       fstream headerFile {};
+
+       // When trying to write header data for the first time, the feature vector file doesn't exist,
+       // so create a new file with ios::out flag. Otherwise, open the feature vector file with ios::in | ios::out flags
+       // to update existing header data in the feature vector file.
+       if (access(_feature_vector_file.c_str(), F_OK))
+               headerFile.open(_feature_vector_file.c_str(), ios::out | ios::binary);
+       else
+               headerFile.open(_feature_vector_file.c_str(), ios::in | ios::out | ios::binary);
+
+       if (!headerFile.is_open())
+               throw InvalidOperation("fail to open a file");
+
+       FeaVecHeader header { FeatureVectorManager::feature_vector_signature, feature_size, label_cnt, data_set_cnt };
+
+       headerFile.write((const char *) &header, sizeof(FeaVecHeader));
+}
+
+void FaceRecognitionFVM::storeData(vector<vector<float> > &features_vec, vector<unsigned int> &label_index)
+{
+       fstream writeFile { _feature_vector_file, ios::binary | ios::app };
+
+       if (!writeFile.is_open())
+               throw InvalidOperation("fail to open a file.");
+
+       for (size_t idx = 0; idx < features_vec.size(); ++idx) {
+               writeFile.write(reinterpret_cast<char *>(features_vec[idx].data()),
+                                               static_cast<streamsize>(features_vec[idx].size() * sizeof(float)));
+               writeFile.write(reinterpret_cast<char *>(&label_index[idx]), static_cast<streamsize>(sizeof(unsigned int)));
+       }
+}
+
+void FaceRecognitionFVM::remove()
+{
+       // Remove existing file forcely.
+       int ret = ::remove(_feature_vector_file.c_str());
+       if (ret)
+               throw InvalidOperation("Fail to remove feature vector file.");
+}
diff --git a/mv_machine_learning/face_recognition/src/Facenet.cpp b/mv_machine_learning/face_recognition/src/Facenet.cpp
new file mode 100644 (file)
index 0000000..752a472
--- /dev/null
@@ -0,0 +1,214 @@
+/**
+ * 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 <string.h>
+#include <map>
+#include <memory>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "Facenet.h"
+#include "face_recognition_type.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+Facenet::Facenet() : _backendType(), _targetDeviceType()
+{
+       _inference = make_unique<Inference>();
+       _parser = make_unique<FacenetParser>();
+}
+
+static bool isJsonFile(const string &fileName)
+{
+       return (!fileName.substr(fileName.find_last_of(".") + 1).compare("json"));
+}
+
+void Facenet::parseMetaFile()
+{
+       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(FACE_RECOGNITION_META_FILE_NAME));
+
+       int ret = _config->getIntegerAttribute(string(MV_FACENET_BACKEND_TYPE), &_backendType);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get backend engine type.");
+
+       ret = _config->getIntegerAttribute(string(MV_FACENET_TARGET_DEVICE_TYPE), &_targetDeviceType);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get target device type.");
+
+       string modelDefaultPath;
+
+       ret = _config->getStringAttribute(MV_FACENET_MODEL_DEFAULT_PATH, &modelDefaultPath);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model default path.");
+
+       ret = _config->getStringAttribute(MV_FACENET_MODEL_FILE_NAME, &_modelFileName);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model file name.");
+
+       _modelFileName = modelDefaultPath + _modelFileName;
+
+       ret = _config->getStringAttribute(MV_FACENET_MODEL_META_FILE_NAME, &_modelMetaFileName);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get model meta file name.");
+
+       _modelMetaFileName = modelDefaultPath + _modelMetaFileName;
+
+       ret = _config->getStringAttribute(MV_FACENET_OUTPUT_TENSOR_NAME, &_facenetOutputTensorName);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to get facenet output tensor name.");
+
+       if (_modelMetaFileName.empty())
+               throw InvalidOperation("Model meta file doesn't exist.");
+
+       if (!isJsonFile(_modelMetaFileName))
+               throw InvalidOperation("Model meta file should be json.");
+
+       _parser->load(_modelMetaFileName);
+}
+
+void Facenet::configure()
+{
+       int ret = _inference->bind(_backendType, _targetDeviceType);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+void Facenet::prepare()
+{
+       int ret = _inference->configureInputMetaInfo(_parser->getInputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure input tensor info from meta file.");
+
+       ret = _inference->configureOutputMetaInfo(_parser->getOutputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+       _inference->configureModelFiles("", _modelFileName, "");
+
+       // Request to load model files to a backend engine.
+       ret = _inference->load();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to load model files.");
+}
+
+shared_ptr<MetaInfo> Facenet::getInputMetaInfo()
+{
+       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
+       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
+
+       // TODO. consider using multiple tensors later.
+       if (tensor_info_map.size() != 1)
+               throw InvalidOperation("Input tensor count not invalid.");
+
+       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];
+}
+
+template<typename T>
+void Facenet::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
+{
+       LOGI("ENTER");
+
+       PreprocessConfig config = { false,
+                                                               metaInfo->colorSpace,
+                                                               metaInfo->dataType,
+                                                               metaInfo->getChannel(),
+                                                               metaInfo->getWidth(),
+                                                               metaInfo->getHeight() };
+
+       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
+       if (normalization) {
+               config.normalize = normalization->use;
+               config.mean = normalization->mean;
+               config.std = normalization->std;
+       }
+
+       auto quantization =
+                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
+       if (quantization) {
+               config.quantize = quantization->use;
+               config.scale = quantization->scale;
+               config.zeropoint = quantization->zeropoint;
+       }
+
+       _preprocess.setConfig(config);
+       _preprocess.run<T>(mv_src, inputVector);
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void Facenet::inference(vector<vector<T> > &inputVectors)
+{
+       LOGI("ENTER");
+
+       int ret = _inference->run<T>(inputVectors);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to run inference");
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void Facenet::perform(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo)
+{
+       vector<T> inputVector;
+
+       preprocess<T>(mv_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+
+       inference<T>(inputVectors);
+}
+
+FacenetOutput &Facenet::result()
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+
+       // Make sure to clear _result.outputs vectors because if not clear then other output_vector will be pushed to _result.outputs
+       // and it results in sending wrong output vector to face recognition framework.
+       _result.outputs.clear();
+
+       _outputTensorBuffer = tensor_buffer_obj.getTensorBuffer(_facenetOutputTensorName);
+       if (!_outputTensorBuffer)
+               throw InvalidOperation("No output tensor.");
+
+       float *buffer = reinterpret_cast<float *>(_outputTensorBuffer->buffer);
+
+       _result.outputs.push_back(vector<float>(buffer, buffer + _outputTensorBuffer->size / sizeof(float)));
+
+       return _result;
+}
+
+template void Facenet::preprocess<float>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo,
+                                                                                vector<float> &inputVector);
+template void Facenet::inference<float>(vector<vector<float> > &inputVectors);
+template void Facenet::perform<float>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo);
+
+template void Facenet::preprocess<unsigned char>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo,
+                                                                                                vector<unsigned char> &inputVector);
+template void Facenet::inference<unsigned char>(vector<vector<unsigned char> > &inputVectors);
+template void Facenet::perform<unsigned char>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo);
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/FacenetAdapter.cpp b/mv_machine_learning/face_recognition/src/FacenetAdapter.cpp
new file mode 100644 (file)
index 0000000..842b665
--- /dev/null
@@ -0,0 +1,103 @@
+/**
+ * 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 "MvMlException.h"
+#include "FacenetAdapter.h"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+FacenetAdapter::FacenetAdapter()
+{
+       _facenet = make_unique<Facenet>();
+}
+
+FacenetAdapter::~FacenetAdapter()
+{}
+
+void FacenetAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                 const string &model_name)
+{}
+
+void FacenetAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{}
+
+void FacenetAdapter::configure()
+{
+       _facenet->parseMetaFile();
+       _facenet->configure();
+}
+
+unsigned int FacenetAdapter::getNumberOfEngines()
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+const string &FacenetAdapter::getEngineType(unsigned int engine_index)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+unsigned int FacenetAdapter::getNumberOfDevices(const string &engine_type)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+const string &FacenetAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       throw InvalidOperation("Not yet implemented");
+}
+
+void FacenetAdapter::prepare()
+{
+       _facenet->prepare();
+}
+
+void FacenetAdapter::perform(InputBaseType &input)
+{
+       auto &source = static_cast<FacenetInput &>(input);
+       shared_ptr<MetaInfo> metaInfo = _facenet->getInputMetaInfo();
+       if (metaInfo->dataType == MV_INFERENCE_DATA_UINT8)
+               _facenet->perform<unsigned char>(source.inference_src, metaInfo);
+       else if (metaInfo->dataType == MV_INFERENCE_DATA_FLOAT32)
+               _facenet->perform<float>(source.inference_src, metaInfo);
+       else
+               throw InvalidOperation("Invalid model data type.");
+}
+
+void FacenetAdapter::performAsync(InputBaseType &input)
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+OutputBaseType &FacenetAdapter::getOutput()
+{
+       return _facenet->result();
+}
+
+OutputBaseType &FacenetAdapter::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/FacenetParser.cpp b/mv_machine_learning/face_recognition/src/FacenetParser.cpp
new file mode 100644 (file)
index 0000000..6789e4d
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * 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 "MvMlException.h"
+#include "FacenetParser.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+FacenetParser::FacenetParser(int task_type)
+{
+       LOGI("ENTER");
+       LOGI("LEAVE");
+}
+
+FacenetParser::~FacenetParser()
+{}
+
+void FacenetParser::parsePostprocess(shared_ptr<MetaInfo> meta_info, JsonObject *in_obj)
+{
+       LOGI("ENTER");
+
+       LOGI("tensor name : %s", meta_info->name.c_str());
+
+       if (json_object_has_member(in_obj, "box"))
+               _postprocessParser.parseBox(meta_info, in_obj);
+
+       LOGI("LEAVE");
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/face_recognition.cpp b/mv_machine_learning/face_recognition/src/face_recognition.cpp
deleted file mode 100644 (file)
index 27a89d5..0000000
+++ /dev/null
@@ -1,428 +0,0 @@
-/**
- * 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 <string.h>
-#include <fstream>
-#include <istream>
-#include <tuple>
-#include <map>
-#include <algorithm>
-
-#include <sys/stat.h>
-
-#include <dlog.h>
-#include <mv_common.h>
-#include <mv_private.h>
-
-#include "machine_learning_exception.h"
-#include "TensorBuffer.h"
-#include "face_recognition.h"
-#include "face_recognition_fvm.h"
-#include "face_recognition_dsm.h"
-#include "file_util.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace TrainingEngineInterface::Common;
-using namespace mediavision::machine_learning::face_recognition;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-void FaceRecognition::checkFeatureVectorFile(string fv_file_name, string new_fv_file_name)
-{
-       // Change new feature vector file to existing one in case that current process is terminated just after removing existing feature vector file but
-       // new feature vector file isn't changed to existing one yet.
-       if (FaceRecogUtil::isFileExist(new_fv_file_name) && !FaceRecogUtil::isFileExist(fv_file_name)) {
-               int ret = ::rename(new_fv_file_name.c_str(), fv_file_name.c_str());
-               if (ret)
-                       throw InvalidOperation("Fail to rename new feature vector file to original one.");
-
-               return;
-       }
-
-       // Make sure to remove a temp file in case that current process is terminated just after generating new feature vector file
-       // which is not correct file but existing one isn't removed. In this case, existing file is used again.
-       if (FaceRecogUtil::isFileExist(new_fv_file_name)) {
-               int ret = ::remove(new_fv_file_name.c_str());
-               if (ret)
-                       throw InvalidOperation("Fail to remove new feature vector file.");
-       }
-}
-
-void FaceRecognition::storeDataSet(unique_ptr<DataSetManager> &data_set, unsigned int label_cnt)
-{
-       try {
-               unique_ptr<FeatureVectorManager> fvm = make_unique<FaceRecognitionFVM>(_config.feature_vector_file_path);
-               unique_ptr<FeatureVectorManager> fvm_new =
-                               make_unique<FaceRecognitionFVM>(_config.feature_vector_file_path + ".new");
-
-               // Make sure feature vector file.
-               checkFeatureVectorFile(fvm->getFileName(), fvm_new->getFileName());
-
-               // Write feature vector header.
-               fvm_new->updateHeader(data_set->getFeaVecSize(), label_cnt, data_set->getData().size());
-
-               // Write feature vector and it's label index.
-               fvm_new->storeData(data_set->getData(), data_set->getLabelIdx());
-
-               int ret = 0;
-
-               // Change new data file to existing one.
-               if (FaceRecogUtil::isFileExist(fvm->getFileName())) {
-                       ret = ::remove(fvm->getFileName().c_str());
-                       if (ret)
-                               throw InvalidOperation("Fail to remove feature vector file.");
-               }
-
-               ret = ::rename(fvm_new->getFileName().c_str(), fvm->getFileName().c_str());
-               if (ret)
-                       throw InvalidOperation("Fail to rename new feature vector file to original one.");
-       } catch (const BaseException &e) {
-               LOGE("%s", e.what());
-               throw e;
-       }
-}
-
-void FaceRecognition::setConfig(FaceRecognitionConfig &config)
-{
-       _config = config;
-}
-
-int FaceRecognition::initialize()
-{
-       _training_model = make_unique<SimpleShot>(_config.training_engine_backend_type, _config.training_target_device_type,
-                                                                                         _config.input_tensor_shape, _config.internal_model_file_path);
-
-       _internal = make_unique<Inference>();
-       _label_manager = make_unique<LabelManager>(_config.label_file_path, _config.decision_threshold);
-
-       int ret = _internal->bind(_config.inference_engine_backend_type, _config.inference_target_device_type);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               return ret;
-
-       _status = WorkingStatus::INITIALIZED;
-
-       return MEDIA_VISION_ERROR_NONE;
-}
-
-int FaceRecognition::registerNewFace(std::vector<float> &input_vec, string label_name)
-{
-       if (_status < WorkingStatus::INITIALIZED) {
-               LOGE("Initialization not ready yet.");
-               return MEDIA_VISION_ERROR_INVALID_OPERATION;
-       }
-
-       // TODO. consider data augmentation.
-       try {
-               // Store a new label name to label file if the given label doesn't exist.
-               if (!_label_manager->isExist(label_name))
-                       _label_manager->addLabelToFile(label_name);
-
-               // Import label data from a label file.
-               _label_manager->importLabel();
-
-               // Get label index and count.
-               unsigned int label_idx = _label_manager->getLabelIndex(label_name);
-               unsigned int label_cnt = _label_manager->getMaxLabel();
-
-               unique_ptr<DataSetManager> data_set = make_unique<FaceRecognitionDSM>();
-
-               data_set->clear();
-
-               // Load existing feature vectors if the feature vector file exists.
-               if (FaceRecogUtil::isFileExist(_config.feature_vector_file_path) == true) {
-                       LOGI("feature vector file already exists so it loads the file first.");
-                       data_set->loadDataSet(_config.feature_vector_file_path, label_cnt);
-               }
-
-               // Add new feature vector only in case that feature vector count of given label_idx is less then 5.
-               // It means that only 5 set of feature vector per a label is valid.
-               // TODO. According to feature vector priority, new feature vector should be added.
-               if (data_set->isFeatureVectorAllowed(label_idx))
-                       data_set->addDataSet(input_vec, label_idx, label_cnt);
-
-               // Store dataset to feature vector file.
-               storeDataSet(data_set, label_cnt);
-               data_set->clear();
-
-               trainModel();
-               _result.is_valid = false;
-       } catch (const BaseException &e) {
-               LOGE("%s", e.what());
-               return e.getError();
-       }
-
-       return MEDIA_VISION_ERROR_NONE;
-}
-
-void FaceRecognition::checkResult()
-{
-       // Check decision threshold.
-       if (_result.raw_data[_result.label_idx] < _label_manager->getDecisionThreshold())
-               throw NoData("Not meet decision threshold.");
-
-       float weighted = _result.raw_data[_result.label_idx] * _label_manager->getDecisionWeight();
-
-       // Check decision weight threshold.
-       for (size_t i = 0; i < _result.raw_data.size(); i++) {
-               if (i != _result.label_idx && _result.raw_data[i] > weighted)
-                       throw NoData("Not meet decision weight threshold");
-       }
-}
-
-void FaceRecognition::trainModel()
-{
-       // Load existing feature vectors if the feature vector file exists.
-       if (!FaceRecogUtil::isFileExist(_config.feature_vector_file_path))
-               throw InvalidOperation("Feature vector file does not exist.");
-
-       unsigned int label_cnt = _label_manager->getMaxLabel();
-       unique_ptr<DataSetManager> data_set = make_unique<FaceRecognitionDSM>();
-
-       data_set->loadDataSet(_config.feature_vector_file_path, label_cnt);
-
-       // Configure and train the model
-       // TODO: No need to configure the model again if number of labels don't change
-       _training_model->configureModel(label_cnt);
-       _training_model->applyDataSet(data_set);
-       _training_model->compile();
-       _training_model->train();
-
-       _training_model->clearDataSet();
-
-       _status = WorkingStatus::TRAINED;
-}
-
-int FaceRecognition::recognizeFace(std::vector<float> &input_vec)
-{
-       if (_status == WorkingStatus::NONE) {
-               LOGE("Initialization not ready yet.");
-               return MEDIA_VISION_ERROR_INVALID_OPERATION;
-       }
-
-       // Face Recognition has following steps
-       // ------------------------------------
-       // 1. Import label data to in-memory from a file.
-       // 2. Load internal model.
-       // 3. Do an inference with the internal model to get a label.
-       // 4. Get the label best suitable to the output tensor and return the label.
-
-       try {
-               // Import label data from a label file.
-               _label_manager->importLabel();
-
-               if (_label_manager->isEmpty()) {
-                       _result.is_valid = false;
-                       _status = WorkingStatus::INFERENCED;
-
-                       return MEDIA_VISION_ERROR_NO_DATA;
-               }
-
-               if (!FaceRecogUtil::isFileExist(_config.internal_model_file_path)) {
-                       LOGE("Internal model file(%s) doesn't exist.", _config.internal_model_file_path.c_str());
-                       return MEDIA_VISION_ERROR_NO_DATA;
-               }
-
-               TrainingEngineBackendInfo engine_info = _training_model->getTrainingEngineInfo();
-               vector<string> &input_layers = engine_info.input_layer_names;
-               vector<inference_engine_tensor_info> &input_tensor_info = engine_info.input_tensor_info;
-               vector<string> &output_layers = engine_info.output_layer_names;
-               vector<inference_engine_tensor_info> &output_tensor_info = engine_info.output_tensor_info;
-
-               if (_status != WorkingStatus::INFERENCED) {
-                       // Tensor order is NCHW.
-                       size_t width = input_tensor_info[0].shape[0];
-                       size_t height = input_tensor_info[0].shape[1];
-                       size_t ch = input_tensor_info[0].shape[2];
-
-                       _internal->configureInputInfo(width, height, 1, ch, 1.0f, 0.0f, MV_INFERENCE_DATA_FLOAT32, input_layers);
-
-                       // Output tensor size should be a number of labels so update it.
-                       output_tensor_info[0].shape[0] = _label_manager->getMaxLabel();
-
-                       _internal->configureOutputInfo(output_layers, output_tensor_info);
-                       _internal->configureModelFiles("", _config.internal_model_file_path, "");
-
-                       // Load the trained internal model.
-                       if (_internal->load() != INFERENCE_ENGINE_ERROR_NONE) {
-                               LOGE("Fail to Load.");
-                               return MEDIA_VISION_ERROR_INVALID_OPERATION;
-                       }
-               }
-
-               std::vector<std::vector<float> > input_tensors = { input_vec };
-
-               // Do inference to the internal model.
-               if (_internal->run<float>(input_tensors) != INFERENCE_ENGINE_ERROR_NONE) {
-                       LOGE("fail to inference internal model.");
-                       return MEDIA_VISION_ERROR_INVALID_OPERATION;
-               }
-
-               // output layer size should be 1.
-               TensorBuffer tensorBuffer = _internal->getOutputTensorBuffer();
-               inference_engine_tensor_buffer *internal_output_buffer = tensorBuffer.getTensorBuffer(output_layers[0]);
-               if (!internal_output_buffer) {
-                       LOGE("fail to get internal output tensor buffer.");
-                       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
-               }
-
-               auto raw_buffer = static_cast<float *>(internal_output_buffer->buffer);
-
-               // Update the result because user can want to get the result regardless of the decision threshold
-               // to check how many people are registered to the label file.
-               //
-               // TODO. as for this, we may need to introduce a new API to provide the number of people later.
-               _result.raw_data.clear();
-               copy(raw_buffer, raw_buffer + internal_output_buffer->size / sizeof(float), back_inserter(_result.raw_data));
-
-               string result_str;
-
-               for (const auto &r : _result.raw_data)
-                       result_str += to_string(r) + " ";
-
-               LOGD("raw data = %s", result_str.c_str());
-
-               _result.labels.clear();
-               _result.labels = _label_manager->getLabels();
-
-               unsigned int answer_index =
-                               max_element(_result.raw_data.begin(), _result.raw_data.end()) - _result.raw_data.begin();
-               _result.label_idx = answer_index;
-               _result.is_valid = true;
-
-               _status = WorkingStatus::INFERENCED;
-
-               checkResult();
-       } catch (const BaseException &e) {
-               LOGE("%s", e.what());
-               return e.getError();
-       }
-
-       return MEDIA_VISION_ERROR_NONE;
-}
-
-int FaceRecognition::deleteLabel(string label_name)
-{
-       if (_status < WorkingStatus::INITIALIZED) {
-               LOGE("Initialization not ready yet.");
-               return MEDIA_VISION_ERROR_INVALID_OPERATION;
-       }
-
-       // Deleting a given label is to remove existing registered person from label and feature vector files.
-
-       try {
-               if (!_label_manager->isExist(label_name)) {
-                       LOGE("%s doesn't exist in label file.", label_name.c_str());
-                       return MEDIA_VISION_ERROR_INVALID_OPERATION;
-               }
-
-               // Import label data from a label file.
-               _label_manager->importLabel();
-
-               unsigned int target_label_idx = _label_manager->getLabelIndex(label_name);
-               auto label_cnt_ori = _label_manager->getMaxLabel();
-
-               LOGD("Current label count is %zu", label_cnt_ori);
-               LOGD("The index of label name(%s) is %d", label_name.c_str(), target_label_idx);
-
-               // Get label count after removing a given label from the label file.
-               _label_manager->removeLabel(label_name);
-
-               auto label_cnt = _label_manager->getMaxLabel();
-
-               LOGD("Current label count is %zu after removing the label(%s)", label_cnt, label_name.c_str());
-
-               unique_ptr<DataSetManager> data_set = make_unique<FaceRecognitionDSM>();
-               unique_ptr<DataSetManager> data_set_new = make_unique<FaceRecognitionDSM>();
-
-               // feature vectors corresponding to given label aren't removed yet from feature vector file.
-               // So label_cnt_ori is needed.
-               LOGD("Load the original feature vector data from the feature vector file.");
-               data_set->loadDataSet(_config.feature_vector_file_path, label_cnt_ori);
-
-               vector<vector<float> > feature_vectors_old = data_set->getData();
-               vector<unsigned int> label_idx_vectors_old = data_set->getLabelIdx();
-
-               // Write existing feature vectors and its one-hot encoding table with updated label.
-               for (unsigned int idx = 0; idx < feature_vectors_old.size(); ++idx) {
-                       // Except the data sets with a given target_label_idx.
-                       if (label_idx_vectors_old[idx] == target_label_idx)
-                               continue;
-
-                       // One-hot encoding table should be updated.
-                       // Assume that below label file exists for example,
-                       //     In label file
-                       //     -------------
-                       //     offset 0 : label 1
-                       //     offset 1 : label 2
-                       //     offset 2 : label 3
-                       //
-                       //     One hot encoding table should be updated like below after removing label 1,
-                       //     In label file
-                       //     -------------
-                       //     offset 0 : label 2
-                       //     offset 1 : label 3
-                       //
-                       // So if the index of removed label less than remaining index then decrease each index.
-                       if (label_idx_vectors_old[idx] > target_label_idx)
-                               label_idx_vectors_old[idx]--;
-
-                       data_set_new->addDataSet(feature_vectors_old[idx], label_idx_vectors_old[idx], label_cnt);
-               }
-
-               // Store only in case that feature vectors exist.
-               if (data_set_new->getData().size() > 0) {
-                       storeDataSet(data_set_new, label_cnt);
-                       trainModel();
-               } else {
-                       _training_model->removeModel();
-                       _label_manager->removeFile();
-
-                       LOGD("No training data so removed all relevant files.");
-               }
-
-               _result.is_valid = false;
-       } catch (const BaseException &e) {
-               LOGE("%s", e.what());
-               return e.getError();
-       }
-
-       return MEDIA_VISION_ERROR_NONE;
-}
-
-FaceRecognitionResult &FaceRecognition::result()
-{
-       if (!_result.is_valid)
-               throw NoData("Inference result not ready yet.");
-
-       if (!_label_manager)
-               throw NoData("Label file doesn't exist.");
-
-       try {
-               _label_manager->getLabelString(_result.label, _result.label_idx);
-       } catch (const BaseException &e) {
-               LOGE("%s", e.what());
-               throw e;
-       }
-
-       return _result;
-}
-
-} // machine_learning
-} // mediavision
diff --git a/mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp b/mv_machine_learning/face_recognition/src/face_recognition_adapter.cpp
deleted file mode 100644 (file)
index e3821e4..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/**
- * 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"
-#include "face_recognition_type.h"
-#include <app_common.h>
-
-using namespace std;
-using namespace MediaVision::Common;
-using namespace mediavision::machine_learning::exception;
-using namespace mediavision::machine_learning::face_recognition;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-FaceRecognitionAdapter::FaceRecognitionAdapter()
-{
-       _face_recognition = make_unique<FaceRecognition>();
-}
-
-FaceRecognitionAdapter::~FaceRecognitionAdapter()
-{}
-
-void FaceRecognitionAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                                 const string &model_name)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-void FaceRecognitionAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-void FaceRecognitionAdapter::configure()
-{
-       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(FACE_RECOGNITION_META_FILE_NAME));
-
-       string defaultPath;
-
-       int ret = _config->getStringAttribute(string(MV_FACE_RECOGNITION_DEFAULT_PATH), &defaultPath);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get default path.");
-
-       auto trusted_path = app_get_shared_trusted_path();
-
-       if (trusted_path) {
-               defaultPath.insert(0, string(trusted_path));
-               free(trusted_path);
-       } else {
-               defaultPath.insert(0, TEST_RES_PATH "/res/face_recognition/");
-       }
-
-       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.");
-
-       std::vector<int> vecIntValues;
-       ret = _config->getIntegerAttribute(string(MV_FACE_RECOGNITION_INPUT_TENSOR_SHAPE), &vecIntValues);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get input tensor shape.");
-
-       FaceRecognitionConfig config = { TRAINING_TARGET_CPU, // device type for training.
-                                                                        TRAINING_BACKEND_NNTRAINER, // backend type for training.
-                                                                        MV_INFERENCE_TARGET_DEVICE_CPU, // device type for internal model interface.
-                                                                        MV_INFERENCE_BACKEND_NNTRAINER, // backend type for internal model inference.
-                                                                        string(defaultPath) + "model_and_weights.ini",
-                                                                        string(defaultPath) + "labels.dat",
-                                                                        string(defaultPath) + "feature_vector_file.dat",
-                                                                        decisionThreshold };
-
-       for (auto value : vecIntValues)
-               config.input_tensor_shape.push_back(static_cast<size_t>(value));
-
-       _face_recognition->setConfig(config);
-}
-
-unsigned int FaceRecognitionAdapter::getNumberOfEngines()
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-const string &FaceRecognitionAdapter::getEngineType(unsigned int engine_index)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-unsigned int FaceRecognitionAdapter::getNumberOfDevices(const string &engine_type)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-const string &FaceRecognitionAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-void FaceRecognitionAdapter::prepare()
-{
-       int ret = _face_recognition->initialize();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to initialize face recognition.");
-}
-
-void FaceRecognitionAdapter::perform(InputBaseType &input)
-{
-       auto &source = static_cast<FaceRecognitionInput &>(input);
-
-       if (source.mode == RequestMode::REGISTER) {
-               if (source.inputs.size() != source.labels.size())
-                       throw InvalidParameter("The number of inputs and labels are not matched.");
-
-               for (size_t idx = 0; idx < source.inputs.size(); ++idx) {
-                       int ret = _face_recognition->registerNewFace(source.inputs[idx], source.labels[idx]);
-                       if (ret != MEDIA_VISION_ERROR_NONE)
-                               throw InvalidOperation("Fail to register new face.");
-               }
-
-               return;
-       }
-
-       if (source.mode == RequestMode::INFERENCE) {
-               // _source.inputs.size should be 1.
-               int ret = _face_recognition->recognizeFace(source.inputs[0]);
-               if (ret == MEDIA_VISION_ERROR_NO_DATA)
-                       throw NoData("Label not found.");
-
-               if (ret != MEDIA_VISION_ERROR_NONE)
-                       throw InvalidOperation("Fail to request a recognition.");
-
-               return;
-       }
-
-       if (source.mode == RequestMode::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;
-       }
-}
-
-void FaceRecognitionAdapter::performAsync(InputBaseType &input)
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-OutputBaseType &FaceRecognitionAdapter::getOutput()
-{
-       return _face_recognition->result();
-}
-
-OutputBaseType &FaceRecognitionAdapter::getOutputCache()
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/face_recognition_dsm.cpp b/mv_machine_learning/face_recognition/src/face_recognition_dsm.cpp
deleted file mode 100644 (file)
index 79de9d3..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * 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 <dlog.h>
-#include <mv_private.h>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "face_recognition_dsm.h"
-
-#define MAX_FEATURE_VECTOR_CNT 5
-#define MAX_FEATURE_SIZE 1024
-#define MAX_NUMBER_OF_LABELS 20
-#define MAX_NUMBER_OF_DATA_SETS (MAX_FEATURE_VECTOR_CNT * MAX_NUMBER_OF_LABELS)
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-void FaceRecognitionDSM::printHeader(FeaVecHeader &fvh)
-{
-       LOGD("signature = %u", fvh.signature);
-       LOGD("feature vector size = %zu", fvh.feature_size);
-       LOGD("label count = %zu", fvh.label_cnt);
-       LOGD("data set count = %u", fvh.data_set_cnt);
-}
-
-bool FaceRecognitionDSM::isHeaderValid(const FeaVecHeader &fvh)
-{
-       return !(FeatureVectorManager::feature_vector_signature != fvh.signature || MAX_FEATURE_SIZE < fvh.feature_size ||
-                        MAX_NUMBER_OF_LABELS < fvh.label_cnt || MAX_NUMBER_OF_DATA_SETS < fvh.data_set_cnt);
-}
-
-FaceRecognitionDSM::FaceRecognitionDSM() : DataSetManager()
-{}
-
-bool FaceRecognitionDSM::isFeatureVectorAllowed(unsigned int label_idx)
-{
-       return (_fv_cnt_per_label[label_idx] < MAX_FEATURE_VECTOR_CNT);
-}
-
-void FaceRecognitionDSM::addDataSet(std::vector<float> &feature_vec, unsigned int label_idx, unsigned int label_cnt)
-{
-       _data.push_back(feature_vec);
-       _label_index.push_back(label_idx);
-       _fv_cnt_per_label[label_idx]++;
-
-       vector<float> oneHotEncoding;
-
-       for (size_t num = 0; num < label_cnt; ++num)
-               oneHotEncoding.push_back(label_idx == num ? 1.0f : 0.0f);
-
-       _labels.push_back(oneHotEncoding);
-       _feature_vector_size = feature_vec.size();
-       _label_count = label_cnt;
-}
-
-void FaceRecognitionDSM::loadDataSet(const string &file_name, unsigned int new_label_cnt)
-{
-       std::ifstream inFile(file_name);
-
-       if (!inFile.is_open())
-               throw InvalidOperation("fail to open a file.");
-
-       FeaVecHeader fvh;
-
-       inFile.read((char *) &fvh, sizeof(FeaVecHeader));
-       if (inFile.gcount() != sizeof(FeaVecHeader))
-               throw InvalidOperation("Invalid feature vector file.");
-
-       printHeader(fvh);
-
-       if (!isHeaderValid(fvh))
-               throw InvalidOperation("Wrong feature vector header.");
-
-       /*
-       * stride line format is as follows
-       * ********************************
-       * ____________________________
-       * |feature vector|label index|
-       * ----------------------------
-       */
-       size_t line_size_in_bytes = fvh.feature_size * sizeof(float) + sizeof(unsigned int);
-
-       _feature_vector_size = fvh.feature_size;
-       _label_count = fvh.label_cnt;
-
-       vector<float> line_data(fvh.feature_size + 1);
-
-       for (size_t idx = 0; idx < fvh.data_set_cnt; ++idx) {
-               inFile.read(reinterpret_cast<char *>(line_data.data()), static_cast<streamsize>(line_size_in_bytes));
-
-               vector<float> data;
-
-               copy_n(line_data.begin(), _feature_vector_size, back_inserter(data));
-               _data.push_back(data);
-
-               unsigned int label_idx;
-
-               memcpy(&label_idx, reinterpret_cast<void *>(line_data.data() + _feature_vector_size), sizeof(unsigned int));
-
-               vector<float> label;
-
-               // max label count may be changed so update one hot encoding table.
-               for (size_t num = 0; num < new_label_cnt; ++num)
-                       label.push_back(label_idx == num ? 1.0f : 0.0f);
-
-               _labels.push_back(label);
-               _label_index.push_back(label_idx);
-
-               _fv_cnt_per_label[label_idx]++;
-       }
-}
diff --git a/mv_machine_learning/face_recognition/src/face_recognition_fvm.cpp b/mv_machine_learning/face_recognition/src/face_recognition_fvm.cpp
deleted file mode 100644 (file)
index 87c7548..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * 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 <fstream>
-#include <unistd.h>
-
-#include "machine_learning_exception.h"
-#include "face_recognition_fvm.h"
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-FaceRecognitionFVM::FaceRecognitionFVM(const string feature_vector_file) : FeatureVectorManager(feature_vector_file)
-{}
-
-void FaceRecognitionFVM::updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt)
-{
-       fstream headerFile {};
-
-       // When trying to write header data for the first time, the feature vector file doesn't exist,
-       // so create a new file with ios::out flag. Otherwise, open the feature vector file with ios::in | ios::out flags
-       // to update existing header data in the feature vector file.
-       if (access(_feature_vector_file.c_str(), F_OK))
-               headerFile.open(_feature_vector_file.c_str(), ios::out | ios::binary);
-       else
-               headerFile.open(_feature_vector_file.c_str(), ios::in | ios::out | ios::binary);
-
-       if (!headerFile.is_open())
-               throw InvalidOperation("fail to open a file");
-
-       FeaVecHeader header { FeatureVectorManager::feature_vector_signature, feature_size, label_cnt, data_set_cnt };
-
-       headerFile.write((const char *) &header, sizeof(FeaVecHeader));
-}
-
-void FaceRecognitionFVM::storeData(vector<vector<float> > &features_vec, vector<unsigned int> &label_index)
-{
-       fstream writeFile { _feature_vector_file, ios::binary | ios::app };
-
-       if (!writeFile.is_open())
-               throw InvalidOperation("fail to open a file.");
-
-       for (size_t idx = 0; idx < features_vec.size(); ++idx) {
-               writeFile.write(reinterpret_cast<char *>(features_vec[idx].data()),
-                                               static_cast<streamsize>(features_vec[idx].size() * sizeof(float)));
-               writeFile.write(reinterpret_cast<char *>(&label_index[idx]), static_cast<streamsize>(sizeof(unsigned int)));
-       }
-}
-
-void FaceRecognitionFVM::remove()
-{
-       // Remove existing file forcely.
-       int ret = ::remove(_feature_vector_file.c_str());
-       if (ret)
-               throw InvalidOperation("Fail to remove feature vector file.");
-}
diff --git a/mv_machine_learning/face_recognition/src/facenet.cpp b/mv_machine_learning/face_recognition/src/facenet.cpp
deleted file mode 100644 (file)
index ed85b72..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- * 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 <string.h>
-#include <map>
-#include <memory>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "facenet.h"
-#include "face_recognition_type.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace MediaVision::Common;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-Facenet::Facenet() : _backendType(), _targetDeviceType()
-{
-       _inference = make_unique<Inference>();
-       _parser = make_unique<FacenetParser>();
-}
-
-static bool isJsonFile(const string &fileName)
-{
-       return (!fileName.substr(fileName.find_last_of(".") + 1).compare("json"));
-}
-
-void Facenet::parseMetaFile()
-{
-       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(FACE_RECOGNITION_META_FILE_NAME));
-
-       int ret = _config->getIntegerAttribute(string(MV_FACENET_BACKEND_TYPE), &_backendType);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get backend engine type.");
-
-       ret = _config->getIntegerAttribute(string(MV_FACENET_TARGET_DEVICE_TYPE), &_targetDeviceType);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get target device type.");
-
-       string modelDefaultPath;
-
-       ret = _config->getStringAttribute(MV_FACENET_MODEL_DEFAULT_PATH, &modelDefaultPath);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model default path.");
-
-       ret = _config->getStringAttribute(MV_FACENET_MODEL_FILE_NAME, &_modelFileName);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model file name.");
-
-       _modelFileName = modelDefaultPath + _modelFileName;
-
-       ret = _config->getStringAttribute(MV_FACENET_MODEL_META_FILE_NAME, &_modelMetaFileName);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get model meta file name.");
-
-       _modelMetaFileName = modelDefaultPath + _modelMetaFileName;
-
-       ret = _config->getStringAttribute(MV_FACENET_OUTPUT_TENSOR_NAME, &_facenetOutputTensorName);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to get facenet output tensor name.");
-
-       if (_modelMetaFileName.empty())
-               throw InvalidOperation("Model meta file doesn't exist.");
-
-       if (!isJsonFile(_modelMetaFileName))
-               throw InvalidOperation("Model meta file should be json.");
-
-       _parser->load(_modelMetaFileName);
-}
-
-void Facenet::configure()
-{
-       int ret = _inference->bind(_backendType, _targetDeviceType);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to bind a backend engine.");
-}
-
-void Facenet::prepare()
-{
-       int ret = _inference->configureInputMetaInfo(_parser->getInputMetaMap());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to configure input tensor info from meta file.");
-
-       ret = _inference->configureOutputMetaInfo(_parser->getOutputMetaMap());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to configure output tensor info from meta file.");
-
-       _inference->configureModelFiles("", _modelFileName, "");
-
-       // Request to load model files to a backend engine.
-       ret = _inference->load();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to load model files.");
-}
-
-shared_ptr<MetaInfo> Facenet::getInputMetaInfo()
-{
-       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
-       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
-
-       // TODO. consider using multiple tensors later.
-       if (tensor_info_map.size() != 1)
-               throw InvalidOperation("Input tensor count not invalid.");
-
-       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];
-}
-
-template<typename T>
-void Facenet::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
-{
-       LOGI("ENTER");
-
-       PreprocessConfig config = { false,
-                                                               metaInfo->colorSpace,
-                                                               metaInfo->dataType,
-                                                               metaInfo->getChannel(),
-                                                               metaInfo->getWidth(),
-                                                               metaInfo->getHeight() };
-
-       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
-       if (normalization) {
-               config.normalize = normalization->use;
-               config.mean = normalization->mean;
-               config.std = normalization->std;
-       }
-
-       auto quantization =
-                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
-       if (quantization) {
-               config.quantize = quantization->use;
-               config.scale = quantization->scale;
-               config.zeropoint = quantization->zeropoint;
-       }
-
-       _preprocess.setConfig(config);
-       _preprocess.run<T>(mv_src, inputVector);
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void Facenet::inference(vector<vector<T> > &inputVectors)
-{
-       LOGI("ENTER");
-
-       int ret = _inference->run<T>(inputVectors);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to run inference");
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void Facenet::perform(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo)
-{
-       vector<T> inputVector;
-
-       preprocess<T>(mv_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-
-       inference<T>(inputVectors);
-}
-
-FacenetOutput &Facenet::result()
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-
-       // Make sure to clear _result.outputs vectors because if not clear then other output_vector will be pushed to _result.outputs
-       // and it results in sending wrong output vector to face recognition framework.
-       _result.outputs.clear();
-
-       _outputTensorBuffer = tensor_buffer_obj.getTensorBuffer(_facenetOutputTensorName);
-       if (!_outputTensorBuffer)
-               throw InvalidOperation("No output tensor.");
-
-       float *buffer = reinterpret_cast<float *>(_outputTensorBuffer->buffer);
-
-       _result.outputs.push_back(vector<float>(buffer, buffer + _outputTensorBuffer->size / sizeof(float)));
-
-       return _result;
-}
-
-template void Facenet::preprocess<float>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo,
-                                                                                vector<float> &inputVector);
-template void Facenet::inference<float>(vector<vector<float> > &inputVectors);
-template void Facenet::perform<float>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo);
-
-template void Facenet::preprocess<unsigned char>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo,
-                                                                                                vector<unsigned char> &inputVector);
-template void Facenet::inference<unsigned char>(vector<vector<unsigned char> > &inputVectors);
-template void Facenet::perform<unsigned char>(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo);
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/facenet_adapter.cpp b/mv_machine_learning/face_recognition/src/facenet_adapter.cpp
deleted file mode 100644 (file)
index 21b4b0d..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * 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 "facenet_adapter.h"
-
-using namespace std;
-using namespace MediaVision::Common;
-using namespace mediavision::machine_learning;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-FacenetAdapter::FacenetAdapter()
-{
-       _facenet = make_unique<Facenet>();
-}
-
-FacenetAdapter::~FacenetAdapter()
-{}
-
-void FacenetAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                 const string &model_name)
-{}
-
-void FacenetAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{}
-
-void FacenetAdapter::configure()
-{
-       _facenet->parseMetaFile();
-       _facenet->configure();
-}
-
-unsigned int FacenetAdapter::getNumberOfEngines()
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-const string &FacenetAdapter::getEngineType(unsigned int engine_index)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-unsigned int FacenetAdapter::getNumberOfDevices(const string &engine_type)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-const string &FacenetAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       throw InvalidOperation("Not yet implemented");
-}
-
-void FacenetAdapter::prepare()
-{
-       _facenet->prepare();
-}
-
-void FacenetAdapter::perform(InputBaseType &input)
-{
-       auto &source = static_cast<FacenetInput &>(input);
-       shared_ptr<MetaInfo> metaInfo = _facenet->getInputMetaInfo();
-       if (metaInfo->dataType == MV_INFERENCE_DATA_UINT8)
-               _facenet->perform<unsigned char>(source.inference_src, metaInfo);
-       else if (metaInfo->dataType == MV_INFERENCE_DATA_FLOAT32)
-               _facenet->perform<float>(source.inference_src, metaInfo);
-       else
-               throw InvalidOperation("Invalid model data type.");
-}
-
-void FacenetAdapter::performAsync(InputBaseType &input)
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-OutputBaseType &FacenetAdapter::getOutput()
-{
-       return _facenet->result();
-}
-
-OutputBaseType &FacenetAdapter::getOutputCache()
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/face_recognition/src/facenet_parser.cpp b/mv_machine_learning/face_recognition/src/facenet_parser.cpp
deleted file mode 100644 (file)
index 2ce236f..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * 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 "facenet_parser.h"
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-FacenetParser::FacenetParser(int task_type)
-{
-       LOGI("ENTER");
-       LOGI("LEAVE");
-}
-
-FacenetParser::~FacenetParser()
-{}
-
-void FacenetParser::parsePostprocess(shared_ptr<MetaInfo> meta_info, JsonObject *in_obj)
-{
-       LOGI("ENTER");
-
-       LOGI("tensor name : %s", meta_info->name.c_str());
-
-       if (json_object_has_member(in_obj, "box"))
-               _postprocessParser.parseBox(meta_info, in_obj);
-
-       LOGI("LEAVE");
-}
-
-}
-}
\ No newline at end of file
index ee257ddb218443a61c4e4f10ed198670f8f6204a..b9f2e4ea95feedefd9dfcf9cd0f0647d2e8c7564 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "context.h"
-#include "machine_learning_exception.h"
-#include "face_recognition_adapter.h"
-#include "facenet_adapter.h"
-#include "MachineLearningNative.h"
+#include "Context.h"
+#include "MvMlException.h"
+#include "FaceRecognitionAdapter.h"
+#include "FacenetAdapter.h"
+#include "native_capi.h"
 #include "mv_face_recognition.h"
 #include "mv_face_recognition_internal.h"
 
index eb6c0a0efd28e393d5f3ae12abdfeb242e578aef..d508ac5c33c2c695bb3e2250170c32bcb3c11a14 100644 (file)
 
 #include <sys/stat.h>
 
-#include "machine_learning_exception.h"
-#include "simple_shot.h"
-#include "data_set_manager.h"
-#include "feature_vector_manager.h"
+#include "MvMlException.h"
+#include "SimpleShot.h"
+#include "DataSetManager.h"
+#include "FeatureVectorManager.h"
 #include "file_util.h"
 
 using namespace std;
diff --git a/mv_machine_learning/image_classification/include/IImageClassification.h b/mv_machine_learning/image_classification/include/IImageClassification.h
new file mode 100644 (file)
index 0000000..ed3412a
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * 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 __IIMAGE_CLASSIFICATION_H__
+#define __IIMAGE_CLASSIFICATION_H__
+
+#include <mv_common.h>
+
+#include "image_classification_type.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class IImageClassification
+{
+public:
+       virtual ~IImageClassification() {};
+
+       virtual void preDestroy() = 0;
+       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
+       virtual unsigned int getNumberOfEngines() = 0;
+       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
+       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
+       virtual const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) = 0;
+       virtual void configure() = 0;
+       virtual void prepare() = 0;
+       virtual void perform(mv_source_h &mv_src) = 0;
+       virtual void performAsync(ImageClassificationInput &input) = 0;
+       virtual ImageClassificationResult &getOutput() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_classification/include/ImageClassification.h b/mv_machine_learning/image_classification/include/ImageClassification.h
new file mode 100644 (file)
index 0000000..7e4dfca
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * 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 __IMAGE_CLASSIFICATION_H__
+#define __IMAGE_CLASSIFICATION_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+#include "mv_private.h"
+
+#include "EngineConfig.h"
+#include "inference_engine_common_impl.h"
+#include "Inference.h"
+#include "image_classification_type.h"
+#include "MetaParser.h"
+#include "MvMlConfig.h"
+#include "ImageClassificationParser.h"
+#include "MvMlPreprocess.h"
+#include "AsyncManager.h"
+#include "IImageClassification.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class ImageClassification : public IImageClassification
+{
+private:
+       std::unique_ptr<AsyncManager<T, ImageClassificationResult> > _async_manager;
+       ImageClassificationResult _current_result;
+
+       void loadLabel();
+       void getEngineList();
+       void getDeviceList(const std::string &engine_type);
+       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
+       std::shared_ptr<MetaInfo> getInputMetaInfo();
+
+protected:
+       std::unique_ptr<mediavision::inference::Inference> _inference;
+       std::shared_ptr<Config> _config;
+       Preprocess _preprocess;
+       std::vector<std::string> _labels;
+       std::vector<std::string> _valid_backends;
+       std::vector<std::string> _valid_devices;
+
+       void getOutputNames(std::vector<std::string> &names);
+       void getOutpuTensor(std::string &target_name, std::vector<float> &tensor);
+       void inference(std::vector<std::vector<T> > &inputVectors);
+       virtual ImageClassificationResult &result() = 0;
+
+public:
+       explicit ImageClassification(std::shared_ptr<Config> config);
+       virtual ~ImageClassification() = default;
+
+       void preDestroy();
+       void setEngineInfo(std::string engine_type_name, std::string device_type_name);
+       unsigned int getNumberOfEngines();
+       const std::string &getEngineType(unsigned int engine_index);
+       unsigned int getNumberOfDevices(const std::string &engine_type);
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index);
+       void configure();
+       void prepare();
+       void perform(mv_source_h &mv_src);
+       void performAsync(ImageClassificationInput &input);
+       ImageClassificationResult &getOutput();
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
diff --git a/mv_machine_learning/image_classification/include/ImageClassificationAdapter.h b/mv_machine_learning/image_classification/include/ImageClassificationAdapter.h
new file mode 100644 (file)
index 0000000..23deb88
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * 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 __IMAGE_CLASSIFICATION_ADAPTER_H__
+#define __IMAGE_CLASSIFICATION_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "MvMlConfig.h"
+#include "ImageClassificationDefault.h"
+#include "IImageClassification.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ImageClassificationAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<IImageClassification> _image_classification;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "image_classification.json";
+
+       void create();
+
+public:
+       ImageClassificationAdapter();
+       ~ImageClassificationAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_classification/include/ImageClassificationDefault.h b/mv_machine_learning/image_classification/include/ImageClassificationDefault.h
new file mode 100644 (file)
index 0000000..04f27a9
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * 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 __IMAGE_CLASSIFICATION_FLOAT_H__
+#define __IMAGE_CLASSIFICATION_FLOAT_H__
+
+#include <memory>
+#include <mv_common.h>
+#include "mv_private.h"
+
+#include "ImageClassification.h"
+#include <mv_inference_type.h>
+#include "EngineConfig.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class ImageClassificationDefault : public ImageClassification<T>
+{
+       using ImageClassification<T>::_config;
+       using ImageClassification<T>::_labels;
+
+private:
+       ImageClassificationResult _result;
+
+public:
+       ImageClassificationDefault(std::shared_ptr<Config> config);
+       ~ImageClassificationDefault();
+
+       ImageClassificationResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_classification/include/iimage_classification.h b/mv_machine_learning/image_classification/include/iimage_classification.h
deleted file mode 100644 (file)
index ed3412a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * 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 __IIMAGE_CLASSIFICATION_H__
-#define __IIMAGE_CLASSIFICATION_H__
-
-#include <mv_common.h>
-
-#include "image_classification_type.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class IImageClassification
-{
-public:
-       virtual ~IImageClassification() {};
-
-       virtual void preDestroy() = 0;
-       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
-       virtual unsigned int getNumberOfEngines() = 0;
-       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
-       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
-       virtual const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) = 0;
-       virtual void configure() = 0;
-       virtual void prepare() = 0;
-       virtual void perform(mv_source_h &mv_src) = 0;
-       virtual void performAsync(ImageClassificationInput &input) = 0;
-       virtual ImageClassificationResult &getOutput() = 0;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_classification/include/image_classification.h b/mv_machine_learning/image_classification/include/image_classification.h
deleted file mode 100644 (file)
index 7e0229d..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * 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 __IMAGE_CLASSIFICATION_H__
-#define __IMAGE_CLASSIFICATION_H__
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-#include "mv_private.h"
-
-#include "EngineConfig.h"
-#include "inference_engine_common_impl.h"
-#include "Inference.h"
-#include "image_classification_type.h"
-#include "MetaParser.h"
-#include "machine_learning_config.h"
-#include "ImageClassificationParser.h"
-#include "machine_learning_preprocess.h"
-#include "async_manager.h"
-#include "iimage_classification.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class ImageClassification : public IImageClassification
-{
-private:
-       std::unique_ptr<AsyncManager<T, ImageClassificationResult> > _async_manager;
-       ImageClassificationResult _current_result;
-
-       void loadLabel();
-       void getEngineList();
-       void getDeviceList(const std::string &engine_type);
-       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
-       std::shared_ptr<MetaInfo> getInputMetaInfo();
-
-protected:
-       std::unique_ptr<mediavision::inference::Inference> _inference;
-       std::shared_ptr<MachineLearningConfig> _config;
-       Preprocess _preprocess;
-       std::vector<std::string> _labels;
-       std::vector<std::string> _valid_backends;
-       std::vector<std::string> _valid_devices;
-
-       void getOutputNames(std::vector<std::string> &names);
-       void getOutpuTensor(std::string &target_name, std::vector<float> &tensor);
-       void inference(std::vector<std::vector<T> > &inputVectors);
-       virtual ImageClassificationResult &result() = 0;
-
-public:
-       explicit ImageClassification(std::shared_ptr<MachineLearningConfig> config);
-       virtual ~ImageClassification() = default;
-
-       void preDestroy();
-       void setEngineInfo(std::string engine_type_name, std::string device_type_name);
-       unsigned int getNumberOfEngines();
-       const std::string &getEngineType(unsigned int engine_index);
-       unsigned int getNumberOfDevices(const std::string &engine_type);
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index);
-       void configure();
-       void prepare();
-       void perform(mv_source_h &mv_src);
-       void performAsync(ImageClassificationInput &input);
-       ImageClassificationResult &getOutput();
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
diff --git a/mv_machine_learning/image_classification/include/image_classification_adapter.h b/mv_machine_learning/image_classification/include/image_classification_adapter.h
deleted file mode 100644 (file)
index 9011f46..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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 __IMAGE_CLASSIFICATION_ADAPTER_H__
-#define __IMAGE_CLASSIFICATION_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "machine_learning_config.h"
-#include "image_classification_default.h"
-#include "iimage_classification.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class ImageClassificationAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<IImageClassification> _image_classification;
-       std::shared_ptr<MachineLearningConfig> _config;
-       const std::string _config_file_name = "image_classification.json";
-
-       void create();
-
-public:
-       ImageClassificationAdapter();
-       ~ImageClassificationAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_classification/include/image_classification_default.h b/mv_machine_learning/image_classification/include/image_classification_default.h
deleted file mode 100644 (file)
index d409276..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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 __IMAGE_CLASSIFICATION_FLOAT_H__
-#define __IMAGE_CLASSIFICATION_FLOAT_H__
-
-#include <memory>
-#include <mv_common.h>
-#include "mv_private.h"
-
-#include "image_classification.h"
-#include <mv_inference_type.h>
-#include "EngineConfig.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class ImageClassificationDefault : public ImageClassification<T>
-{
-       using ImageClassification<T>::_config;
-       using ImageClassification<T>::_labels;
-
-private:
-       ImageClassificationResult _result;
-
-public:
-       ImageClassificationDefault(std::shared_ptr<MachineLearningConfig> config);
-       ~ImageClassificationDefault();
-
-       ImageClassificationResult &result() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
index 9b9b9f7db7c8a0b2f8ac3f55d0a96c352f5c43b6..92277d4ab73a1c18eb454b51ff6d3b21852b83b3 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <mv_common.h>
 #include <mv_inference_type.h>
-#include "MachineLearningType.h"
+#include "mv_ml_types.h"
 
 namespace mediavision
 {
diff --git a/mv_machine_learning/image_classification/src/ImageClassification.cpp b/mv_machine_learning/image_classification/src/ImageClassification.cpp
new file mode 100644 (file)
index 0000000..0a55330
--- /dev/null
@@ -0,0 +1,336 @@
+/**
+ * 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 <string.h>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "common.h"
+#include "mv_image_classification_config.h"
+#include "ImageClassification.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> ImageClassification<T>::ImageClassification(std::shared_ptr<Config> config) : _config(config)
+{
+       _inference = make_unique<Inference>();
+}
+
+template<typename T> void ImageClassification<T>::preDestroy()
+{
+       if (!_async_manager)
+               return;
+
+       _async_manager->stop();
+}
+
+template<typename T> void ImageClassification<T>::configure()
+{
+       loadLabel();
+
+       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+template<typename T> void ImageClassification<T>::loadLabel()
+{
+       if (_config->getLabelFilePath().empty())
+               return;
+
+       ifstream readFile;
+
+       _labels.clear();
+       readFile.open(_config->getLabelFilePath().c_str());
+
+       if (readFile.fail())
+               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
+
+       string line;
+
+       while (getline(readFile, line))
+               _labels.push_back(line);
+
+       readFile.close();
+}
+
+template<typename T> void ImageClassification<T>::getEngineList()
+{
+       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
+               auto backend = _inference->getSupportedInferenceBackend(idx);
+               // TODO. we need to describe what inference engines are supported by each Task API,
+               //       and based on it, below inference engine types should be checked
+               //       if a given type is supported by this Task API later. As of now, tflite only.
+               if (backend.second == true && backend.first.compare("tflite") == 0)
+                       _valid_backends.push_back(backend.first);
+       }
+}
+
+template<typename T> void ImageClassification<T>::getDeviceList(const string &engine_type)
+{
+       // TODO. add device types available for a given engine type later.
+       //       In default, cpu and gpu only.
+       _valid_devices.push_back("cpu");
+       _valid_devices.push_back("gpu");
+}
+
+template<typename T>
+void ImageClassification<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
+{
+       if (engine_type_name.empty() || device_type_name.empty())
+               throw InvalidParameter("Invalid engine info.");
+
+       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);
+
+       int engine_type = GetBackendType(engine_type_name);
+       int device_type = GetDeviceType(device_type_name);
+
+       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);
+}
+
+template<typename T> unsigned int ImageClassification<T>::getNumberOfEngines()
+{
+       if (!_valid_backends.empty()) {
+               return _valid_backends.size();
+       }
+
+       getEngineList();
+       return _valid_backends.size();
+}
+
+template<typename T> const string &ImageClassification<T>::getEngineType(unsigned int engine_index)
+{
+       if (!_valid_backends.empty()) {
+               if (_valid_backends.size() <= engine_index)
+                       throw InvalidParameter("Invalid engine index.");
+
+               return _valid_backends[engine_index];
+       }
+
+       getEngineList();
+
+       if (_valid_backends.size() <= engine_index)
+               throw InvalidParameter("Invalid engine index.");
+
+       return _valid_backends[engine_index];
+}
+
+template<typename T> unsigned int ImageClassification<T>::getNumberOfDevices(const string &engine_type)
+{
+       if (!_valid_devices.empty()) {
+               return _valid_devices.size();
+       }
+
+       getDeviceList(engine_type);
+       return _valid_devices.size();
+}
+
+template<typename T>
+const string &ImageClassification<T>::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       if (!_valid_devices.empty()) {
+               if (_valid_devices.size() <= device_index)
+                       throw InvalidParameter("Invalid device index.");
+
+               return _valid_devices[device_index];
+       }
+
+       getDeviceList(engine_type);
+
+       if (_valid_devices.size() <= device_index)
+               throw InvalidParameter("Invalid device index.");
+
+       return _valid_devices[device_index];
+}
+
+template<typename T> void ImageClassification<T>::prepare()
+{
+       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(_config->getOutputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+       _inference->configureModelFiles("", _config->getModelFilePath(), "");
+
+       // Request to load model files to a backend engine.
+       ret = _inference->load();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to load model files.");
+}
+
+template<typename T> shared_ptr<MetaInfo> ImageClassification<T>::getInputMetaInfo()
+{
+       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
+       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
+
+       // TODO. consider using multiple tensors later.
+       if (tensor_info_map.size() != 1)
+               throw InvalidOperation("Input tensor count not invalid.");
+
+       auto tensor_buffer_iter = tensor_info_map.begin();
+
+       // Get the meta information corresponding to a given input tensor name.
+       return _config->getInputMetaMap()[tensor_buffer_iter->first];
+}
+
+template<typename T>
+void ImageClassification<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
+{
+       LOGI("ENTER");
+
+       PreprocessConfig config = { false,
+                                                               metaInfo->colorSpace,
+                                                               metaInfo->dataType,
+                                                               metaInfo->getChannel(),
+                                                               metaInfo->getWidth(),
+                                                               metaInfo->getHeight() };
+
+       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
+       if (normalization) {
+               config.normalize = normalization->use;
+               config.mean = normalization->mean;
+               config.std = normalization->std;
+       }
+
+       auto quantization =
+                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
+       if (quantization) {
+               config.quantize = quantization->use;
+               config.scale = quantization->scale;
+               config.zeropoint = quantization->zeropoint;
+       }
+
+       _preprocess.setConfig(config);
+       _preprocess.run<T>(mv_src, inputVector);
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ImageClassification<T>::inference(vector<vector<T> > &inputVectors)
+{
+       LOGI("ENTER");
+
+       int ret = _inference->run<T>(inputVectors);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to run inference");
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ImageClassification<T>::perform(mv_source_h &mv_src)
+{
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(mv_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       inference(inputVectors);
+}
+
+template<typename T> ImageClassificationResult &ImageClassification<T>::getOutput()
+{
+       if (_async_manager) {
+               if (!_async_manager->isWorking())
+                       throw InvalidOperation("Image classification has been already destroyed so invalid operation.");
+
+               _current_result = _async_manager->pop();
+       } else {
+               // TODO. Check if inference request is completed or not here.
+               //       If not then throw an exception.
+               _current_result = result();
+       }
+
+       return _current_result;
+}
+
+template<typename T> void ImageClassification<T>::performAsync(ImageClassificationInput &input)
+{
+       if (!_async_manager) {
+               _async_manager = make_unique<AsyncManager<T, ImageClassificationResult> >([this]() {
+                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
+
+                       inference(inputQueue.inputs);
+
+                       ImageClassificationResult &resultQueue = result();
+
+                       resultQueue.frame_number = inputQueue.frame_number;
+                       _async_manager->pushToOutput(resultQueue);
+               });
+       }
+
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(input.inference_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       _async_manager->push(inputVectors);
+}
+
+template<typename T> void ImageClassification<T>::getOutputNames(vector<string> &names)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+
+       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
+               names.push_back(it->first);
+}
+
+template<typename T> void ImageClassification<T>::getOutpuTensor(string &target_name, vector<float> &tensor)
+{
+       LOGI("ENTER");
+
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+
+       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
+       if (!tensor_buffer)
+               throw InvalidOperation("Fail to get tensor buffer.");
+
+       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
+
+       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
+
+       LOGI("LEAVE");
+}
+
+template class ImageClassification<unsigned char>;
+template class ImageClassification<float>;
+
+}
+}
diff --git a/mv_machine_learning/image_classification/src/ImageClassificationAdapter.cpp b/mv_machine_learning/image_classification/src/ImageClassificationAdapter.cpp
new file mode 100644 (file)
index 0000000..b4b78b7
--- /dev/null
@@ -0,0 +1,130 @@
+/**
+ * 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 <string>
+
+#include "MvMlException.h"
+#include "mv_image_classification_config.h"
+#include "ImageClassificationAdapter.h"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+ImageClassificationAdapter::ImageClassificationAdapter()
+{
+       _config = make_shared<Config>();
+       _config->parseConfigFile(_config_file_name);
+
+       create();
+}
+
+ImageClassificationAdapter::~ImageClassificationAdapter()
+{
+       _image_classification->preDestroy();
+}
+
+void ImageClassificationAdapter::create()
+{
+       _config->loadMetaFile(make_unique<ImageClassificationParser>());
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               _image_classification = make_unique<ImageClassificationDefault<unsigned char> >(_config);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               _image_classification = make_unique<ImageClassificationDefault<float> >(_config);
+               break;
+       default:
+               throw InvalidOperation("Invalid image classification data type.");
+       }
+}
+
+void ImageClassificationAdapter::setModelInfo(const string &model_file, const string &meta_file,
+                                                                                         const string &label_file, const string &model_name)
+{
+       _config->setUserModel(model_file, meta_file, label_file);
+       create();
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+}
+
+void ImageClassificationAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _image_classification->setEngineInfo(engine_type, device_type);
+}
+
+void ImageClassificationAdapter::configure()
+{
+       _image_classification->configure();
+}
+
+unsigned int ImageClassificationAdapter::getNumberOfEngines()
+{
+       return _image_classification->getNumberOfEngines();
+}
+
+const string &ImageClassificationAdapter::getEngineType(unsigned int engine_index)
+{
+       return _image_classification->getEngineType(engine_index);
+}
+
+unsigned int ImageClassificationAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _image_classification->getNumberOfDevices(engine_type);
+}
+
+const string &ImageClassificationAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _image_classification->getDeviceType(engine_type, device_index);
+}
+
+void ImageClassificationAdapter::prepare()
+{
+       _image_classification->prepare();
+}
+
+void ImageClassificationAdapter::perform(InputBaseType &input)
+{
+       _image_classification->perform(input.inference_src);
+}
+
+void ImageClassificationAdapter::performAsync(InputBaseType &input)
+{
+       _image_classification->performAsync(static_cast<ImageClassificationInput &>(input));
+}
+
+OutputBaseType &ImageClassificationAdapter::getOutput()
+{
+       return _image_classification->getOutput();
+}
+
+OutputBaseType &ImageClassificationAdapter::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+}
+}
diff --git a/mv_machine_learning/image_classification/src/ImageClassificationDefault.cpp b/mv_machine_learning/image_classification/src/ImageClassificationDefault.cpp
new file mode 100644 (file)
index 0000000..01f8a34
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * 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 <string.h>
+#include <map>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "ImageClassificationDefault.h"
+#include "Postprocess.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+ImageClassificationDefault<T>::ImageClassificationDefault(shared_ptr<Config> config)
+               : ImageClassification<T>(config), _result()
+{}
+
+template<typename T> ImageClassificationDefault<T>::~ImageClassificationDefault()
+{}
+
+template<typename T> ImageClassificationResult &ImageClassificationDefault<T>::result()
+{
+       vector<string> names;
+
+       ImageClassification<T>::getOutputNames(names);
+
+       vector<float> output_vec;
+
+       // In case of image classification model, only one output tensor is used.
+       ImageClassification<T>::getOutpuTensor(names[0], output_vec);
+
+       auto metaInfo = _config->getOutputMetaMap().at(names[0]);
+       auto decodingScore = static_pointer_cast<DecodingScore>(metaInfo->decodingTypeMap.at(DecodingType::SCORE));
+
+       if (decodingScore->type == ScoreType::SIGMOID) {
+               for (size_t idx = 0; idx < output_vec.size(); ++idx)
+                       output_vec[idx] = PostProcess::sigmoid(output_vec[idx]);
+       }
+
+       _result.label = _labels[max_element(output_vec.begin(), output_vec.end()) - output_vec.begin()];
+       LOGI("Label = %s", _result.label.c_str());
+
+       return _result;
+}
+
+template class ImageClassificationDefault<unsigned char>;
+template class ImageClassificationDefault<float>;
+
+}
+}
index 72f681f828425658d9725351b884b7b50b6134eb..965ff5ccb2a6fd4120e5ad82148761a45d0cb2a1 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "machine_learning_exception.h"
+#include "MvMlException.h"
 #include "ImageClassificationParser.h"
 
 using namespace std;
diff --git a/mv_machine_learning/image_classification/src/image_classification.cpp b/mv_machine_learning/image_classification/src/image_classification.cpp
deleted file mode 100644 (file)
index d4bf394..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/**
- * 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 <string.h>
-#include <fstream>
-#include <map>
-#include <memory>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "mv_machine_learning_common.h"
-#include "mv_image_classification_config.h"
-#include "image_classification.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace MediaVision::Common;
-using namespace mediavision::common;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-ImageClassification<T>::ImageClassification(std::shared_ptr<MachineLearningConfig> config) : _config(config)
-{
-       _inference = make_unique<Inference>();
-}
-
-template<typename T> void ImageClassification<T>::preDestroy()
-{
-       if (!_async_manager)
-               return;
-
-       _async_manager->stop();
-}
-
-template<typename T> void ImageClassification<T>::configure()
-{
-       loadLabel();
-
-       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to bind a backend engine.");
-}
-
-template<typename T> void ImageClassification<T>::loadLabel()
-{
-       if (_config->getLabelFilePath().empty())
-               return;
-
-       ifstream readFile;
-
-       _labels.clear();
-       readFile.open(_config->getLabelFilePath().c_str());
-
-       if (readFile.fail())
-               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
-
-       string line;
-
-       while (getline(readFile, line))
-               _labels.push_back(line);
-
-       readFile.close();
-}
-
-template<typename T> void ImageClassification<T>::getEngineList()
-{
-       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
-               auto backend = _inference->getSupportedInferenceBackend(idx);
-               // TODO. we need to describe what inference engines are supported by each Task API,
-               //       and based on it, below inference engine types should be checked
-               //       if a given type is supported by this Task API later. As of now, tflite only.
-               if (backend.second == true && backend.first.compare("tflite") == 0)
-                       _valid_backends.push_back(backend.first);
-       }
-}
-
-template<typename T> void ImageClassification<T>::getDeviceList(const string &engine_type)
-{
-       // TODO. add device types available for a given engine type later.
-       //       In default, cpu and gpu only.
-       _valid_devices.push_back("cpu");
-       _valid_devices.push_back("gpu");
-}
-
-template<typename T>
-void ImageClassification<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
-{
-       if (engine_type_name.empty() || device_type_name.empty())
-               throw InvalidParameter("Invalid engine info.");
-
-       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);
-
-       int engine_type = GetBackendType(engine_type_name);
-       int device_type = GetDeviceType(device_type_name);
-
-       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);
-}
-
-template<typename T> unsigned int ImageClassification<T>::getNumberOfEngines()
-{
-       if (!_valid_backends.empty()) {
-               return _valid_backends.size();
-       }
-
-       getEngineList();
-       return _valid_backends.size();
-}
-
-template<typename T> const string &ImageClassification<T>::getEngineType(unsigned int engine_index)
-{
-       if (!_valid_backends.empty()) {
-               if (_valid_backends.size() <= engine_index)
-                       throw InvalidParameter("Invalid engine index.");
-
-               return _valid_backends[engine_index];
-       }
-
-       getEngineList();
-
-       if (_valid_backends.size() <= engine_index)
-               throw InvalidParameter("Invalid engine index.");
-
-       return _valid_backends[engine_index];
-}
-
-template<typename T> unsigned int ImageClassification<T>::getNumberOfDevices(const string &engine_type)
-{
-       if (!_valid_devices.empty()) {
-               return _valid_devices.size();
-       }
-
-       getDeviceList(engine_type);
-       return _valid_devices.size();
-}
-
-template<typename T>
-const string &ImageClassification<T>::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       if (!_valid_devices.empty()) {
-               if (_valid_devices.size() <= device_index)
-                       throw InvalidParameter("Invalid device index.");
-
-               return _valid_devices[device_index];
-       }
-
-       getDeviceList(engine_type);
-
-       if (_valid_devices.size() <= device_index)
-               throw InvalidParameter("Invalid device index.");
-
-       return _valid_devices[device_index];
-}
-
-template<typename T> void ImageClassification<T>::prepare()
-{
-       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(_config->getOutputMetaMap());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to configure output tensor info from meta file.");
-
-       _inference->configureModelFiles("", _config->getModelFilePath(), "");
-
-       // Request to load model files to a backend engine.
-       ret = _inference->load();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to load model files.");
-}
-
-template<typename T> shared_ptr<MetaInfo> ImageClassification<T>::getInputMetaInfo()
-{
-       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
-       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
-
-       // TODO. consider using multiple tensors later.
-       if (tensor_info_map.size() != 1)
-               throw InvalidOperation("Input tensor count not invalid.");
-
-       auto tensor_buffer_iter = tensor_info_map.begin();
-
-       // Get the meta information corresponding to a given input tensor name.
-       return _config->getInputMetaMap()[tensor_buffer_iter->first];
-}
-
-template<typename T>
-void ImageClassification<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
-{
-       LOGI("ENTER");
-
-       PreprocessConfig config = { false,
-                                                               metaInfo->colorSpace,
-                                                               metaInfo->dataType,
-                                                               metaInfo->getChannel(),
-                                                               metaInfo->getWidth(),
-                                                               metaInfo->getHeight() };
-
-       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
-       if (normalization) {
-               config.normalize = normalization->use;
-               config.mean = normalization->mean;
-               config.std = normalization->std;
-       }
-
-       auto quantization =
-                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
-       if (quantization) {
-               config.quantize = quantization->use;
-               config.scale = quantization->scale;
-               config.zeropoint = quantization->zeropoint;
-       }
-
-       _preprocess.setConfig(config);
-       _preprocess.run<T>(mv_src, inputVector);
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ImageClassification<T>::inference(vector<vector<T> > &inputVectors)
-{
-       LOGI("ENTER");
-
-       int ret = _inference->run<T>(inputVectors);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to run inference");
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ImageClassification<T>::perform(mv_source_h &mv_src)
-{
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(mv_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       inference(inputVectors);
-}
-
-template<typename T> ImageClassificationResult &ImageClassification<T>::getOutput()
-{
-       if (_async_manager) {
-               if (!_async_manager->isWorking())
-                       throw InvalidOperation("Image classification has been already destroyed so invalid operation.");
-
-               _current_result = _async_manager->pop();
-       } else {
-               // TODO. Check if inference request is completed or not here.
-               //       If not then throw an exception.
-               _current_result = result();
-       }
-
-       return _current_result;
-}
-
-template<typename T> void ImageClassification<T>::performAsync(ImageClassificationInput &input)
-{
-       if (!_async_manager) {
-               _async_manager = make_unique<AsyncManager<T, ImageClassificationResult> >([this]() {
-                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
-
-                       inference(inputQueue.inputs);
-
-                       ImageClassificationResult &resultQueue = result();
-
-                       resultQueue.frame_number = inputQueue.frame_number;
-                       _async_manager->pushToOutput(resultQueue);
-               });
-       }
-
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(input.inference_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       _async_manager->push(inputVectors);
-}
-
-template<typename T> void ImageClassification<T>::getOutputNames(vector<string> &names)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
-
-       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
-               names.push_back(it->first);
-}
-
-template<typename T> void ImageClassification<T>::getOutpuTensor(string &target_name, vector<float> &tensor)
-{
-       LOGI("ENTER");
-
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-
-       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
-       if (!tensor_buffer)
-               throw InvalidOperation("Fail to get tensor buffer.");
-
-       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
-
-       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
-
-       LOGI("LEAVE");
-}
-
-template class ImageClassification<unsigned char>;
-template class ImageClassification<float>;
-
-}
-}
diff --git a/mv_machine_learning/image_classification/src/image_classification_adapter.cpp b/mv_machine_learning/image_classification/src/image_classification_adapter.cpp
deleted file mode 100644 (file)
index c47d1d0..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * 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 <string>
-
-#include "machine_learning_exception.h"
-#include "mv_image_classification_config.h"
-#include "image_classification_adapter.h"
-
-using namespace std;
-using namespace MediaVision::Common;
-using namespace mediavision::machine_learning;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-ImageClassificationAdapter::ImageClassificationAdapter()
-{
-       _config = make_shared<MachineLearningConfig>();
-       _config->parseConfigFile(_config_file_name);
-
-       create();
-}
-
-ImageClassificationAdapter::~ImageClassificationAdapter()
-{
-       _image_classification->preDestroy();
-}
-
-void ImageClassificationAdapter::create()
-{
-       _config->loadMetaFile(make_unique<ImageClassificationParser>());
-       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
-
-       switch (dataType) {
-       case MV_INFERENCE_DATA_UINT8:
-               _image_classification = make_unique<ImageClassificationDefault<unsigned char> >(_config);
-               break;
-       case MV_INFERENCE_DATA_FLOAT32:
-               _image_classification = make_unique<ImageClassificationDefault<float> >(_config);
-               break;
-       default:
-               throw InvalidOperation("Invalid image classification data type.");
-       }
-}
-
-void ImageClassificationAdapter::setModelInfo(const string &model_file, const string &meta_file,
-                                                                                         const string &label_file, const string &model_name)
-{
-       _config->setUserModel(model_file, meta_file, label_file);
-       create();
-
-       if (model_file.empty() && meta_file.empty()) {
-               LOGW("Given model info is invalid so default model info will be used instead.");
-               return;
-       }
-}
-
-void ImageClassificationAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       _image_classification->setEngineInfo(engine_type, device_type);
-}
-
-void ImageClassificationAdapter::configure()
-{
-       _image_classification->configure();
-}
-
-unsigned int ImageClassificationAdapter::getNumberOfEngines()
-{
-       return _image_classification->getNumberOfEngines();
-}
-
-const string &ImageClassificationAdapter::getEngineType(unsigned int engine_index)
-{
-       return _image_classification->getEngineType(engine_index);
-}
-
-unsigned int ImageClassificationAdapter::getNumberOfDevices(const string &engine_type)
-{
-       return _image_classification->getNumberOfDevices(engine_type);
-}
-
-const string &ImageClassificationAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _image_classification->getDeviceType(engine_type, device_index);
-}
-
-void ImageClassificationAdapter::prepare()
-{
-       _image_classification->prepare();
-}
-
-void ImageClassificationAdapter::perform(InputBaseType &input)
-{
-       _image_classification->perform(input.inference_src);
-}
-
-void ImageClassificationAdapter::performAsync(InputBaseType &input)
-{
-       _image_classification->performAsync(static_cast<ImageClassificationInput &>(input));
-}
-
-OutputBaseType &ImageClassificationAdapter::getOutput()
-{
-       return _image_classification->getOutput();
-}
-
-OutputBaseType &ImageClassificationAdapter::getOutputCache()
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-}
-}
diff --git a/mv_machine_learning/image_classification/src/image_classification_default.cpp b/mv_machine_learning/image_classification/src/image_classification_default.cpp
deleted file mode 100644 (file)
index 59e8f33..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * 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 <string.h>
-#include <map>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "image_classification_default.h"
-#include "Postprocess.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-ImageClassificationDefault<T>::ImageClassificationDefault(shared_ptr<MachineLearningConfig> config)
-               : ImageClassification<T>(config), _result()
-{}
-
-template<typename T> ImageClassificationDefault<T>::~ImageClassificationDefault()
-{}
-
-template<typename T> ImageClassificationResult &ImageClassificationDefault<T>::result()
-{
-       vector<string> names;
-
-       ImageClassification<T>::getOutputNames(names);
-
-       vector<float> output_vec;
-
-       // In case of image classification model, only one output tensor is used.
-       ImageClassification<T>::getOutpuTensor(names[0], output_vec);
-
-       auto metaInfo = _config->getOutputMetaMap().at(names[0]);
-       auto decodingScore = static_pointer_cast<DecodingScore>(metaInfo->decodingTypeMap.at(DecodingType::SCORE));
-
-       if (decodingScore->type == ScoreType::SIGMOID) {
-               for (size_t idx = 0; idx < output_vec.size(); ++idx)
-                       output_vec[idx] = PostProcess::sigmoid(output_vec[idx]);
-       }
-
-       _result.label = _labels[max_element(output_vec.begin(), output_vec.end()) - output_vec.begin()];
-       LOGI("Label = %s", _result.label.c_str());
-
-       return _result;
-}
-
-template class ImageClassificationDefault<unsigned char>;
-template class ImageClassificationDefault<float>;
-
-}
-}
index 208624ef552a795ebcb32c9ae47abcc9a1b7a53b..89296e426e033a7edd40da9387c12145e53f31e3 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "itask.h"
+#include "ITask.h"
 #include "mv_image_classification_internal.h"
-#include "image_classification_adapter.h"
-#include "machine_learning_exception.h"
-#include "MachineLearningNative.h"
+#include "ImageClassificationAdapter.h"
+#include "MvMlException.h"
+#include "native_capi.h"
 #include "image_classification_type.h"
-#include "context.h"
+#include "Context.h"
 
 #include <new>
 #include <unistd.h>
index 1e3d95872644bae54be71abd43049cece9756c95..5d29c85b7ddeaeb68c53352076cfabc1723dcf94 100644 (file)
@@ -23,6 +23,6 @@ install(
 install(
        DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include/media
        FILES_MATCHING
-       PATTERN "iimage_segmentation.h"
+       PATTERN "IImageSegmentation.h"
        PATTERN "image_segmentation_type.h"
        )
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/IImageSegmentation.h b/mv_machine_learning/image_segmentation/include/IImageSegmentation.h
new file mode 100644 (file)
index 0000000..3305d36
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 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 __IIMAGE_SEGMENTATION_H__
+#define __IIMAGE_SEGMENTATION_H__
+
+#include <mv_common.h>
+
+#include "image_segmentation_type.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class IImageSegmentation
+{
+public:
+       virtual ~IImageSegmentation() {};
+
+       virtual void preDestroy() = 0;
+       virtual void setUserModel(std::string model_file, std::string meta_file, std::string label_file) = 0;
+       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
+       virtual unsigned int getNumberOfEngines() = 0;
+       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
+       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
+       virtual const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) = 0;
+       virtual void configure() = 0;
+       virtual void prepare() = 0;
+       virtual void perform(mv_source_h &mv_src) = 0;
+       virtual void performAsync(ImageSegmentationInput &input) = 0;
+       virtual ImageSegmentationResult &getOutput() = 0;
+       virtual ImageSegmentationResult &getOutputCache() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/ImageSegmentation.h b/mv_machine_learning/image_segmentation/include/ImageSegmentation.h
new file mode 100644 (file)
index 0000000..c16fa0d
--- /dev/null
@@ -0,0 +1,91 @@
+/**
+ * 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 __IMAGE_SEGMENTATION_H__
+#define __IMAGE_SEGMENTATION_H__
+
+#include <queue>
+#include <thread>
+#include <mutex>
+#include <atomic>
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+#include "mv_private.h"
+
+#include "EngineConfig.h"
+#include "inference_engine_common_impl.h"
+#include "Inference.h"
+#include "image_segmentation_type.h"
+#include "MetaParser.h"
+#include "MvMlConfig.h"
+#include "ImageSegmentationParser.h"
+#include "MvMlPreprocess.h"
+#include "IImageSegmentation.h"
+#include "AsyncManager.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class ImageSegmentation : public IImageSegmentation
+{
+private:
+       std::unique_ptr<AsyncManager<T, ImageSegmentationResult> > _async_manager;
+       ImageSegmentationResult _current_result {};
+
+       void loadLabel();
+       void getEngineList();
+       void getDeviceList(const std::string &engine_type);
+       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
+       std::shared_ptr<MetaInfo> getInputMetaInfo();
+
+protected:
+       std::unique_ptr<mediavision::inference::Inference> _inference;
+       std::shared_ptr<Config> _config;
+       std::vector<std::string> _labels;
+       std::vector<std::string> _valid_backends;
+       std::vector<std::string> _valid_devices;
+       Preprocess _preprocess;
+
+       void getOutputNames(std::vector<std::string> &names);
+       void getOutputTensor(std::string target_name, std::vector<float> &tensor);
+       void inference(std::vector<std::vector<T> > &inputVectors);
+       virtual ImageSegmentationResult &result() = 0;
+
+public:
+       explicit ImageSegmentation(std::shared_ptr<Config> config);
+       virtual ~ImageSegmentation() = default;
+
+       void preDestroy() 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;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) override;
+       void configure() override;
+       void prepare() override;
+       void perform(mv_source_h &mv_src) override;
+       void performAsync(ImageSegmentationInput &input) override;
+       ImageSegmentationResult &getOutput() override;
+       ImageSegmentationResult &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/ImageSegmentationAdapter.h b/mv_machine_learning/image_segmentation/include/ImageSegmentationAdapter.h
new file mode 100644 (file)
index 0000000..93758e0
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * 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 __SELFIE_SEGMENTATION_ADAPTER_H__
+#define __SELFIE_SEGMENTATION_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "ImageSegmentation.h"
+#include "IImageSegmentation.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ImageSegmentationAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<IImageSegmentation> _selfie_segmentation;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "selfie_segmentation.json";
+       const std::string _plugin_config_file_name = "selfie_segmentation_plugin.json";
+
+       void create(std::string model_name = "");
+       template<typename U> void create(ImageSegmentationTaskType task_type);
+       ImageSegmentationTaskType convertToTaskType(std::string model_name);
+
+public:
+       ImageSegmentationAdapter();
+       ~ImageSegmentationAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/ImageSegmentationExternal.h b/mv_machine_learning/image_segmentation/include/ImageSegmentationExternal.h
new file mode 100644 (file)
index 0000000..e662e48
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * 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 __IMAGE_SEGMENTATION_EXTERNAL_H__
+#define __IMAGE_SEGMENTATION_EXTERNAL_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+#include <opencv2/core.hpp>
+#include <opencv2/imgproc.hpp>
+
+#include "image_segmentation_type.h"
+#include "IImageSegmentation.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ImageSegmentationExternal : public IImageSegmentation
+{
+private:
+       void *_plugin_handle {};
+       IImageSegmentation *_image_segmentation_plugin {};
+       ImageSegmentationTaskType _task_type { ImageSegmentationTaskType::IMAGE_SEGMENTATION_TASK_NONE };
+       ImageSegmentationResult _current_result;
+
+public:
+       ImageSegmentationExternal(ImageSegmentationTaskType task_type, const std::string &plugin_name);
+       virtual ~ImageSegmentationExternal();
+
+       void preDestroy() 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;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) override;
+       void configure() override;
+       void prepare() override;
+       void perform(mv_source_h &mv_src) override;
+       void performAsync(ImageSegmentationInput &input) override;
+       ImageSegmentationResult &getOutput() override;
+       ImageSegmentationResult &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/ImageSegmentationParser.h b/mv_machine_learning/image_segmentation/include/ImageSegmentationParser.h
new file mode 100644 (file)
index 0000000..c6c9cde
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * 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 __IMAGE_SEGMENTATION_PARSER_H__
+#define __IMAGE_SEGMENTATION_PARSER_H__
+
+#include "MetaParser.h"
+#include "PostprocessParser.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ImageSegmentationParser : public MetaParser
+{
+private:
+       PostprocessParser _postprocessParser;
+
+protected:
+       void parsePostprocess(std::shared_ptr<MetaInfo> meta_info, JsonObject *in_obj) override;
+
+public:
+       ImageSegmentationParser(int task_type = 0);
+       ~ImageSegmentationParser();
+};
+
+}
+}
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/iimage_segmentation.h b/mv_machine_learning/image_segmentation/include/iimage_segmentation.h
deleted file mode 100644 (file)
index 3305d36..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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 __IIMAGE_SEGMENTATION_H__
-#define __IIMAGE_SEGMENTATION_H__
-
-#include <mv_common.h>
-
-#include "image_segmentation_type.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class IImageSegmentation
-{
-public:
-       virtual ~IImageSegmentation() {};
-
-       virtual void preDestroy() = 0;
-       virtual void setUserModel(std::string model_file, std::string meta_file, std::string label_file) = 0;
-       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
-       virtual unsigned int getNumberOfEngines() = 0;
-       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
-       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
-       virtual const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) = 0;
-       virtual void configure() = 0;
-       virtual void prepare() = 0;
-       virtual void perform(mv_source_h &mv_src) = 0;
-       virtual void performAsync(ImageSegmentationInput &input) = 0;
-       virtual ImageSegmentationResult &getOutput() = 0;
-       virtual ImageSegmentationResult &getOutputCache() = 0;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/image_segmentation.h b/mv_machine_learning/image_segmentation/include/image_segmentation.h
deleted file mode 100644 (file)
index 81a4cdb..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * 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 __IMAGE_SEGMENTATION_H__
-#define __IMAGE_SEGMENTATION_H__
-
-#include <queue>
-#include <thread>
-#include <mutex>
-#include <atomic>
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-#include "mv_private.h"
-
-#include "EngineConfig.h"
-#include "inference_engine_common_impl.h"
-#include "Inference.h"
-#include "image_segmentation_type.h"
-#include "MetaParser.h"
-#include "machine_learning_config.h"
-#include "image_segmentation_parser.h"
-#include "machine_learning_preprocess.h"
-#include "iimage_segmentation.h"
-#include "async_manager.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class ImageSegmentation : public IImageSegmentation
-{
-private:
-       std::unique_ptr<AsyncManager<T, ImageSegmentationResult> > _async_manager;
-       ImageSegmentationResult _current_result {};
-
-       void loadLabel();
-       void getEngineList();
-       void getDeviceList(const std::string &engine_type);
-       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
-       std::shared_ptr<MetaInfo> getInputMetaInfo();
-
-protected:
-       std::unique_ptr<mediavision::inference::Inference> _inference;
-       std::shared_ptr<MachineLearningConfig> _config;
-       std::vector<std::string> _labels;
-       std::vector<std::string> _valid_backends;
-       std::vector<std::string> _valid_devices;
-       Preprocess _preprocess;
-
-       void getOutputNames(std::vector<std::string> &names);
-       void getOutputTensor(std::string target_name, std::vector<float> &tensor);
-       void inference(std::vector<std::vector<T> > &inputVectors);
-       virtual ImageSegmentationResult &result() = 0;
-
-public:
-       explicit ImageSegmentation(std::shared_ptr<MachineLearningConfig> config);
-       virtual ~ImageSegmentation() = default;
-
-       void preDestroy() 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;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) override;
-       void configure() override;
-       void prepare() override;
-       void perform(mv_source_h &mv_src) override;
-       void performAsync(ImageSegmentationInput &input) override;
-       ImageSegmentationResult &getOutput() override;
-       ImageSegmentationResult &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/image_segmentation_external.h b/mv_machine_learning/image_segmentation/include/image_segmentation_external.h
deleted file mode 100644 (file)
index c663480..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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 __IMAGE_SEGMENTATION_EXTERNAL_H__
-#define __IMAGE_SEGMENTATION_EXTERNAL_H__
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-
-#include <opencv2/core.hpp>
-#include <opencv2/imgproc.hpp>
-
-#include "image_segmentation_type.h"
-#include "iimage_segmentation.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class ImageSegmentationExternal : public IImageSegmentation
-{
-private:
-       void *_plugin_handle {};
-       IImageSegmentation *_image_segmentation_plugin {};
-       ImageSegmentationTaskType _task_type { ImageSegmentationTaskType::IMAGE_SEGMENTATION_TASK_NONE };
-       ImageSegmentationResult _current_result;
-
-public:
-       ImageSegmentationExternal(ImageSegmentationTaskType task_type, const std::string &plugin_name);
-       virtual ~ImageSegmentationExternal();
-
-       void preDestroy() 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;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) override;
-       void configure() override;
-       void prepare() override;
-       void perform(mv_source_h &mv_src) override;
-       void performAsync(ImageSegmentationInput &input) override;
-       ImageSegmentationResult &getOutput() override;
-       ImageSegmentationResult &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/include/image_segmentation_parser.h b/mv_machine_learning/image_segmentation/include/image_segmentation_parser.h
deleted file mode 100644 (file)
index c6c9cde..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * 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 __IMAGE_SEGMENTATION_PARSER_H__
-#define __IMAGE_SEGMENTATION_PARSER_H__
-
-#include "MetaParser.h"
-#include "PostprocessParser.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class ImageSegmentationParser : public MetaParser
-{
-private:
-       PostprocessParser _postprocessParser;
-
-protected:
-       void parsePostprocess(std::shared_ptr<MetaInfo> meta_info, JsonObject *in_obj) override;
-
-public:
-       ImageSegmentationParser(int task_type = 0);
-       ~ImageSegmentationParser();
-};
-
-}
-}
-
-#endif
\ No newline at end of file
index e6a459c53eed3d9954a8953812e7bef9555e9f93..0b9f68823b59a8e4f5713fe1aa0be94091af681d 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <mv_common.h>
 #include <mv_inference_type.h>
-#include "MachineLearningType.h"
+#include "mv_ml_types.h"
 
 namespace mediavision
 {
diff --git a/mv_machine_learning/image_segmentation/include/selfie_segmentation_adapter.h b/mv_machine_learning/image_segmentation/include/selfie_segmentation_adapter.h
deleted file mode 100644 (file)
index 82ed323..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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 __SELFIE_SEGMENTATION_ADAPTER_H__
-#define __SELFIE_SEGMENTATION_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "image_segmentation.h"
-#include "iimage_segmentation.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class ImageSegmentationAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<IImageSegmentation> _selfie_segmentation;
-       std::shared_ptr<MachineLearningConfig> _config;
-       const std::string _config_file_name = "selfie_segmentation.json";
-       const std::string _plugin_config_file_name = "selfie_segmentation_plugin.json";
-
-       void create(std::string model_name = "");
-       template<typename U> void create(ImageSegmentationTaskType task_type);
-       ImageSegmentationTaskType convertToTaskType(std::string model_name);
-
-public:
-       ImageSegmentationAdapter();
-       ~ImageSegmentationAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/src/ImageSegmentation.cpp b/mv_machine_learning/image_segmentation/src/ImageSegmentation.cpp
new file mode 100644 (file)
index 0000000..096bc11
--- /dev/null
@@ -0,0 +1,340 @@
+/**
+ * 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 <string.h>
+#include <fstream>
+#include <map>
+#include <memory>
+
+#include "MvMlException.h"
+#include "common.h"
+#include "mv_image_segmentation_config.h"
+#include "ImageSegmentation.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> ImageSegmentation<T>::ImageSegmentation(shared_ptr<Config> config) : _config(config)
+{
+       _inference = make_unique<Inference>();
+}
+
+template<typename T> void ImageSegmentation<T>::preDestroy()
+{
+       if (!_async_manager)
+               return;
+
+       _async_manager->stop();
+}
+
+template<typename T> void ImageSegmentation<T>::getEngineList()
+{
+       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
+               auto backend = _inference->getSupportedInferenceBackend(idx);
+               // TODO. we need to describe what inference engines are supported by each Task API,
+               //       and based on it, below inference engine types should be checked
+               //       if a given type is supported by this Task API later. As of now, tflite only.
+               if (backend.second == true && backend.first.compare("tflite") == 0)
+                       _valid_backends.push_back(backend.first);
+       }
+}
+
+template<typename T> void ImageSegmentation<T>::getDeviceList(const string &engine_type)
+{
+       // TODO. add device types available for a given engine type later.
+       //       In default, cpu and gpu only.
+       _valid_devices.push_back("cpu");
+       _valid_devices.push_back("gpu");
+}
+
+template<typename T>
+void ImageSegmentation<T>::setUserModel(std::string model_file, std::string meta_file, std::string label_file)
+{}
+
+template<typename T>
+void ImageSegmentation<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
+{
+       if (engine_type_name.empty() || device_type_name.empty())
+               throw InvalidParameter("Invalid engine info.");
+
+       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);
+
+       int engine_type = GetBackendType(engine_type_name);
+       int device_type = GetDeviceType(device_type_name);
+
+       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);
+}
+
+template<typename T> unsigned int ImageSegmentation<T>::getNumberOfEngines()
+{
+       if (!_valid_backends.empty()) {
+               return _valid_backends.size();
+       }
+
+       getEngineList();
+       return _valid_backends.size();
+}
+
+template<typename T> const string &ImageSegmentation<T>::getEngineType(unsigned int engine_index)
+{
+       if (!_valid_backends.empty()) {
+               if (_valid_backends.size() <= engine_index)
+                       throw InvalidParameter("Invalid engine index.");
+
+               return _valid_backends[engine_index];
+       }
+
+       getEngineList();
+
+       if (_valid_backends.size() <= engine_index)
+               throw InvalidParameter("Invalid engine index.");
+
+       return _valid_backends[engine_index];
+}
+
+template<typename T> unsigned int ImageSegmentation<T>::getNumberOfDevices(const string &engine_type)
+{
+       if (!_valid_devices.empty()) {
+               return _valid_devices.size();
+       }
+
+       getDeviceList(engine_type);
+       return _valid_devices.size();
+}
+
+template<typename T>
+const string &ImageSegmentation<T>::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       if (!_valid_devices.empty()) {
+               if (_valid_devices.size() <= device_index)
+                       throw InvalidParameter("Invalid device index.");
+
+               return _valid_devices[device_index];
+       }
+
+       getDeviceList(engine_type);
+
+       if (_valid_devices.size() <= device_index)
+               throw InvalidParameter("Invalid device index.");
+
+       return _valid_devices[device_index];
+}
+
+template<typename T> void ImageSegmentation<T>::loadLabel()
+{
+       if (_config->getLabelFilePath().empty())
+               return;
+
+       ifstream readFile;
+
+       _labels.clear();
+       readFile.open(_config->getLabelFilePath().c_str());
+
+       if (readFile.fail())
+               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
+
+       string line;
+
+       while (getline(readFile, line))
+               _labels.push_back(line);
+
+       readFile.close();
+}
+
+template<typename T> void ImageSegmentation<T>::configure()
+{
+       loadLabel();
+
+       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+template<typename T> void ImageSegmentation<T>::prepare()
+{
+       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(_config->getOutputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+       _inference->configureModelFiles("", _config->getModelFilePath(), "");
+
+       // Request to load model files to a backend engine.
+       ret = _inference->load();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to load model files.");
+}
+
+template<typename T> shared_ptr<MetaInfo> ImageSegmentation<T>::getInputMetaInfo()
+{
+       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
+       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
+
+       // TODO. consider using multiple tensors later.
+       if (tensor_info_map.size() != 1)
+               throw InvalidOperation("Input tensor count not invalid.");
+
+       auto tensor_buffer_iter = tensor_info_map.begin();
+
+       // Get the meta information corresponding to a given input tensor name.
+       return _config->getInputMetaMap()[tensor_buffer_iter->first];
+}
+
+template<typename T>
+void ImageSegmentation<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
+{
+       LOGI("ENTER");
+
+       PreprocessConfig config = { false,
+                                                               metaInfo->colorSpace,
+                                                               metaInfo->dataType,
+                                                               metaInfo->getChannel(),
+                                                               metaInfo->getWidth(),
+                                                               metaInfo->getHeight() };
+
+       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
+       if (normalization) {
+               config.normalize = normalization->use;
+               config.mean = normalization->mean;
+               config.std = normalization->std;
+       }
+
+       auto quantization =
+                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
+       if (quantization) {
+               config.quantize = quantization->use;
+               config.scale = quantization->scale;
+               config.zeropoint = quantization->zeropoint;
+       }
+
+       _preprocess.setConfig(config);
+       _preprocess.run<T>(mv_src, inputVector);
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ImageSegmentation<T>::inference(vector<vector<T> > &inputVectors)
+{
+       LOGI("ENTER");
+
+       int ret = _inference->run<T>(inputVectors);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to run inference");
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ImageSegmentation<T>::perform(mv_source_h &mv_src)
+{
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(mv_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       inference(inputVectors);
+}
+
+template<typename T> void ImageSegmentation<T>::performAsync(ImageSegmentationInput &input)
+{
+       if (!_async_manager) {
+               _async_manager = make_unique<AsyncManager<T, ImageSegmentationResult> >([this]() {
+                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
+
+                       inference(inputQueue.inputs);
+
+                       ImageSegmentationResult &resultQueue = result();
+
+                       resultQueue.frame_number = inputQueue.frame_number;
+                       _async_manager->pushToOutput(resultQueue);
+               });
+       }
+
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(input.inference_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       _async_manager->push(inputVectors);
+}
+
+template<typename T> ImageSegmentationResult &ImageSegmentation<T>::getOutput()
+{
+       if (_async_manager) {
+               if (!_async_manager->isWorking())
+                       throw InvalidOperation("Object detection has been already destroyed so invalid operation.");
+
+               _current_result = _async_manager->pop();
+       } else {
+               // TODO. Check if inference request is completed or not here.
+               //       If not then throw an exception.
+               _current_result = result();
+       }
+
+       return _current_result;
+}
+
+template<typename T> ImageSegmentationResult &ImageSegmentation<T>::getOutputCache()
+{
+       return _current_result;
+}
+
+template<typename T> void ImageSegmentation<T>::getOutputNames(vector<string> &names)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+
+       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
+               names.push_back(it->first);
+}
+
+template<typename T> void ImageSegmentation<T>::getOutputTensor(string target_name, vector<float> &tensor)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+
+       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
+       if (!tensor_buffer)
+               throw InvalidOperation("Fail to get tensor buffer.");
+
+       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
+
+       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
+}
+
+template class ImageSegmentation<unsigned char>;
+template class ImageSegmentation<float>;
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/src/ImageSegmentationAdapter.cpp b/mv_machine_learning/image_segmentation/src/ImageSegmentationAdapter.cpp
new file mode 100644 (file)
index 0000000..493cc06
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * 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 "MvMlException.h"
+#include "ImageSegmentationAdapter.h"
+#include "ImageSegmentationExternal.h"
+#include "mv_image_segmentation_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
+{
+ImageSegmentationAdapter::ImageSegmentationAdapter()
+{
+       _config = make_shared<Config>();
+
+       // If the model type needs external plugin then bypass to load the meta file and just create the external plugin.
+       // In this case, external plugin will use its own meta file approach regardless of Mediavision's one.
+       _config->parsePluginConfigFile(_plugin_config_file_name);
+       if (!_config->isPluginUsed())
+               _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+ImageSegmentationAdapter::~ImageSegmentationAdapter()
+{
+       _selfie_segmentation->preDestroy();
+}
+
+template<typename U> void ImageSegmentationAdapter::create(ImageSegmentationTaskType task_type)
+{
+       // TODO. add switch-case statement here for Mediavision own task types.
+}
+
+void ImageSegmentationAdapter::create(std::string model_name)
+{
+       if (model_name.empty())
+               model_name = _config->getDefaultModelName();
+
+       auto task_type = convertToTaskType(model_name);
+
+       if (_config->isPluginUsed()) {
+               const auto &plugin_name = _config->getPluginFileName();
+
+               _selfie_segmentation = make_unique<ImageSegmentationExternal>(task_type, plugin_name.c_str());
+               return;
+       }
+
+       _config->loadMetaFile(make_unique<ImageSegmentationParser>(static_cast<int>(task_type)));
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               create<unsigned char>(task_type);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               create<float>(task_type);
+               break;
+       default:
+               throw InvalidOperation("Invalid image segmentation data type.");
+       }
+}
+
+ImageSegmentationTaskType ImageSegmentationAdapter::convertToTaskType(string 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 == "SELFIE_SEGMENTATION")
+               return ImageSegmentationTaskType::SELFIE_SEGMENTATION;
+
+       throw InvalidParameter("Invalid selfie segmentation model name.");
+}
+
+void ImageSegmentationAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                                       const string &model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               create(model_name);
+       } catch (const BaseException &e) {
+               LOGW("A given model name is invalid so default task type will be used.");
+       }
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+
+       _selfie_segmentation->setUserModel(model_file, meta_file, label_file);
+}
+
+void ImageSegmentationAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _selfie_segmentation->setEngineInfo(engine_type, device_type);
+}
+
+void ImageSegmentationAdapter::configure()
+{
+       _selfie_segmentation->configure();
+}
+
+unsigned int ImageSegmentationAdapter::getNumberOfEngines()
+{
+       return _selfie_segmentation->getNumberOfEngines();
+}
+
+const string &ImageSegmentationAdapter::getEngineType(unsigned int engine_index)
+{
+       return _selfie_segmentation->getEngineType(engine_index);
+}
+
+unsigned int ImageSegmentationAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _selfie_segmentation->getNumberOfDevices(engine_type);
+}
+
+const string &ImageSegmentationAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _selfie_segmentation->getDeviceType(engine_type, device_index);
+}
+
+void ImageSegmentationAdapter::prepare()
+{
+       _selfie_segmentation->prepare();
+}
+
+void ImageSegmentationAdapter::perform(InputBaseType &input)
+{
+       _selfie_segmentation->perform(input.inference_src);
+}
+
+OutputBaseType &ImageSegmentationAdapter::getOutput()
+{
+       return _selfie_segmentation->getOutput();
+}
+
+OutputBaseType &ImageSegmentationAdapter::getOutputCache()
+{
+       return _selfie_segmentation->getOutputCache();
+}
+
+void ImageSegmentationAdapter::performAsync(InputBaseType &input)
+{
+       _selfie_segmentation->performAsync(static_cast<ImageSegmentationInput &>(input));
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/src/ImageSegmentationExternal.cpp b/mv_machine_learning/image_segmentation/src/ImageSegmentationExternal.cpp
new file mode 100644 (file)
index 0000000..267f3ed
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * 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 "MvMlException.h"
+#include "ImageSegmentationExternal.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+typedef IImageSegmentation *create_t(ImageSegmentationTaskType task_type);
+typedef void destroy_t(IImageSegmentation *);
+
+ImageSegmentationExternal::ImageSegmentationExternal(ImageSegmentationTaskType task_type, const string &plugin_name)
+               : _plugin_handle(), _image_segmentation_plugin()
+{
+       // Load external plugin library.
+       LOGI("lib: %s", plugin_name.c_str());
+       _plugin_handle = dlopen(plugin_name.c_str(), 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.");
+       }
+
+       _image_segmentation_plugin = createPlugin(task_type);
+       if (_image_segmentation_plugin == NULL) {
+               dlclose(_plugin_handle);
+               _plugin_handle = NULL;
+               throw InvalidOperation("Fail to create plugin module.");
+       }
+}
+
+ImageSegmentationExternal::~ImageSegmentationExternal()
+{
+       if (_plugin_handle) {
+               destroy_t *destroyPlugin = (destroy_t *) dlsym(_plugin_handle, "destroyPlugin");
+
+               destroyPlugin(_image_segmentation_plugin);
+               dlclose(_plugin_handle);
+               _image_segmentation_plugin = nullptr;
+               _plugin_handle = nullptr;
+       }
+}
+
+void ImageSegmentationExternal::preDestroy()
+{
+       _image_segmentation_plugin->preDestroy();
+}
+
+void ImageSegmentationExternal::setUserModel(string model_file, string meta_file, string label_file)
+{
+       _image_segmentation_plugin->setUserModel(model_file, meta_file, label_file);
+}
+
+void ImageSegmentationExternal::setEngineInfo(string engine_type, string device_type)
+{
+       _image_segmentation_plugin->setEngineInfo(engine_type, device_type);
+}
+
+unsigned int ImageSegmentationExternal::getNumberOfEngines()
+{
+       return _image_segmentation_plugin->getNumberOfEngines();
+}
+
+const string &ImageSegmentationExternal::getEngineType(unsigned int engine_index)
+{
+       return _image_segmentation_plugin->getEngineType(engine_index);
+}
+
+unsigned int ImageSegmentationExternal::getNumberOfDevices(const string &engine_type)
+{
+       return _image_segmentation_plugin->getNumberOfDevices(engine_type.c_str());
+}
+
+const string &ImageSegmentationExternal::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _image_segmentation_plugin->getDeviceType(engine_type.c_str(), device_index);
+}
+
+void ImageSegmentationExternal::configure()
+{
+       _image_segmentation_plugin->configure();
+}
+
+void ImageSegmentationExternal::prepare()
+{
+       _image_segmentation_plugin->prepare();
+}
+
+void ImageSegmentationExternal::perform(mv_source_h &mv_src)
+{
+       _image_segmentation_plugin->perform(mv_src);
+}
+
+void ImageSegmentationExternal::performAsync(ImageSegmentationInput &input)
+{
+       _image_segmentation_plugin->performAsync(input);
+}
+
+ImageSegmentationResult &ImageSegmentationExternal::getOutput()
+{
+       _current_result = _image_segmentation_plugin->getOutput();
+
+       return _current_result;
+}
+
+ImageSegmentationResult &ImageSegmentationExternal::getOutputCache()
+{
+       return _current_result;
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/src/ImageSegmentationParser.cpp b/mv_machine_learning/image_segmentation/src/ImageSegmentationParser.cpp
new file mode 100644 (file)
index 0000000..a3e56ca
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * 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 <memory>
+
+#include "MvMlException.h"
+#include "ImageSegmentationParser.h"
+#include "image_segmentation_type.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+ImageSegmentationParser::ImageSegmentationParser(int task_type)
+{
+       LOGI("ENTER");
+       LOGI("LEAVE");
+}
+
+ImageSegmentationParser::~ImageSegmentationParser()
+{
+       LOGI("ENTER");
+       LOGI("LEAVE");
+}
+
+void ImageSegmentationParser::parsePostprocess(shared_ptr<MetaInfo> meta_info, JsonObject *in_obj)
+{
+       LOGI("ENTER");
+       LOGI("LEAVE");
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/src/image_segmentation.cpp b/mv_machine_learning/image_segmentation/src/image_segmentation.cpp
deleted file mode 100644 (file)
index 30d065c..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/**
- * 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 <string.h>
-#include <fstream>
-#include <map>
-#include <memory>
-
-#include "machine_learning_exception.h"
-#include "mv_machine_learning_common.h"
-#include "mv_image_segmentation_config.h"
-#include "image_segmentation.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace MediaVision::Common;
-using namespace mediavision::common;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> ImageSegmentation<T>::ImageSegmentation(shared_ptr<MachineLearningConfig> config) : _config(config)
-{
-       _inference = make_unique<Inference>();
-}
-
-template<typename T> void ImageSegmentation<T>::preDestroy()
-{
-       if (!_async_manager)
-               return;
-
-       _async_manager->stop();
-}
-
-template<typename T> void ImageSegmentation<T>::getEngineList()
-{
-       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
-               auto backend = _inference->getSupportedInferenceBackend(idx);
-               // TODO. we need to describe what inference engines are supported by each Task API,
-               //       and based on it, below inference engine types should be checked
-               //       if a given type is supported by this Task API later. As of now, tflite only.
-               if (backend.second == true && backend.first.compare("tflite") == 0)
-                       _valid_backends.push_back(backend.first);
-       }
-}
-
-template<typename T> void ImageSegmentation<T>::getDeviceList(const string &engine_type)
-{
-       // TODO. add device types available for a given engine type later.
-       //       In default, cpu and gpu only.
-       _valid_devices.push_back("cpu");
-       _valid_devices.push_back("gpu");
-}
-
-template<typename T>
-void ImageSegmentation<T>::setUserModel(std::string model_file, std::string meta_file, std::string label_file)
-{}
-
-template<typename T>
-void ImageSegmentation<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
-{
-       if (engine_type_name.empty() || device_type_name.empty())
-               throw InvalidParameter("Invalid engine info.");
-
-       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);
-
-       int engine_type = GetBackendType(engine_type_name);
-       int device_type = GetDeviceType(device_type_name);
-
-       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);
-}
-
-template<typename T> unsigned int ImageSegmentation<T>::getNumberOfEngines()
-{
-       if (!_valid_backends.empty()) {
-               return _valid_backends.size();
-       }
-
-       getEngineList();
-       return _valid_backends.size();
-}
-
-template<typename T> const string &ImageSegmentation<T>::getEngineType(unsigned int engine_index)
-{
-       if (!_valid_backends.empty()) {
-               if (_valid_backends.size() <= engine_index)
-                       throw InvalidParameter("Invalid engine index.");
-
-               return _valid_backends[engine_index];
-       }
-
-       getEngineList();
-
-       if (_valid_backends.size() <= engine_index)
-               throw InvalidParameter("Invalid engine index.");
-
-       return _valid_backends[engine_index];
-}
-
-template<typename T> unsigned int ImageSegmentation<T>::getNumberOfDevices(const string &engine_type)
-{
-       if (!_valid_devices.empty()) {
-               return _valid_devices.size();
-       }
-
-       getDeviceList(engine_type);
-       return _valid_devices.size();
-}
-
-template<typename T>
-const string &ImageSegmentation<T>::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       if (!_valid_devices.empty()) {
-               if (_valid_devices.size() <= device_index)
-                       throw InvalidParameter("Invalid device index.");
-
-               return _valid_devices[device_index];
-       }
-
-       getDeviceList(engine_type);
-
-       if (_valid_devices.size() <= device_index)
-               throw InvalidParameter("Invalid device index.");
-
-       return _valid_devices[device_index];
-}
-
-template<typename T> void ImageSegmentation<T>::loadLabel()
-{
-       if (_config->getLabelFilePath().empty())
-               return;
-
-       ifstream readFile;
-
-       _labels.clear();
-       readFile.open(_config->getLabelFilePath().c_str());
-
-       if (readFile.fail())
-               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
-
-       string line;
-
-       while (getline(readFile, line))
-               _labels.push_back(line);
-
-       readFile.close();
-}
-
-template<typename T> void ImageSegmentation<T>::configure()
-{
-       loadLabel();
-
-       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to bind a backend engine.");
-}
-
-template<typename T> void ImageSegmentation<T>::prepare()
-{
-       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(_config->getOutputMetaMap());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to configure output tensor info from meta file.");
-
-       _inference->configureModelFiles("", _config->getModelFilePath(), "");
-
-       // Request to load model files to a backend engine.
-       ret = _inference->load();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to load model files.");
-}
-
-template<typename T> shared_ptr<MetaInfo> ImageSegmentation<T>::getInputMetaInfo()
-{
-       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
-       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
-
-       // TODO. consider using multiple tensors later.
-       if (tensor_info_map.size() != 1)
-               throw InvalidOperation("Input tensor count not invalid.");
-
-       auto tensor_buffer_iter = tensor_info_map.begin();
-
-       // Get the meta information corresponding to a given input tensor name.
-       return _config->getInputMetaMap()[tensor_buffer_iter->first];
-}
-
-template<typename T>
-void ImageSegmentation<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
-{
-       LOGI("ENTER");
-
-       PreprocessConfig config = { false,
-                                                               metaInfo->colorSpace,
-                                                               metaInfo->dataType,
-                                                               metaInfo->getChannel(),
-                                                               metaInfo->getWidth(),
-                                                               metaInfo->getHeight() };
-
-       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
-       if (normalization) {
-               config.normalize = normalization->use;
-               config.mean = normalization->mean;
-               config.std = normalization->std;
-       }
-
-       auto quantization =
-                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
-       if (quantization) {
-               config.quantize = quantization->use;
-               config.scale = quantization->scale;
-               config.zeropoint = quantization->zeropoint;
-       }
-
-       _preprocess.setConfig(config);
-       _preprocess.run<T>(mv_src, inputVector);
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ImageSegmentation<T>::inference(vector<vector<T> > &inputVectors)
-{
-       LOGI("ENTER");
-
-       int ret = _inference->run<T>(inputVectors);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to run inference");
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ImageSegmentation<T>::perform(mv_source_h &mv_src)
-{
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(mv_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       inference(inputVectors);
-}
-
-template<typename T> void ImageSegmentation<T>::performAsync(ImageSegmentationInput &input)
-{
-       if (!_async_manager) {
-               _async_manager = make_unique<AsyncManager<T, ImageSegmentationResult> >([this]() {
-                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
-
-                       inference(inputQueue.inputs);
-
-                       ImageSegmentationResult &resultQueue = result();
-
-                       resultQueue.frame_number = inputQueue.frame_number;
-                       _async_manager->pushToOutput(resultQueue);
-               });
-       }
-
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(input.inference_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       _async_manager->push(inputVectors);
-}
-
-template<typename T> ImageSegmentationResult &ImageSegmentation<T>::getOutput()
-{
-       if (_async_manager) {
-               if (!_async_manager->isWorking())
-                       throw InvalidOperation("Object detection has been already destroyed so invalid operation.");
-
-               _current_result = _async_manager->pop();
-       } else {
-               // TODO. Check if inference request is completed or not here.
-               //       If not then throw an exception.
-               _current_result = result();
-       }
-
-       return _current_result;
-}
-
-template<typename T> ImageSegmentationResult &ImageSegmentation<T>::getOutputCache()
-{
-       return _current_result;
-}
-
-template<typename T> void ImageSegmentation<T>::getOutputNames(vector<string> &names)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
-
-       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
-               names.push_back(it->first);
-}
-
-template<typename T> void ImageSegmentation<T>::getOutputTensor(string target_name, vector<float> &tensor)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-
-       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
-       if (!tensor_buffer)
-               throw InvalidOperation("Fail to get tensor buffer.");
-
-       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
-
-       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
-}
-
-template class ImageSegmentation<unsigned char>;
-template class ImageSegmentation<float>;
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/src/image_segmentation_external.cpp b/mv_machine_learning/image_segmentation/src/image_segmentation_external.cpp
deleted file mode 100644 (file)
index bf3083e..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * 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 "image_segmentation_external.h"
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-typedef IImageSegmentation *create_t(ImageSegmentationTaskType task_type);
-typedef void destroy_t(IImageSegmentation *);
-
-ImageSegmentationExternal::ImageSegmentationExternal(ImageSegmentationTaskType task_type, const string &plugin_name)
-               : _plugin_handle(), _image_segmentation_plugin()
-{
-       // Load external plugin library.
-       LOGI("lib: %s", plugin_name.c_str());
-       _plugin_handle = dlopen(plugin_name.c_str(), 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.");
-       }
-
-       _image_segmentation_plugin = createPlugin(task_type);
-       if (_image_segmentation_plugin == NULL) {
-               dlclose(_plugin_handle);
-               _plugin_handle = NULL;
-               throw InvalidOperation("Fail to create plugin module.");
-       }
-}
-
-ImageSegmentationExternal::~ImageSegmentationExternal()
-{
-       if (_plugin_handle) {
-               destroy_t *destroyPlugin = (destroy_t *) dlsym(_plugin_handle, "destroyPlugin");
-
-               destroyPlugin(_image_segmentation_plugin);
-               dlclose(_plugin_handle);
-               _image_segmentation_plugin = nullptr;
-               _plugin_handle = nullptr;
-       }
-}
-
-void ImageSegmentationExternal::preDestroy()
-{
-       _image_segmentation_plugin->preDestroy();
-}
-
-void ImageSegmentationExternal::setUserModel(string model_file, string meta_file, string label_file)
-{
-       _image_segmentation_plugin->setUserModel(model_file, meta_file, label_file);
-}
-
-void ImageSegmentationExternal::setEngineInfo(string engine_type, string device_type)
-{
-       _image_segmentation_plugin->setEngineInfo(engine_type, device_type);
-}
-
-unsigned int ImageSegmentationExternal::getNumberOfEngines()
-{
-       return _image_segmentation_plugin->getNumberOfEngines();
-}
-
-const string &ImageSegmentationExternal::getEngineType(unsigned int engine_index)
-{
-       return _image_segmentation_plugin->getEngineType(engine_index);
-}
-
-unsigned int ImageSegmentationExternal::getNumberOfDevices(const string &engine_type)
-{
-       return _image_segmentation_plugin->getNumberOfDevices(engine_type.c_str());
-}
-
-const string &ImageSegmentationExternal::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _image_segmentation_plugin->getDeviceType(engine_type.c_str(), device_index);
-}
-
-void ImageSegmentationExternal::configure()
-{
-       _image_segmentation_plugin->configure();
-}
-
-void ImageSegmentationExternal::prepare()
-{
-       _image_segmentation_plugin->prepare();
-}
-
-void ImageSegmentationExternal::perform(mv_source_h &mv_src)
-{
-       _image_segmentation_plugin->perform(mv_src);
-}
-
-void ImageSegmentationExternal::performAsync(ImageSegmentationInput &input)
-{
-       _image_segmentation_plugin->performAsync(input);
-}
-
-ImageSegmentationResult &ImageSegmentationExternal::getOutput()
-{
-       _current_result = _image_segmentation_plugin->getOutput();
-
-       return _current_result;
-}
-
-ImageSegmentationResult &ImageSegmentationExternal::getOutputCache()
-{
-       return _current_result;
-}
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/image_segmentation/src/image_segmentation_parser.cpp b/mv_machine_learning/image_segmentation/src/image_segmentation_parser.cpp
deleted file mode 100644 (file)
index f3ea0b6..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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 <memory>
-
-#include "machine_learning_exception.h"
-#include "image_segmentation_parser.h"
-#include "image_segmentation_type.h"
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-ImageSegmentationParser::ImageSegmentationParser(int task_type)
-{
-       LOGI("ENTER");
-       LOGI("LEAVE");
-}
-
-ImageSegmentationParser::~ImageSegmentationParser()
-{
-       LOGI("ENTER");
-       LOGI("LEAVE");
-}
-
-void ImageSegmentationParser::parsePostprocess(shared_ptr<MetaInfo> meta_info, JsonObject *in_obj)
-{
-       LOGI("ENTER");
-       LOGI("LEAVE");
-}
-
-}
-}
\ No newline at end of file
index 5c3c25b7ae2990d44c9c041cd57b227a9739e859..7bd675493f98a7e2d0bab8cb01757fd923275731 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "itask.h"
+#include "ITask.h"
 #include "mv_selfie_segmentation_type.h"
 #include "mv_selfie_segmentation_internal.h"
-#include "selfie_segmentation_adapter.h"
-#include "machine_learning_exception.h"
-#include "MachineLearningNative.h"
+#include "ImageSegmentationAdapter.h"
+#include "MvMlException.h"
+#include "native_capi.h"
 #include "image_segmentation_type.h"
-#include "context.h"
+#include "Context.h"
 
 #include <new>
 #include <unistd.h>
diff --git a/mv_machine_learning/image_segmentation/src/selfie_segmentation_adapter.cpp b/mv_machine_learning/image_segmentation/src/selfie_segmentation_adapter.cpp
deleted file mode 100644 (file)
index d43b75b..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * 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 "selfie_segmentation_adapter.h"
-#include "image_segmentation_external.h"
-#include "mv_image_segmentation_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
-{
-ImageSegmentationAdapter::ImageSegmentationAdapter()
-{
-       _config = make_shared<MachineLearningConfig>();
-
-       // If the model type needs external plugin then bypass to load the meta file and just create the external plugin.
-       // In this case, external plugin will use its own meta file approach regardless of Mediavision's one.
-       _config->parsePluginConfigFile(_plugin_config_file_name);
-       if (!_config->isPluginUsed())
-               _config->parseConfigFile(_config_file_name);
-
-       create(_config->getDefaultModelName());
-}
-
-ImageSegmentationAdapter::~ImageSegmentationAdapter()
-{
-       _selfie_segmentation->preDestroy();
-}
-
-template<typename U> void ImageSegmentationAdapter::create(ImageSegmentationTaskType task_type)
-{
-       // TODO. add switch-case statement here for Mediavision own task types.
-}
-
-void ImageSegmentationAdapter::create(std::string model_name)
-{
-       if (model_name.empty())
-               model_name = _config->getDefaultModelName();
-
-       auto task_type = convertToTaskType(model_name);
-
-       if (_config->isPluginUsed()) {
-               const auto &plugin_name = _config->getPluginFileName();
-
-               _selfie_segmentation = make_unique<ImageSegmentationExternal>(task_type, plugin_name.c_str());
-               return;
-       }
-
-       _config->loadMetaFile(make_unique<ImageSegmentationParser>(static_cast<int>(task_type)));
-       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
-
-       switch (dataType) {
-       case MV_INFERENCE_DATA_UINT8:
-               create<unsigned char>(task_type);
-               break;
-       case MV_INFERENCE_DATA_FLOAT32:
-               create<float>(task_type);
-               break;
-       default:
-               throw InvalidOperation("Invalid image segmentation data type.");
-       }
-}
-
-ImageSegmentationTaskType ImageSegmentationAdapter::convertToTaskType(string 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 == "SELFIE_SEGMENTATION")
-               return ImageSegmentationTaskType::SELFIE_SEGMENTATION;
-
-       throw InvalidParameter("Invalid selfie segmentation model name.");
-}
-
-void ImageSegmentationAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                                       const string &model_name)
-{
-       try {
-               _config->setUserModel(model_file, meta_file, label_file);
-               create(model_name);
-       } catch (const BaseException &e) {
-               LOGW("A given model name is invalid so default task type will be used.");
-       }
-
-       if (model_file.empty() && meta_file.empty()) {
-               LOGW("Given model info is invalid so default model info will be used instead.");
-               return;
-       }
-
-       _selfie_segmentation->setUserModel(model_file, meta_file, label_file);
-}
-
-void ImageSegmentationAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       _selfie_segmentation->setEngineInfo(engine_type, device_type);
-}
-
-void ImageSegmentationAdapter::configure()
-{
-       _selfie_segmentation->configure();
-}
-
-unsigned int ImageSegmentationAdapter::getNumberOfEngines()
-{
-       return _selfie_segmentation->getNumberOfEngines();
-}
-
-const string &ImageSegmentationAdapter::getEngineType(unsigned int engine_index)
-{
-       return _selfie_segmentation->getEngineType(engine_index);
-}
-
-unsigned int ImageSegmentationAdapter::getNumberOfDevices(const string &engine_type)
-{
-       return _selfie_segmentation->getNumberOfDevices(engine_type);
-}
-
-const string &ImageSegmentationAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _selfie_segmentation->getDeviceType(engine_type, device_index);
-}
-
-void ImageSegmentationAdapter::prepare()
-{
-       _selfie_segmentation->prepare();
-}
-
-void ImageSegmentationAdapter::perform(InputBaseType &input)
-{
-       _selfie_segmentation->perform(input.inference_src);
-}
-
-OutputBaseType &ImageSegmentationAdapter::getOutput()
-{
-       return _selfie_segmentation->getOutput();
-}
-
-OutputBaseType &ImageSegmentationAdapter::getOutputCache()
-{
-       return _selfie_segmentation->getOutputCache();
-}
-
-void ImageSegmentationAdapter::performAsync(InputBaseType &input)
-{
-       _selfie_segmentation->performAsync(static_cast<ImageSegmentationInput &>(input));
-}
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/FacialLandmarkAdapter.h b/mv_machine_learning/landmark_detection/include/FacialLandmarkAdapter.h
new file mode 100644 (file)
index 0000000..5ec7ee1
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * 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 __FACE_LANDMARK_ADAPTER_H__
+#define __FACE_LANDMARK_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "MvMlConfig.h"
+#include "FldTweakCnn.h"
+#include "ILandmarkDetection.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FacialLandmarkAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<ILandmarkDetection> _landmark_detection;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "facial_landmark.json";
+
+       void create(const std::string &model_name);
+       template<typename U> void create(LandmarkDetectionTaskType task_type);
+       LandmarkDetectionTaskType convertToTaskType(std::string model_name);
+
+public:
+       FacialLandmarkAdapter();
+       ~FacialLandmarkAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/FldTweakCnn.h b/mv_machine_learning/landmark_detection/include/FldTweakCnn.h
new file mode 100644 (file)
index 0000000..b6e13bb
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 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 __FLD_TWEAK_CNN_H__
+#define __FLD_TWEAK_CNN_H__
+
+#include <string>
+#include <memory>
+#include <mv_common.h>
+#include "mv_private.h"
+
+#include "LandmarkDetection.h"
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class FldTweakCnn : public LandmarkDetection<T>
+{
+       using LandmarkDetection<T>::_config;
+       using LandmarkDetection<T>::_preprocess;
+       using LandmarkDetection<T>::_inference;
+
+private:
+       LandmarkDetectionResult _result;
+
+public:
+       FldTweakCnn(LandmarkDetectionTaskType task_type, std::shared_ptr<Config> config);
+       ~FldTweakCnn();
+
+       LandmarkDetectionResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/ILandmarkDetection.h b/mv_machine_learning/landmark_detection/include/ILandmarkDetection.h
new file mode 100644 (file)
index 0000000..0d709ad
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * 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 __ILANDMARK_DETECTION_H__
+#define __ILANDMARK_DETECTION_H__
+
+#include <mv_common.h>
+
+#include "landmark_detection_type.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ILandmarkDetection
+{
+public:
+       virtual ~ILandmarkDetection() {};
+
+       virtual void preDestroy() = 0;
+       virtual LandmarkDetectionTaskType getTaskType() = 0;
+       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
+       virtual unsigned int getNumberOfEngines() = 0;
+       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
+       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
+       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
+       virtual void configure() = 0;
+       virtual void prepare() = 0;
+       virtual void perform(mv_source_h &mv_src) = 0;
+       virtual void performAsync(LandmarkDetectionInput &input) = 0;
+       virtual LandmarkDetectionResult &getOutput() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/LandmarkDetection.h b/mv_machine_learning/landmark_detection/include/LandmarkDetection.h
new file mode 100644 (file)
index 0000000..01d45f0
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ * 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 __LANDMARK_DETECTION_H__
+#define __LANDMARK_DETECTION_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+#include "mv_private.h"
+
+#include "EngineConfig.h"
+#include "inference_engine_common_impl.h"
+#include "Inference.h"
+#include "landmark_detection_type.h"
+#include "MetaParser.h"
+#include "LandmarkDetectionParser.h"
+#include "MvMlConfig.h"
+#include "MvMlPreprocess.h"
+#include "AsyncManager.h"
+#include "ILandmarkDetection.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class LandmarkDetection : public ILandmarkDetection
+{
+private:
+       std::unique_ptr<AsyncManager<T, LandmarkDetectionResult> > _async_manager;
+       LandmarkDetectionResult _current_result {};
+       LandmarkDetectionTaskType _task_type;
+
+       void loadLabel();
+       void getEngineList();
+       void getDeviceList(const std::string &engine_type);
+
+       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
+       std::shared_ptr<MetaInfo> getInputMetaInfo();
+
+protected:
+       std::unique_ptr<mediavision::inference::Inference> _inference;
+       std::shared_ptr<Config> _config;
+       std::vector<std::string> _labels;
+       std::vector<std::string> _valid_backends;
+       std::vector<std::string> _valid_devices;
+       Preprocess _preprocess;
+
+       void getOutputNames(std::vector<std::string> &names);
+       void getOutputTensor(std::string target_name, std::vector<float> &tensor);
+       void inference(std::vector<std::vector<T> > &inputVectors);
+       virtual LandmarkDetectionResult &result() = 0;
+
+public:
+       LandmarkDetection(LandmarkDetectionTaskType task_type, std::shared_ptr<Config> config);
+       virtual ~LandmarkDetection() = default;
+       void preDestroy();
+       LandmarkDetectionTaskType getTaskType();
+       void setEngineInfo(std::string engine_type_name, std::string device_type_name);
+       unsigned int getNumberOfEngines();
+       const std::string &getEngineType(unsigned int engine_index);
+       unsigned int getNumberOfDevices(const std::string &engine_type);
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index);
+       void configure();
+       void prepare();
+       void perform(mv_source_h &mv_src);
+       void performAsync(LandmarkDetectionInput &input);
+       LandmarkDetectionResult &getOutput();
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/PldCpm.h b/mv_machine_learning/landmark_detection/include/PldCpm.h
new file mode 100644 (file)
index 0000000..3a06e26
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * 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 __PLD_CPM_H__
+#define __PLD_CPM_H__
+
+#include <string>
+#include <memory>
+#include <mv_common.h>
+#include "mv_private.h"
+
+#include "LandmarkDetection.h"
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class PldCpm : public LandmarkDetection<T>
+{
+       using LandmarkDetection<T>::_config;
+       using LandmarkDetection<T>::_preprocess;
+
+private:
+       LandmarkDetectionResult _result;
+
+public:
+       PldCpm(LandmarkDetectionTaskType task_type, std::shared_ptr<Config> config);
+       ~PldCpm();
+
+       LandmarkDetectionResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/PoseLandmarkAdapter.h b/mv_machine_learning/landmark_detection/include/PoseLandmarkAdapter.h
new file mode 100644 (file)
index 0000000..d4d1505
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * 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 __POSE_LANDMARK_ADAPTER_H__
+#define __POSE_LANDMARK_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "MvMlConfig.h"
+#include "PldCpm.h"
+#include "ILandmarkDetection.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class PoseLandmarkAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<ILandmarkDetection> _landmark_detection;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "pose_landmark.json";
+
+       void create(const std::string &model_name);
+       template<typename U> void create(LandmarkDetectionTaskType task_type);
+       LandmarkDetectionTaskType convertToTaskType(std::string model_name);
+
+public:
+       PoseLandmarkAdapter();
+       ~PoseLandmarkAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h b/mv_machine_learning/landmark_detection/include/facial_landmark_adapter.h
deleted file mode 100644 (file)
index 7302719..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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 __FACE_LANDMARK_ADAPTER_H__
-#define __FACE_LANDMARK_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "machine_learning_config.h"
-#include "fld_tweak_cnn.h"
-#include "ilandmark_detection.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class FacialLandmarkAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<ILandmarkDetection> _landmark_detection;
-       std::shared_ptr<MachineLearningConfig> _config;
-       const std::string _config_file_name = "facial_landmark.json";
-
-       void create(const std::string &model_name);
-       template<typename U> void create(LandmarkDetectionTaskType task_type);
-       LandmarkDetectionTaskType convertToTaskType(std::string model_name);
-
-public:
-       FacialLandmarkAdapter();
-       ~FacialLandmarkAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/fld_tweak_cnn.h b/mv_machine_learning/landmark_detection/include/fld_tweak_cnn.h
deleted file mode 100644 (file)
index 08d4b67..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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 __FLD_TWEAK_CNN_H__
-#define __FLD_TWEAK_CNN_H__
-
-#include <string>
-#include <memory>
-#include <mv_common.h>
-#include "mv_private.h"
-
-#include "landmark_detection.h"
-#include <mv_inference_type.h>
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class FldTweakCnn : public LandmarkDetection<T>
-{
-       using LandmarkDetection<T>::_config;
-       using LandmarkDetection<T>::_preprocess;
-       using LandmarkDetection<T>::_inference;
-
-private:
-       LandmarkDetectionResult _result;
-
-public:
-       FldTweakCnn(LandmarkDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       ~FldTweakCnn();
-
-       LandmarkDetectionResult &result() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/ilandmark_detection.h b/mv_machine_learning/landmark_detection/include/ilandmark_detection.h
deleted file mode 100644 (file)
index 0d709ad..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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 __ILANDMARK_DETECTION_H__
-#define __ILANDMARK_DETECTION_H__
-
-#include <mv_common.h>
-
-#include "landmark_detection_type.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class ILandmarkDetection
-{
-public:
-       virtual ~ILandmarkDetection() {};
-
-       virtual void preDestroy() = 0;
-       virtual LandmarkDetectionTaskType getTaskType() = 0;
-       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
-       virtual unsigned int getNumberOfEngines() = 0;
-       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
-       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
-       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
-       virtual void configure() = 0;
-       virtual void prepare() = 0;
-       virtual void perform(mv_source_h &mv_src) = 0;
-       virtual void performAsync(LandmarkDetectionInput &input) = 0;
-       virtual LandmarkDetectionResult &getOutput() = 0;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/landmark_detection.h b/mv_machine_learning/landmark_detection/include/landmark_detection.h
deleted file mode 100644 (file)
index 075c6ba..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * 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 __LANDMARK_DETECTION_H__
-#define __LANDMARK_DETECTION_H__
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-#include "mv_private.h"
-
-#include "EngineConfig.h"
-#include "inference_engine_common_impl.h"
-#include "Inference.h"
-#include "landmark_detection_type.h"
-#include "MetaParser.h"
-#include "LandmarkDetectionParser.h"
-#include "machine_learning_config.h"
-#include "machine_learning_preprocess.h"
-#include "async_manager.h"
-#include "ilandmark_detection.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class LandmarkDetection : public ILandmarkDetection
-{
-private:
-       std::unique_ptr<AsyncManager<T, LandmarkDetectionResult> > _async_manager;
-       LandmarkDetectionResult _current_result {};
-       LandmarkDetectionTaskType _task_type;
-
-       void loadLabel();
-       void getEngineList();
-       void getDeviceList(const std::string &engine_type);
-
-       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
-       std::shared_ptr<MetaInfo> getInputMetaInfo();
-
-protected:
-       std::unique_ptr<mediavision::inference::Inference> _inference;
-       std::shared_ptr<MachineLearningConfig> _config;
-       std::vector<std::string> _labels;
-       std::vector<std::string> _valid_backends;
-       std::vector<std::string> _valid_devices;
-       Preprocess _preprocess;
-
-       void getOutputNames(std::vector<std::string> &names);
-       void getOutputTensor(std::string target_name, std::vector<float> &tensor);
-       void inference(std::vector<std::vector<T> > &inputVectors);
-       virtual LandmarkDetectionResult &result() = 0;
-
-public:
-       LandmarkDetection(LandmarkDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       virtual ~LandmarkDetection() = default;
-       void preDestroy();
-       LandmarkDetectionTaskType getTaskType();
-       void setEngineInfo(std::string engine_type_name, std::string device_type_name);
-       unsigned int getNumberOfEngines();
-       const std::string &getEngineType(unsigned int engine_index);
-       unsigned int getNumberOfDevices(const std::string &engine_type);
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index);
-       void configure();
-       void prepare();
-       void perform(mv_source_h &mv_src);
-       void performAsync(LandmarkDetectionInput &input);
-       LandmarkDetectionResult &getOutput();
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
index f1310296a40bee93b925382cd98fa22705759286..80a947b0579edb7a515b34b85518cc0243b69761 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <mv_common.h>
 #include <mv_inference_type.h>
-#include "MachineLearningType.h"
+#include "mv_ml_types.h"
 
 namespace mediavision
 {
diff --git a/mv_machine_learning/landmark_detection/include/pld_cpm.h b/mv_machine_learning/landmark_detection/include/pld_cpm.h
deleted file mode 100644 (file)
index 993e975..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * 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 __PLD_CPM_H__
-#define __PLD_CPM_H__
-
-#include <string>
-#include <memory>
-#include <mv_common.h>
-#include "mv_private.h"
-
-#include "landmark_detection.h"
-#include <mv_inference_type.h>
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class PldCpm : public LandmarkDetection<T>
-{
-       using LandmarkDetection<T>::_config;
-       using LandmarkDetection<T>::_preprocess;
-
-private:
-       LandmarkDetectionResult _result;
-
-public:
-       PldCpm(LandmarkDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       ~PldCpm();
-
-       LandmarkDetectionResult &result() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h b/mv_machine_learning/landmark_detection/include/pose_landmark_adapter.h
deleted file mode 100644 (file)
index 484246a..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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 __POSE_LANDMARK_ADAPTER_H__
-#define __POSE_LANDMARK_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "machine_learning_config.h"
-#include "pld_cpm.h"
-#include "ilandmark_detection.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class PoseLandmarkAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<ILandmarkDetection> _landmark_detection;
-       std::shared_ptr<MachineLearningConfig> _config;
-       const std::string _config_file_name = "pose_landmark.json";
-
-       void create(const std::string &model_name);
-       template<typename U> void create(LandmarkDetectionTaskType task_type);
-       LandmarkDetectionTaskType convertToTaskType(std::string model_name);
-
-public:
-       PoseLandmarkAdapter();
-       ~PoseLandmarkAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/FacialLandmarkAdapter.cpp b/mv_machine_learning/landmark_detection/src/FacialLandmarkAdapter.cpp
new file mode 100644 (file)
index 0000000..a200477
--- /dev/null
@@ -0,0 +1,158 @@
+/**
+ * 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 "MvMlException.h"
+#include "FacialLandmarkAdapter.h"
+#include "mv_landmark_detection_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
+{
+FacialLandmarkAdapter::FacialLandmarkAdapter()
+{
+       _config = make_shared<Config>();
+       _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+FacialLandmarkAdapter::~FacialLandmarkAdapter()
+{
+       _landmark_detection->preDestroy();
+}
+
+template<typename U> void FacialLandmarkAdapter::create(LandmarkDetectionTaskType task_type)
+{
+       switch (task_type) {
+       case LandmarkDetectionTaskType::FLD_TWEAK_CNN:
+               _landmark_detection = make_unique<FldTweakCnn<U> >(task_type, _config);
+               break;
+       default:
+               throw InvalidOperation("Invalid landmark detection task type.");
+       }
+}
+
+void FacialLandmarkAdapter::create(const string &model_name)
+{
+       LandmarkDetectionTaskType task_type = convertToTaskType(model_name);
+       _config->loadMetaFile(make_unique<LandmarkDetectionParser>(static_cast<int>(task_type)));
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               create<unsigned char>(task_type);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               create<float>(task_type);
+               break;
+       default:
+               throw InvalidOperation("Invalid landmark detection data type.");
+       }
+}
+
+LandmarkDetectionTaskType FacialLandmarkAdapter::convertToTaskType(string 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 == "FLD_TWEAK_CNN")
+               return LandmarkDetectionTaskType::FLD_TWEAK_CNN;
+       // TODO.
+
+       throw InvalidParameter("Invalid facial detection model name.");
+}
+
+void FacialLandmarkAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                                const string &model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               create(model_name);
+       } catch (const BaseException &e) {
+               LOGW("A given model name is invalid so default task type will be used.");
+       }
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+}
+
+void FacialLandmarkAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _landmark_detection->setEngineInfo(string(engine_type), string(device_type));
+}
+
+void FacialLandmarkAdapter::configure()
+{
+       _landmark_detection->configure();
+}
+
+unsigned int FacialLandmarkAdapter::getNumberOfEngines()
+{
+       return _landmark_detection->getNumberOfEngines();
+}
+
+const string &FacialLandmarkAdapter::getEngineType(unsigned int engine_index)
+{
+       return _landmark_detection->getEngineType(engine_index);
+}
+
+unsigned int FacialLandmarkAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _landmark_detection->getNumberOfDevices(engine_type);
+}
+
+const string &FacialLandmarkAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _landmark_detection->getDeviceType(engine_type, device_index);
+}
+
+void FacialLandmarkAdapter::prepare()
+{
+       _landmark_detection->prepare();
+}
+
+void FacialLandmarkAdapter::perform(InputBaseType &input)
+{
+       _landmark_detection->perform(input.inference_src);
+}
+
+void FacialLandmarkAdapter::performAsync(InputBaseType &input)
+{
+       _landmark_detection->performAsync(static_cast<LandmarkDetectionInput &>(input));
+}
+
+OutputBaseType &FacialLandmarkAdapter::getOutput()
+{
+       return _landmark_detection->getOutput();
+}
+
+OutputBaseType &FacialLandmarkAdapter::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/FldTweakCnn.cpp b/mv_machine_learning/landmark_detection/src/FldTweakCnn.cpp
new file mode 100644 (file)
index 0000000..512b3be
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * 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 <string.h>
+#include <map>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "FldTweakCnn.h"
+#include "Postprocess.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+FldTweakCnn<T>::FldTweakCnn(LandmarkDetectionTaskType task_type, std::shared_ptr<Config> config)
+               : LandmarkDetection<T>(task_type, config), _result()
+{}
+
+template<typename T> FldTweakCnn<T>::~FldTweakCnn()
+{}
+
+template<typename T> LandmarkDetectionResult &FldTweakCnn<T>::result()
+{
+       constexpr static unsigned int numberOfLandmarks = 5;
+
+       // Clear _result object because result() function can be called every time user wants
+       // so make sure to clear existing result data before getting the data again.
+       _result = LandmarkDetectionResult();
+
+       vector<string> names;
+
+       LandmarkDetection<T>::getOutputNames(names);
+
+       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[0]);
+       auto decodingLandmark =
+                       static_pointer_cast<DecodingLandmark>(scoreMetaInfo->decodingTypeMap[DecodingType::LANDMARK]);
+
+       if (decodingLandmark->decoding_type != LandmarkDecodingType::BYPASS)
+               throw InvalidOperation("decoding type not support.");
+
+       if (decodingLandmark->coordinate_type != LandmarkCoordinateType::RATIO)
+               throw InvalidOperation("coordinate type not support.");
+
+       if (decodingLandmark->landmark_type != LandmarkType::SINGLE_2D)
+               throw InvalidOperation("landmark type not support.");
+
+       auto ori_src_width = static_cast<double>(_preprocess.getImageWidth()[0]);
+       auto ori_src_height = static_cast<double>(_preprocess.getImageHeight()[0]);
+       auto input_tensor_width = static_cast<double>(_inference->getInputWidth());
+       auto input_tensor_height = static_cast<double>(_inference->getInputHeight());
+
+       _result.number_of_landmarks = numberOfLandmarks;
+
+       vector<float> score_tensor;
+
+       LandmarkDetection<T>::getOutputTensor(names[0], score_tensor);
+
+       // Calculate the ratio[A] between the original image size and the input tensor size.
+       double width_ratio = ori_src_width / input_tensor_width;
+       double height_ratio = ori_src_height / input_tensor_height;
+
+       // In case that landmark coordinate type is RATIO, output tensor buffer contains ratio values indicating
+       // the position of each landmark for the input tensor.
+       // Therefore, each landmark position for original image is as following,
+       //    x = [width A] * width of input tensor * width ratio value of output tensor.
+       //    y = [height A] * height of input tensor * height ratio value of output tensor.
+       for (unsigned int idx = 0; idx < numberOfLandmarks; ++idx) {
+               _result.x_pos.push_back(
+                               static_cast<unsigned int>(width_ratio * input_tensor_width * score_tensor[idx + idx * 1]));
+               _result.y_pos.push_back(
+                               static_cast<unsigned int>(height_ratio * input_tensor_height * score_tensor[idx + idx * 1 + 1]));
+       }
+
+       return _result;
+}
+
+template class FldTweakCnn<unsigned char>;
+template class FldTweakCnn<float>;
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/LandmarkDetection.cpp b/mv_machine_learning/landmark_detection/src/LandmarkDetection.cpp
new file mode 100644 (file)
index 0000000..d4f179e
--- /dev/null
@@ -0,0 +1,339 @@
+/**
+ * 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 <string.h>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "common.h"
+#include "LandmarkDetection.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+LandmarkDetection<T>::LandmarkDetection(LandmarkDetectionTaskType task_type, shared_ptr<Config> config)
+               : _task_type(task_type), _config(config)
+{
+       _inference = make_unique<Inference>();
+}
+
+template<typename T> void LandmarkDetection<T>::preDestroy()
+{
+       if (!_async_manager)
+               return;
+
+       _async_manager->stop();
+}
+
+template<typename T> LandmarkDetectionTaskType LandmarkDetection<T>::getTaskType()
+{
+       return _task_type;
+}
+
+template<typename T> void LandmarkDetection<T>::getEngineList()
+{
+       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
+               auto backend = _inference->getSupportedInferenceBackend(idx);
+               // TODO. we need to describe what inference engines are supported by each Task API,
+               //       and based on it, below inference engine types should be checked
+               //       if a given type is supported by this Task API later. As of now, tflite only.
+               if (backend.second == true && backend.first.compare("tflite") == 0)
+                       _valid_backends.push_back(backend.first);
+       }
+}
+
+template<typename T> void LandmarkDetection<T>::getDeviceList(const string &engine_type)
+{
+       // TODO. add device types available for a given engine type later.
+       //       In default, cpu and gpu only.
+       _valid_devices.push_back("cpu");
+       _valid_devices.push_back("gpu");
+}
+
+template<typename T> void LandmarkDetection<T>::setEngineInfo(string engine_type_name, string device_type_name)
+{
+       if (engine_type_name.empty() || device_type_name.empty())
+               throw InvalidParameter("Invalid engine info.");
+
+       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);
+
+       int engine_type = GetBackendType(engine_type_name);
+       int device_type = GetDeviceType(device_type_name);
+
+       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);
+}
+
+template<typename T> unsigned int LandmarkDetection<T>::getNumberOfEngines()
+{
+       if (!_valid_backends.empty()) {
+               return _valid_backends.size();
+       }
+
+       getEngineList();
+       return _valid_backends.size();
+}
+
+template<typename T> const string &LandmarkDetection<T>::getEngineType(unsigned int engine_index)
+{
+       if (!_valid_backends.empty()) {
+               if (_valid_backends.size() <= engine_index)
+                       throw InvalidParameter("Invalid engine index.");
+
+               return _valid_backends[engine_index];
+       }
+
+       getEngineList();
+
+       if (_valid_backends.size() <= engine_index)
+               throw InvalidParameter("Invalid engine index.");
+
+       return _valid_backends[engine_index];
+}
+
+template<typename T> unsigned int LandmarkDetection<T>::getNumberOfDevices(const string &engine_type)
+{
+       if (!_valid_devices.empty()) {
+               return _valid_devices.size();
+       }
+
+       getDeviceList(engine_type);
+       return _valid_devices.size();
+}
+
+template<typename T>
+const string &LandmarkDetection<T>::getDeviceType(const string &engine_type, const unsigned int device_index)
+{
+       if (!_valid_devices.empty()) {
+               if (_valid_devices.size() <= device_index)
+                       throw InvalidParameter("Invalid device index.");
+
+               return _valid_devices[device_index];
+       }
+
+       getDeviceList(engine_type);
+
+       if (_valid_devices.size() <= device_index)
+               throw InvalidParameter("Invalid device index.");
+
+       return _valid_devices[device_index];
+}
+
+template<typename T> void LandmarkDetection<T>::loadLabel()
+{
+       if (_config->getLabelFilePath().empty())
+               return;
+
+       ifstream readFile;
+
+       _labels.clear();
+       readFile.open(_config->getLabelFilePath().c_str());
+
+       if (readFile.fail())
+               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
+
+       string line;
+
+       while (getline(readFile, line))
+               _labels.push_back(line);
+
+       readFile.close();
+}
+
+template<typename T> void LandmarkDetection<T>::configure()
+{
+       loadLabel();
+
+       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+template<typename T> void LandmarkDetection<T>::prepare()
+{
+       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(_config->getOutputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+       _inference->configureModelFiles("", _config->getModelFilePath(), "");
+
+       // Request to load model files to a backend engine.
+       ret = _inference->load();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to load model files.");
+}
+
+template<typename T> shared_ptr<MetaInfo> LandmarkDetection<T>::getInputMetaInfo()
+{
+       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
+       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
+
+       // TODO. consider using multiple tensors later.
+       if (tensor_info_map.size() != 1)
+               throw InvalidOperation("Input tensor count not invalid.");
+
+       auto tensor_buffer_iter = tensor_info_map.begin();
+
+       // Get the meta information corresponding to a given input tensor name.
+       return _config->getInputMetaMap()[tensor_buffer_iter->first];
+}
+
+template<typename T>
+void LandmarkDetection<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
+{
+       LOGI("ENTER");
+
+       PreprocessConfig config = { false,
+                                                               metaInfo->colorSpace,
+                                                               metaInfo->dataType,
+                                                               metaInfo->getChannel(),
+                                                               metaInfo->getWidth(),
+                                                               metaInfo->getHeight() };
+
+       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
+       if (normalization) {
+               config.normalize = normalization->use;
+               config.mean = normalization->mean;
+               config.std = normalization->std;
+       }
+
+       auto quantization =
+                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
+       if (quantization) {
+               config.quantize = quantization->use;
+               config.scale = quantization->scale;
+               config.zeropoint = quantization->zeropoint;
+       }
+
+       _preprocess.setConfig(config);
+       _preprocess.run<T>(mv_src, inputVector);
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void LandmarkDetection<T>::inference(vector<vector<T> > &inputVectors)
+{
+       LOGI("ENTER");
+
+       int ret = _inference->run<T>(inputVectors);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to run inference");
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void LandmarkDetection<T>::perform(mv_source_h &mv_src)
+{
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(mv_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       inference(inputVectors);
+}
+
+template<typename T> LandmarkDetectionResult &LandmarkDetection<T>::getOutput()
+{
+       if (_async_manager) {
+               if (!_async_manager->isWorking())
+                       throw InvalidOperation("landmark detection has been already destroyed so invalid operation.");
+
+               _current_result = _async_manager->pop();
+       } else {
+               // TODO. Check if inference request is completed or not here.
+               //       If not then throw an exception.
+               _current_result = result();
+       }
+
+       return _current_result;
+}
+
+template<typename T> void LandmarkDetection<T>::performAsync(LandmarkDetectionInput &input)
+{
+       if (!_async_manager) {
+               _async_manager = make_unique<AsyncManager<T, LandmarkDetectionResult> >([this]() {
+                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
+
+                       LOGD("Poped input frame number = %ld", inputQueue.frame_number);
+
+                       inference(inputQueue.inputs);
+
+                       LandmarkDetectionResult &resultQueue = result();
+
+                       resultQueue.frame_number = inputQueue.frame_number;
+                       _async_manager->pushToOutput(resultQueue);
+               });
+       }
+
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(input.inference_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       _async_manager->push(inputVectors);
+}
+
+template<typename T> void LandmarkDetection<T>::getOutputNames(vector<string> &names)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+
+       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
+               names.push_back(it->first);
+}
+
+template<typename T> void LandmarkDetection<T>::getOutputTensor(string target_name, vector<float> &tensor)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+
+       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
+       if (!tensor_buffer)
+               throw InvalidOperation("Fail to get tensor buffer.");
+
+       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
+
+       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
+}
+
+template class LandmarkDetection<float>;
+template class LandmarkDetection<unsigned char>;
+
+}
+}
\ No newline at end of file
index 2321ffa8ac0c4cf0bf9a724438ff1c123f4af248..d47c6eee9609a203228e9a1b45db874c44a1268b 100644 (file)
@@ -15,7 +15,7 @@
  */
 #include <memory>
 
-#include "machine_learning_exception.h"
+#include "MvMlException.h"
 #include "LandmarkDetectionParser.h"
 #include "landmark_detection_type.h"
 
diff --git a/mv_machine_learning/landmark_detection/src/PldCpm.cpp b/mv_machine_learning/landmark_detection/src/PldCpm.cpp
new file mode 100644 (file)
index 0000000..b871490
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * 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 <string.h>
+#include <map>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "mv_landmark_detection_config.h"
+#include "PldCpm.h"
+#include "Postprocess.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+PldCpm<T>::PldCpm(LandmarkDetectionTaskType task_type, std::shared_ptr<Config> config)
+               : LandmarkDetection<T>(task_type, config), _result()
+{}
+
+template<typename T> PldCpm<T>::~PldCpm()
+{}
+
+template<typename T> LandmarkDetectionResult &PldCpm<T>::result()
+{
+       // Clear _result object because result() function can be called every time user wants
+       // so make sure to clear existing result data before getting the data again.
+       _result = LandmarkDetectionResult();
+
+       vector<string> names;
+
+       LandmarkDetection<T>::getOutputNames(names);
+
+       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[0]);
+       auto decodingLandmark =
+                       static_pointer_cast<DecodingLandmark>(scoreMetaInfo->decodingTypeMap[DecodingType::LANDMARK]);
+
+       if (decodingLandmark->decoding_type != LandmarkDecodingType::HEATMAP)
+               throw InvalidOperation("decoding type not support.");
+
+       if (decodingLandmark->coordinate_type != LandmarkCoordinateType::PIXEL)
+               throw InvalidOperation("coordinate type not support.");
+
+       if (decodingLandmark->landmark_type != LandmarkType::SINGLE_2D)
+               throw InvalidOperation("landmark type not support.");
+
+       auto heatMapWidth = scoreMetaInfo->dims[2];
+       auto heatMapHeight = scoreMetaInfo->dims[1];
+       auto heatMapChannel = scoreMetaInfo->dims[3];
+       vector<float> score_tensor;
+
+       _result.number_of_landmarks = heatMapChannel;
+
+       LandmarkDetection<T>::getOutputTensor(names[0], score_tensor);
+
+       auto ori_src_width = static_cast<double>(_preprocess.getImageWidth()[0]);
+       auto ori_src_height = static_cast<double>(_preprocess.getImageHeight()[0]);
+       auto width_ratio = ori_src_width / static_cast<double>(heatMapWidth);
+       auto height_ratio = ori_src_height / static_cast<double>(heatMapHeight);
+
+       for (auto c = 0; c < heatMapChannel; ++c) {
+               float max_score = 0.0f;
+               int max_x = 0;
+               int max_y = 0;
+
+               for (auto y = 0; y < heatMapHeight; ++y) {
+                       for (auto x = 0; x < heatMapWidth; ++x) {
+                               auto score = score_tensor[y * heatMapWidth * heatMapChannel + x * heatMapChannel + c];
+                               if (score < _config->getConfidenceThreshold())
+                                       continue;
+
+                               if (max_score < score) {
+                                       max_score = score;
+                                       max_x = x;
+                                       max_y = y;
+                               }
+                       }
+               }
+
+               if (max_score == 0.0f) {
+                       // If max_score is 0 then it means that all score values of current heatmap is 0 so
+                       // ignore the scores that do not meet the threshold.
+                       _result.number_of_landmarks--;
+                       continue;
+               }
+
+               _result.x_pos.push_back(static_cast<size_t>(static_cast<double>(max_x) * width_ratio));
+               _result.y_pos.push_back(static_cast<size_t>(static_cast<double>(max_y) * height_ratio));
+               _result.scores.push_back(max_score);
+       }
+
+       return _result;
+}
+
+template class PldCpm<unsigned char>;
+template class PldCpm<float>;
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/PoseLandmarkAdapter.cpp b/mv_machine_learning/landmark_detection/src/PoseLandmarkAdapter.cpp
new file mode 100644 (file)
index 0000000..54cfd57
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * 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 "MvMlException.h"
+#include "PoseLandmarkAdapter.h"
+#include "mv_landmark_detection_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
+{
+PoseLandmarkAdapter::PoseLandmarkAdapter()
+{
+       _config = make_shared<Config>();
+       _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+PoseLandmarkAdapter::~PoseLandmarkAdapter()
+{
+       _landmark_detection->preDestroy();
+}
+
+template<typename U> void PoseLandmarkAdapter::create(LandmarkDetectionTaskType task_type)
+{
+       switch (task_type) {
+       case LandmarkDetectionTaskType::PLD_CPM:
+               _landmark_detection = make_unique<PldCpm<U> >(task_type, _config);
+               break;
+       default:
+               throw InvalidOperation("Invalid landmark detection task type.");
+       }
+}
+
+void PoseLandmarkAdapter::create(const string &model_name)
+{
+       LandmarkDetectionTaskType task_type = convertToTaskType(model_name);
+       _config->loadMetaFile(make_unique<LandmarkDetectionParser>(static_cast<int>(task_type)));
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               create<unsigned char>(task_type);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               create<float>(task_type);
+               break;
+       default:
+               throw InvalidOperation("Invalid landmark detection data type.");
+       }
+}
+
+LandmarkDetectionTaskType PoseLandmarkAdapter::convertToTaskType(string 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 == "PLD_CPM")
+               return LandmarkDetectionTaskType::PLD_CPM;
+
+       throw InvalidParameter("Invalid pose landmark model name.");
+}
+
+void PoseLandmarkAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                          const string &model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               create(model_name);
+       } catch (const BaseException &e) {
+               LOGW("A given model name is invalid so default task type will be used.");
+       }
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+}
+
+void PoseLandmarkAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _landmark_detection->setEngineInfo(engine_type, device_type);
+}
+
+void PoseLandmarkAdapter::configure()
+{
+       _landmark_detection->configure();
+}
+
+unsigned int PoseLandmarkAdapter::getNumberOfEngines()
+{
+       return _landmark_detection->getNumberOfEngines();
+}
+
+const string &PoseLandmarkAdapter::getEngineType(unsigned int engine_index)
+{
+       return _landmark_detection->getEngineType(engine_index);
+}
+
+unsigned int PoseLandmarkAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _landmark_detection->getNumberOfDevices(engine_type);
+}
+
+const string &PoseLandmarkAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _landmark_detection->getDeviceType(engine_type, device_index);
+}
+
+void PoseLandmarkAdapter::prepare()
+{
+       _landmark_detection->prepare();
+}
+
+void PoseLandmarkAdapter::perform(InputBaseType &input)
+{
+       _landmark_detection->perform(input.inference_src);
+}
+
+void PoseLandmarkAdapter::performAsync(InputBaseType &input)
+{
+       _landmark_detection->performAsync(static_cast<LandmarkDetectionInput &>(input));
+}
+
+OutputBaseType &PoseLandmarkAdapter::getOutput()
+{
+       return _landmark_detection->getOutput();
+}
+
+OutputBaseType &PoseLandmarkAdapter::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+}
+}
diff --git a/mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp b/mv_machine_learning/landmark_detection/src/facial_landmark_adapter.cpp
deleted file mode 100644 (file)
index d277767..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * 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 "facial_landmark_adapter.h"
-#include "mv_landmark_detection_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
-{
-FacialLandmarkAdapter::FacialLandmarkAdapter()
-{
-       _config = make_shared<MachineLearningConfig>();
-       _config->parseConfigFile(_config_file_name);
-
-       create(_config->getDefaultModelName());
-}
-
-FacialLandmarkAdapter::~FacialLandmarkAdapter()
-{
-       _landmark_detection->preDestroy();
-}
-
-template<typename U> void FacialLandmarkAdapter::create(LandmarkDetectionTaskType task_type)
-{
-       switch (task_type) {
-       case LandmarkDetectionTaskType::FLD_TWEAK_CNN:
-               _landmark_detection = make_unique<FldTweakCnn<U> >(task_type, _config);
-               break;
-       default:
-               throw InvalidOperation("Invalid landmark detection task type.");
-       }
-}
-
-void FacialLandmarkAdapter::create(const string &model_name)
-{
-       LandmarkDetectionTaskType task_type = convertToTaskType(model_name);
-       _config->loadMetaFile(make_unique<LandmarkDetectionParser>(static_cast<int>(task_type)));
-       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
-
-       switch (dataType) {
-       case MV_INFERENCE_DATA_UINT8:
-               create<unsigned char>(task_type);
-               break;
-       case MV_INFERENCE_DATA_FLOAT32:
-               create<float>(task_type);
-               break;
-       default:
-               throw InvalidOperation("Invalid landmark detection data type.");
-       }
-}
-
-LandmarkDetectionTaskType FacialLandmarkAdapter::convertToTaskType(string 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 == "FLD_TWEAK_CNN")
-               return LandmarkDetectionTaskType::FLD_TWEAK_CNN;
-       // TODO.
-
-       throw InvalidParameter("Invalid facial detection model name.");
-}
-
-void FacialLandmarkAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                                const string &model_name)
-{
-       try {
-               _config->setUserModel(model_file, meta_file, label_file);
-               create(model_name);
-       } catch (const BaseException &e) {
-               LOGW("A given model name is invalid so default task type will be used.");
-       }
-
-       if (model_file.empty() && meta_file.empty()) {
-               LOGW("Given model info is invalid so default model info will be used instead.");
-               return;
-       }
-}
-
-void FacialLandmarkAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       _landmark_detection->setEngineInfo(string(engine_type), string(device_type));
-}
-
-void FacialLandmarkAdapter::configure()
-{
-       _landmark_detection->configure();
-}
-
-unsigned int FacialLandmarkAdapter::getNumberOfEngines()
-{
-       return _landmark_detection->getNumberOfEngines();
-}
-
-const string &FacialLandmarkAdapter::getEngineType(unsigned int engine_index)
-{
-       return _landmark_detection->getEngineType(engine_index);
-}
-
-unsigned int FacialLandmarkAdapter::getNumberOfDevices(const string &engine_type)
-{
-       return _landmark_detection->getNumberOfDevices(engine_type);
-}
-
-const string &FacialLandmarkAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _landmark_detection->getDeviceType(engine_type, device_index);
-}
-
-void FacialLandmarkAdapter::prepare()
-{
-       _landmark_detection->prepare();
-}
-
-void FacialLandmarkAdapter::perform(InputBaseType &input)
-{
-       _landmark_detection->perform(input.inference_src);
-}
-
-void FacialLandmarkAdapter::performAsync(InputBaseType &input)
-{
-       _landmark_detection->performAsync(static_cast<LandmarkDetectionInput &>(input));
-}
-
-OutputBaseType &FacialLandmarkAdapter::getOutput()
-{
-       return _landmark_detection->getOutput();
-}
-
-OutputBaseType &FacialLandmarkAdapter::getOutputCache()
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/fld_tweak_cnn.cpp b/mv_machine_learning/landmark_detection/src/fld_tweak_cnn.cpp
deleted file mode 100644 (file)
index 3e2f609..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * 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 <string.h>
-#include <map>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "fld_tweak_cnn.h"
-#include "Postprocess.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-FldTweakCnn<T>::FldTweakCnn(LandmarkDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config)
-               : LandmarkDetection<T>(task_type, config), _result()
-{}
-
-template<typename T> FldTweakCnn<T>::~FldTweakCnn()
-{}
-
-template<typename T> LandmarkDetectionResult &FldTweakCnn<T>::result()
-{
-       constexpr static unsigned int numberOfLandmarks = 5;
-
-       // Clear _result object because result() function can be called every time user wants
-       // so make sure to clear existing result data before getting the data again.
-       _result = LandmarkDetectionResult();
-
-       vector<string> names;
-
-       LandmarkDetection<T>::getOutputNames(names);
-
-       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[0]);
-       auto decodingLandmark =
-                       static_pointer_cast<DecodingLandmark>(scoreMetaInfo->decodingTypeMap[DecodingType::LANDMARK]);
-
-       if (decodingLandmark->decoding_type != LandmarkDecodingType::BYPASS)
-               throw InvalidOperation("decoding type not support.");
-
-       if (decodingLandmark->coordinate_type != LandmarkCoordinateType::RATIO)
-               throw InvalidOperation("coordinate type not support.");
-
-       if (decodingLandmark->landmark_type != LandmarkType::SINGLE_2D)
-               throw InvalidOperation("landmark type not support.");
-
-       auto ori_src_width = static_cast<double>(_preprocess.getImageWidth()[0]);
-       auto ori_src_height = static_cast<double>(_preprocess.getImageHeight()[0]);
-       auto input_tensor_width = static_cast<double>(_inference->getInputWidth());
-       auto input_tensor_height = static_cast<double>(_inference->getInputHeight());
-
-       _result.number_of_landmarks = numberOfLandmarks;
-
-       vector<float> score_tensor;
-
-       LandmarkDetection<T>::getOutputTensor(names[0], score_tensor);
-
-       // Calculate the ratio[A] between the original image size and the input tensor size.
-       double width_ratio = ori_src_width / input_tensor_width;
-       double height_ratio = ori_src_height / input_tensor_height;
-
-       // In case that landmark coordinate type is RATIO, output tensor buffer contains ratio values indicating
-       // the position of each landmark for the input tensor.
-       // Therefore, each landmark position for original image is as following,
-       //    x = [width A] * width of input tensor * width ratio value of output tensor.
-       //    y = [height A] * height of input tensor * height ratio value of output tensor.
-       for (unsigned int idx = 0; idx < numberOfLandmarks; ++idx) {
-               _result.x_pos.push_back(
-                               static_cast<unsigned int>(width_ratio * input_tensor_width * score_tensor[idx + idx * 1]));
-               _result.y_pos.push_back(
-                               static_cast<unsigned int>(height_ratio * input_tensor_height * score_tensor[idx + idx * 1 + 1]));
-       }
-
-       return _result;
-}
-
-template class FldTweakCnn<unsigned char>;
-template class FldTweakCnn<float>;
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/landmark_detection.cpp b/mv_machine_learning/landmark_detection/src/landmark_detection.cpp
deleted file mode 100644 (file)
index a813635..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
- * 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 <string.h>
-#include <fstream>
-#include <map>
-#include <memory>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "mv_machine_learning_common.h"
-#include "landmark_detection.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace MediaVision::Common;
-using namespace mediavision::common;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-LandmarkDetection<T>::LandmarkDetection(LandmarkDetectionTaskType task_type, shared_ptr<MachineLearningConfig> config)
-               : _task_type(task_type), _config(config)
-{
-       _inference = make_unique<Inference>();
-}
-
-template<typename T> void LandmarkDetection<T>::preDestroy()
-{
-       if (!_async_manager)
-               return;
-
-       _async_manager->stop();
-}
-
-template<typename T> LandmarkDetectionTaskType LandmarkDetection<T>::getTaskType()
-{
-       return _task_type;
-}
-
-template<typename T> void LandmarkDetection<T>::getEngineList()
-{
-       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
-               auto backend = _inference->getSupportedInferenceBackend(idx);
-               // TODO. we need to describe what inference engines are supported by each Task API,
-               //       and based on it, below inference engine types should be checked
-               //       if a given type is supported by this Task API later. As of now, tflite only.
-               if (backend.second == true && backend.first.compare("tflite") == 0)
-                       _valid_backends.push_back(backend.first);
-       }
-}
-
-template<typename T> void LandmarkDetection<T>::getDeviceList(const string &engine_type)
-{
-       // TODO. add device types available for a given engine type later.
-       //       In default, cpu and gpu only.
-       _valid_devices.push_back("cpu");
-       _valid_devices.push_back("gpu");
-}
-
-template<typename T> void LandmarkDetection<T>::setEngineInfo(string engine_type_name, string device_type_name)
-{
-       if (engine_type_name.empty() || device_type_name.empty())
-               throw InvalidParameter("Invalid engine info.");
-
-       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);
-
-       int engine_type = GetBackendType(engine_type_name);
-       int device_type = GetDeviceType(device_type_name);
-
-       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);
-}
-
-template<typename T> unsigned int LandmarkDetection<T>::getNumberOfEngines()
-{
-       if (!_valid_backends.empty()) {
-               return _valid_backends.size();
-       }
-
-       getEngineList();
-       return _valid_backends.size();
-}
-
-template<typename T> const string &LandmarkDetection<T>::getEngineType(unsigned int engine_index)
-{
-       if (!_valid_backends.empty()) {
-               if (_valid_backends.size() <= engine_index)
-                       throw InvalidParameter("Invalid engine index.");
-
-               return _valid_backends[engine_index];
-       }
-
-       getEngineList();
-
-       if (_valid_backends.size() <= engine_index)
-               throw InvalidParameter("Invalid engine index.");
-
-       return _valid_backends[engine_index];
-}
-
-template<typename T> unsigned int LandmarkDetection<T>::getNumberOfDevices(const string &engine_type)
-{
-       if (!_valid_devices.empty()) {
-               return _valid_devices.size();
-       }
-
-       getDeviceList(engine_type);
-       return _valid_devices.size();
-}
-
-template<typename T>
-const string &LandmarkDetection<T>::getDeviceType(const string &engine_type, const unsigned int device_index)
-{
-       if (!_valid_devices.empty()) {
-               if (_valid_devices.size() <= device_index)
-                       throw InvalidParameter("Invalid device index.");
-
-               return _valid_devices[device_index];
-       }
-
-       getDeviceList(engine_type);
-
-       if (_valid_devices.size() <= device_index)
-               throw InvalidParameter("Invalid device index.");
-
-       return _valid_devices[device_index];
-}
-
-template<typename T> void LandmarkDetection<T>::loadLabel()
-{
-       if (_config->getLabelFilePath().empty())
-               return;
-
-       ifstream readFile;
-
-       _labels.clear();
-       readFile.open(_config->getLabelFilePath().c_str());
-
-       if (readFile.fail())
-               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
-
-       string line;
-
-       while (getline(readFile, line))
-               _labels.push_back(line);
-
-       readFile.close();
-}
-
-template<typename T> void LandmarkDetection<T>::configure()
-{
-       loadLabel();
-
-       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to bind a backend engine.");
-}
-
-template<typename T> void LandmarkDetection<T>::prepare()
-{
-       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(_config->getOutputMetaMap());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to configure output tensor info from meta file.");
-
-       _inference->configureModelFiles("", _config->getModelFilePath(), "");
-
-       // Request to load model files to a backend engine.
-       ret = _inference->load();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to load model files.");
-}
-
-template<typename T> shared_ptr<MetaInfo> LandmarkDetection<T>::getInputMetaInfo()
-{
-       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
-       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
-
-       // TODO. consider using multiple tensors later.
-       if (tensor_info_map.size() != 1)
-               throw InvalidOperation("Input tensor count not invalid.");
-
-       auto tensor_buffer_iter = tensor_info_map.begin();
-
-       // Get the meta information corresponding to a given input tensor name.
-       return _config->getInputMetaMap()[tensor_buffer_iter->first];
-}
-
-template<typename T>
-void LandmarkDetection<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
-{
-       LOGI("ENTER");
-
-       PreprocessConfig config = { false,
-                                                               metaInfo->colorSpace,
-                                                               metaInfo->dataType,
-                                                               metaInfo->getChannel(),
-                                                               metaInfo->getWidth(),
-                                                               metaInfo->getHeight() };
-
-       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
-       if (normalization) {
-               config.normalize = normalization->use;
-               config.mean = normalization->mean;
-               config.std = normalization->std;
-       }
-
-       auto quantization =
-                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
-       if (quantization) {
-               config.quantize = quantization->use;
-               config.scale = quantization->scale;
-               config.zeropoint = quantization->zeropoint;
-       }
-
-       _preprocess.setConfig(config);
-       _preprocess.run<T>(mv_src, inputVector);
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void LandmarkDetection<T>::inference(vector<vector<T> > &inputVectors)
-{
-       LOGI("ENTER");
-
-       int ret = _inference->run<T>(inputVectors);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to run inference");
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void LandmarkDetection<T>::perform(mv_source_h &mv_src)
-{
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(mv_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       inference(inputVectors);
-}
-
-template<typename T> LandmarkDetectionResult &LandmarkDetection<T>::getOutput()
-{
-       if (_async_manager) {
-               if (!_async_manager->isWorking())
-                       throw InvalidOperation("landmark detection has been already destroyed so invalid operation.");
-
-               _current_result = _async_manager->pop();
-       } else {
-               // TODO. Check if inference request is completed or not here.
-               //       If not then throw an exception.
-               _current_result = result();
-       }
-
-       return _current_result;
-}
-
-template<typename T> void LandmarkDetection<T>::performAsync(LandmarkDetectionInput &input)
-{
-       if (!_async_manager) {
-               _async_manager = make_unique<AsyncManager<T, LandmarkDetectionResult> >([this]() {
-                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
-
-                       LOGD("Poped input frame number = %ld", inputQueue.frame_number);
-
-                       inference(inputQueue.inputs);
-
-                       LandmarkDetectionResult &resultQueue = result();
-
-                       resultQueue.frame_number = inputQueue.frame_number;
-                       _async_manager->pushToOutput(resultQueue);
-               });
-       }
-
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(input.inference_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       _async_manager->push(inputVectors);
-}
-
-template<typename T> void LandmarkDetection<T>::getOutputNames(vector<string> &names)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
-
-       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
-               names.push_back(it->first);
-}
-
-template<typename T> void LandmarkDetection<T>::getOutputTensor(string target_name, vector<float> &tensor)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-
-       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
-       if (!tensor_buffer)
-               throw InvalidOperation("Fail to get tensor buffer.");
-
-       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
-
-       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
-}
-
-template class LandmarkDetection<float>;
-template class LandmarkDetection<unsigned char>;
-
-}
-}
\ No newline at end of file
index 40d2ae4b50399d159022ad46db0419702ee64790..f98d2a6095983855b983e99531b59fa7bc14f3c9 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "itask.h"
+#include "ITask.h"
 #include "mv_facial_landmark_internal.h"
-#include "facial_landmark_adapter.h"
-#include "machine_learning_exception.h"
-#include "MachineLearningNative.h"
+#include "FacialLandmarkAdapter.h"
+#include "MvMlException.h"
+#include "native_capi.h"
 #include "landmark_detection_type.h"
-#include "context.h"
+#include "Context.h"
 
 #include <new>
 #include <unistd.h>
index 09dc5eddf270b0f201af5ab8d6580edb4ed7e76b..8abf04c4333e466429709854c8bda699a2ff9f95 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "itask.h"
+#include "ITask.h"
 #include "mv_pose_landmark_internal.h"
-#include "pose_landmark_adapter.h"
-#include "machine_learning_exception.h"
-#include "MachineLearningNative.h"
+#include "PoseLandmarkAdapter.h"
+#include "MvMlException.h"
+#include "native_capi.h"
 #include "landmark_detection_type.h"
-#include "context.h"
+#include "Context.h"
 
 #include <new>
 #include <unistd.h>
diff --git a/mv_machine_learning/landmark_detection/src/pld_cpm.cpp b/mv_machine_learning/landmark_detection/src/pld_cpm.cpp
deleted file mode 100644 (file)
index 47addda..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * 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 <string.h>
-#include <map>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "mv_landmark_detection_config.h"
-#include "pld_cpm.h"
-#include "Postprocess.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-PldCpm<T>::PldCpm(LandmarkDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config)
-               : LandmarkDetection<T>(task_type, config), _result()
-{}
-
-template<typename T> PldCpm<T>::~PldCpm()
-{}
-
-template<typename T> LandmarkDetectionResult &PldCpm<T>::result()
-{
-       // Clear _result object because result() function can be called every time user wants
-       // so make sure to clear existing result data before getting the data again.
-       _result = LandmarkDetectionResult();
-
-       vector<string> names;
-
-       LandmarkDetection<T>::getOutputNames(names);
-
-       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[0]);
-       auto decodingLandmark =
-                       static_pointer_cast<DecodingLandmark>(scoreMetaInfo->decodingTypeMap[DecodingType::LANDMARK]);
-
-       if (decodingLandmark->decoding_type != LandmarkDecodingType::HEATMAP)
-               throw InvalidOperation("decoding type not support.");
-
-       if (decodingLandmark->coordinate_type != LandmarkCoordinateType::PIXEL)
-               throw InvalidOperation("coordinate type not support.");
-
-       if (decodingLandmark->landmark_type != LandmarkType::SINGLE_2D)
-               throw InvalidOperation("landmark type not support.");
-
-       auto heatMapWidth = scoreMetaInfo->dims[2];
-       auto heatMapHeight = scoreMetaInfo->dims[1];
-       auto heatMapChannel = scoreMetaInfo->dims[3];
-       vector<float> score_tensor;
-
-       _result.number_of_landmarks = heatMapChannel;
-
-       LandmarkDetection<T>::getOutputTensor(names[0], score_tensor);
-
-       auto ori_src_width = static_cast<double>(_preprocess.getImageWidth()[0]);
-       auto ori_src_height = static_cast<double>(_preprocess.getImageHeight()[0]);
-       auto width_ratio = ori_src_width / static_cast<double>(heatMapWidth);
-       auto height_ratio = ori_src_height / static_cast<double>(heatMapHeight);
-
-       for (auto c = 0; c < heatMapChannel; ++c) {
-               float max_score = 0.0f;
-               int max_x = 0;
-               int max_y = 0;
-
-               for (auto y = 0; y < heatMapHeight; ++y) {
-                       for (auto x = 0; x < heatMapWidth; ++x) {
-                               auto score = score_tensor[y * heatMapWidth * heatMapChannel + x * heatMapChannel + c];
-                               if (score < _config->getConfidenceThreshold())
-                                       continue;
-
-                               if (max_score < score) {
-                                       max_score = score;
-                                       max_x = x;
-                                       max_y = y;
-                               }
-                       }
-               }
-
-               if (max_score == 0.0f) {
-                       // If max_score is 0 then it means that all score values of current heatmap is 0 so
-                       // ignore the scores that do not meet the threshold.
-                       _result.number_of_landmarks--;
-                       continue;
-               }
-
-               _result.x_pos.push_back(static_cast<size_t>(static_cast<double>(max_x) * width_ratio));
-               _result.y_pos.push_back(static_cast<size_t>(static_cast<double>(max_y) * height_ratio));
-               _result.scores.push_back(max_score);
-       }
-
-       return _result;
-}
-
-template class PldCpm<unsigned char>;
-template class PldCpm<float>;
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp b/mv_machine_learning/landmark_detection/src/pose_landmark_adapter.cpp
deleted file mode 100644 (file)
index d7d9922..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * 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 "pose_landmark_adapter.h"
-#include "mv_landmark_detection_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
-{
-PoseLandmarkAdapter::PoseLandmarkAdapter()
-{
-       _config = make_shared<MachineLearningConfig>();
-       _config->parseConfigFile(_config_file_name);
-
-       create(_config->getDefaultModelName());
-}
-
-PoseLandmarkAdapter::~PoseLandmarkAdapter()
-{
-       _landmark_detection->preDestroy();
-}
-
-template<typename U> void PoseLandmarkAdapter::create(LandmarkDetectionTaskType task_type)
-{
-       switch (task_type) {
-       case LandmarkDetectionTaskType::PLD_CPM:
-               _landmark_detection = make_unique<PldCpm<U> >(task_type, _config);
-               break;
-       default:
-               throw InvalidOperation("Invalid landmark detection task type.");
-       }
-}
-
-void PoseLandmarkAdapter::create(const string &model_name)
-{
-       LandmarkDetectionTaskType task_type = convertToTaskType(model_name);
-       _config->loadMetaFile(make_unique<LandmarkDetectionParser>(static_cast<int>(task_type)));
-       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
-
-       switch (dataType) {
-       case MV_INFERENCE_DATA_UINT8:
-               create<unsigned char>(task_type);
-               break;
-       case MV_INFERENCE_DATA_FLOAT32:
-               create<float>(task_type);
-               break;
-       default:
-               throw InvalidOperation("Invalid landmark detection data type.");
-       }
-}
-
-LandmarkDetectionTaskType PoseLandmarkAdapter::convertToTaskType(string 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 == "PLD_CPM")
-               return LandmarkDetectionTaskType::PLD_CPM;
-
-       throw InvalidParameter("Invalid pose landmark model name.");
-}
-
-void PoseLandmarkAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                          const string &model_name)
-{
-       try {
-               _config->setUserModel(model_file, meta_file, label_file);
-               create(model_name);
-       } catch (const BaseException &e) {
-               LOGW("A given model name is invalid so default task type will be used.");
-       }
-
-       if (model_file.empty() && meta_file.empty()) {
-               LOGW("Given model info is invalid so default model info will be used instead.");
-               return;
-       }
-}
-
-void PoseLandmarkAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       _landmark_detection->setEngineInfo(engine_type, device_type);
-}
-
-void PoseLandmarkAdapter::configure()
-{
-       _landmark_detection->configure();
-}
-
-unsigned int PoseLandmarkAdapter::getNumberOfEngines()
-{
-       return _landmark_detection->getNumberOfEngines();
-}
-
-const string &PoseLandmarkAdapter::getEngineType(unsigned int engine_index)
-{
-       return _landmark_detection->getEngineType(engine_index);
-}
-
-unsigned int PoseLandmarkAdapter::getNumberOfDevices(const string &engine_type)
-{
-       return _landmark_detection->getNumberOfDevices(engine_type);
-}
-
-const string &PoseLandmarkAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _landmark_detection->getDeviceType(engine_type, device_index);
-}
-
-void PoseLandmarkAdapter::prepare()
-{
-       _landmark_detection->prepare();
-}
-
-void PoseLandmarkAdapter::perform(InputBaseType &input)
-{
-       _landmark_detection->perform(input.inference_src);
-}
-
-void PoseLandmarkAdapter::performAsync(InputBaseType &input)
-{
-       _landmark_detection->performAsync(static_cast<LandmarkDetectionInput &>(input));
-}
-
-OutputBaseType &PoseLandmarkAdapter::getOutput()
-{
-       return _landmark_detection->getOutput();
-}
-
-OutputBaseType &PoseLandmarkAdapter::getOutputCache()
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-}
-}
index 96a95a25a563370e98572395ff8e37b75fe95f29..121791ca55cae7200047d6658454b849d8a67630 100644 (file)
@@ -25,6 +25,6 @@ install(
 install(
        DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include/media
        FILES_MATCHING
-       PATTERN "iobject_detection.h"
+       PATTERN "IObjectDetection.h"
        PATTERN "object_detection_type.h"
        )
diff --git a/mv_machine_learning/object_detection/include/FaceDetectionAdapter.h b/mv_machine_learning/object_detection/include/FaceDetectionAdapter.h
new file mode 100644 (file)
index 0000000..2ebb7a8
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * 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 __FACE_DETECTION_ADAPTER_H__
+#define __FACE_DETECTION_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "MvMlConfig.h"
+#include "MobilenetV1Ssd.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FaceDetectionAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<IObjectDetection> _object_detection;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "face_detection.json";
+       const std::string _plugin_config_file_name = "face_detection_plugin.json";
+
+       void create(std::string model_name = "");
+       template<typename U> void create(ObjectDetectionTaskType task_type);
+       ObjectDetectionTaskType convertToTaskType(std::string model_name);
+
+public:
+       FaceDetectionAdapter();
+       ~FaceDetectionAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/IObjectDetection.h b/mv_machine_learning/object_detection/include/IObjectDetection.h
new file mode 100644 (file)
index 0000000..5a64ad1
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 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 __IOBJECT_DETECTION_H__
+#define __IOBJECT_DETECTION_H__
+
+#include <mv_common.h>
+
+#include "object_detection_type.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class IObjectDetection
+{
+public:
+       virtual ~IObjectDetection() {};
+
+       virtual void preDestroy() = 0;
+       virtual ObjectDetectionTaskType getTaskType() = 0;
+       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
+       virtual unsigned int getNumberOfEngines() = 0;
+       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
+       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
+       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
+       virtual void configure() = 0;
+       virtual void prepare() = 0;
+       virtual void perform(mv_source_h &mv_src) = 0;
+       virtual void performAsync(ObjectDetectionInput &input) = 0;
+       virtual ObjectDetectionResult &getOutput() = 0;
+       virtual ObjectDetectionResult &getOutputCache() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/MobilenetV1Ssd.h b/mv_machine_learning/object_detection/include/MobilenetV1Ssd.h
new file mode 100644 (file)
index 0000000..e8e9d38
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 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 __MOBILENET_V1_SSD_H__
+#define __MOBILENET_V1_SSD_H__
+
+#include <string>
+#include <memory>
+#include <mv_common.h>
+#include "mv_private.h"
+
+#include "ObjectDetection.h"
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class MobilenetV1Ssd : public ObjectDetection<T>
+{
+       using ObjectDetection<T>::_config;
+       using ObjectDetection<T>::_preprocess;
+       using ObjectDetection<T>::_labels;
+
+private:
+       ObjectDetectionResult _result;
+
+public:
+       MobilenetV1Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<Config> config);
+       ~MobilenetV1Ssd();
+
+       ObjectDetectionResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/MobilenetV2Ssd.h b/mv_machine_learning/object_detection/include/MobilenetV2Ssd.h
new file mode 100644 (file)
index 0000000..1f6f789
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * 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 __MOBILENET_V2_SSD_H__
+#define __MOBILENET_V2_SSD_H__
+
+#include <string>
+#include <memory>
+#include <mv_common.h>
+#include "mv_private.h"
+
+#include "ObjectDetection.h"
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class MobilenetV2Ssd : public ObjectDetection<T>
+{
+       using ObjectDetection<T>::_config;
+       using ObjectDetection<T>::_preprocess;
+       using ObjectDetection<T>::_labels;
+
+private:
+       ObjectDetectionResult _result;
+
+       void ApplyNms(std::vector<std::vector<Box> > &box_lists, BoxNmsMode mode, float threshold,
+                                 std::vector<Box> &box_vector);
+       Box decodeBox(const DecodingBox *decodingBox, std::vector<float> &bb_tensor, int idx, float score, int label,
+                                 int box_offset);
+       Box decodeBoxWithAnchor(const BoxAnchorParam *boxAnchorParam, Box &box, cv::Rect2f &anchor);
+
+public:
+       MobilenetV2Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<Config> config);
+       ~MobilenetV2Ssd();
+
+       ObjectDetectionResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/ObjectDetection.h b/mv_machine_learning/object_detection/include/ObjectDetection.h
new file mode 100644 (file)
index 0000000..03bce20
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * 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 __OBJECT_DETECTION_H__
+#define __OBJECT_DETECTION_H__
+
+#include <queue>
+#include <thread>
+#include <mutex>
+#include <atomic>
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+#include "mv_private.h"
+
+#include "EngineConfig.h"
+#include "inference_engine_common_impl.h"
+#include "Inference.h"
+#include "object_detection_type.h"
+#include "MetaParser.h"
+#include "ObjectDetectionParser.h"
+#include "MvMlConfig.h"
+#include "MvMlPreprocess.h"
+#include "IObjectDetection.h"
+#include "AsyncManager.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class ObjectDetection : public IObjectDetection
+{
+private:
+       ObjectDetectionTaskType _task_type { ObjectDetectionTaskType::OBJECT_DETECTION_TASK_NONE };
+       std::unique_ptr<AsyncManager<T, ObjectDetectionResult> > _async_manager;
+       ObjectDetectionResult _current_result;
+
+       void loadLabel();
+       void getEngineList();
+       void getDeviceList(const std::string &engine_type);
+       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
+       std::shared_ptr<MetaInfo> getInputMetaInfo();
+
+protected:
+       std::unique_ptr<mediavision::inference::Inference> _inference;
+       std::shared_ptr<Config> _config;
+       std::vector<std::string> _labels;
+       std::vector<std::string> _valid_backends;
+       std::vector<std::string> _valid_devices;
+       Preprocess _preprocess;
+
+       void getOutputNames(std::vector<std::string> &names);
+       void getOutputTensor(std::string target_name, std::vector<float> &tensor);
+       void inference(std::vector<std::vector<T> > &inputVectors);
+       virtual ObjectDetectionResult &result() = 0;
+
+public:
+       explicit ObjectDetection(ObjectDetectionTaskType task_type, std::shared_ptr<Config> config);
+       virtual ~ObjectDetection() = default;
+
+       void preDestroy() override;
+       ObjectDetectionTaskType getTaskType() override;
+       void setUserModel(std::string model_file, std::string meta_file, std::string label_file);
+       void setEngineInfo(std::string engine_type_name, std::string device_type_name) override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void configure() override;
+       void prepare() override;
+       void perform(mv_source_h &mv_src) override;
+       void performAsync(ObjectDetectionInput &input) override;
+       ObjectDetectionResult &getOutput() override;
+       ObjectDetectionResult &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/ObjectDetectionAdapter.h b/mv_machine_learning/object_detection/include/ObjectDetectionAdapter.h
new file mode 100644 (file)
index 0000000..098964e
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * 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 __OBJECT_DETECTION_ADAPTER_H__
+#define __OBJECT_DETECTION_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "MvMlConfig.h"
+#include "MobilenetV1Ssd.h"
+#include "MobilenetV2Ssd.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ObjectDetectionAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<IObjectDetection> _object_detection;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "object_detection.json";
+       const std::string _plugin_config_file_name = "object_detection_plugin.json";
+
+       void create(std::string model_name = "");
+       template<typename U> void create(ObjectDetectionTaskType task_type);
+       ObjectDetectionTaskType convertToTaskType(std::string model_name);
+
+public:
+       ObjectDetectionAdapter();
+       ~ObjectDetectionAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       void configure() override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/ObjectDetectionExternal.h b/mv_machine_learning/object_detection/include/ObjectDetectionExternal.h
new file mode 100644 (file)
index 0000000..e82f0bb
--- /dev/null
@@ -0,0 +1,63 @@
+/**
+ * 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 "IObjectDetection.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ObjectDetectionExternal : public IObjectDetection
+{
+private:
+       void *_plugin_handle {};
+       IObjectDetection *_object_detection_plugin {};
+       ObjectDetectionTaskType _task_type { ObjectDetectionTaskType::OBJECT_DETECTION_TASK_NONE };
+       ObjectDetectionResult _current_result;
+
+public:
+       ObjectDetectionExternal(ObjectDetectionTaskType task_type, const std::string &plugin_name);
+       virtual ~ObjectDetectionExternal();
+
+       void preDestroy() override;
+       ObjectDetectionTaskType getTaskType() override;
+       void setEngineInfo(std::string engine_type, std::string device_type) override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) override;
+       void configure() override;
+       void prepare() override;
+       void perform(mv_source_h &mv_src) override;
+       void performAsync(ObjectDetectionInput &input) override;
+       ObjectDetectionResult &getOutput() override;
+       ObjectDetectionResult &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/face_detection_adapter.h b/mv_machine_learning/object_detection/include/face_detection_adapter.h
deleted file mode 100644 (file)
index ae4cb68..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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 __FACE_DETECTION_ADAPTER_H__
-#define __FACE_DETECTION_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "machine_learning_config.h"
-#include "mobilenet_v1_ssd.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class FaceDetectionAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<IObjectDetection> _object_detection;
-       std::shared_ptr<MachineLearningConfig> _config;
-       const std::string _config_file_name = "face_detection.json";
-       const std::string _plugin_config_file_name = "face_detection_plugin.json";
-
-       void create(std::string model_name = "");
-       template<typename U> void create(ObjectDetectionTaskType task_type);
-       ObjectDetectionTaskType convertToTaskType(std::string model_name);
-
-public:
-       FaceDetectionAdapter();
-       ~FaceDetectionAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/iobject_detection.h b/mv_machine_learning/object_detection/include/iobject_detection.h
deleted file mode 100644 (file)
index 5a64ad1..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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 __IOBJECT_DETECTION_H__
-#define __IOBJECT_DETECTION_H__
-
-#include <mv_common.h>
-
-#include "object_detection_type.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class IObjectDetection
-{
-public:
-       virtual ~IObjectDetection() {};
-
-       virtual void preDestroy() = 0;
-       virtual ObjectDetectionTaskType getTaskType() = 0;
-       virtual void setEngineInfo(std::string engine_type, std::string device_type) = 0;
-       virtual unsigned int getNumberOfEngines() = 0;
-       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
-       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
-       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
-       virtual void configure() = 0;
-       virtual void prepare() = 0;
-       virtual void perform(mv_source_h &mv_src) = 0;
-       virtual void performAsync(ObjectDetectionInput &input) = 0;
-       virtual ObjectDetectionResult &getOutput() = 0;
-       virtual ObjectDetectionResult &getOutputCache() = 0;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/mobilenet_v1_ssd.h b/mv_machine_learning/object_detection/include/mobilenet_v1_ssd.h
deleted file mode 100644 (file)
index bb309bf..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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 __MOBILENET_V1_SSD_H__
-#define __MOBILENET_V1_SSD_H__
-
-#include <string>
-#include <memory>
-#include <mv_common.h>
-#include "mv_private.h"
-
-#include "object_detection.h"
-#include <mv_inference_type.h>
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class MobilenetV1Ssd : public ObjectDetection<T>
-{
-       using ObjectDetection<T>::_config;
-       using ObjectDetection<T>::_preprocess;
-       using ObjectDetection<T>::_labels;
-
-private:
-       ObjectDetectionResult _result;
-
-public:
-       MobilenetV1Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       ~MobilenetV1Ssd();
-
-       ObjectDetectionResult &result() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/mobilenet_v2_ssd.h b/mv_machine_learning/object_detection/include/mobilenet_v2_ssd.h
deleted file mode 100644 (file)
index c598c43..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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 __MOBILENET_V2_SSD_H__
-#define __MOBILENET_V2_SSD_H__
-
-#include <string>
-#include <memory>
-#include <mv_common.h>
-#include "mv_private.h"
-
-#include "object_detection.h"
-#include <mv_inference_type.h>
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class MobilenetV2Ssd : public ObjectDetection<T>
-{
-       using ObjectDetection<T>::_config;
-       using ObjectDetection<T>::_preprocess;
-       using ObjectDetection<T>::_labels;
-
-private:
-       ObjectDetectionResult _result;
-
-       void ApplyNms(std::vector<std::vector<Box> > &box_lists, BoxNmsMode mode, float threshold,
-                                 std::vector<Box> &box_vector);
-       Box decodeBox(const DecodingBox *decodingBox, std::vector<float> &bb_tensor, int idx, float score, int label,
-                                 int box_offset);
-       Box decodeBoxWithAnchor(const BoxAnchorParam *boxAnchorParam, Box &box, cv::Rect2f &anchor);
-
-public:
-       MobilenetV2Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       ~MobilenetV2Ssd();
-
-       ObjectDetectionResult &result() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/object_detection.h b/mv_machine_learning/object_detection/include/object_detection.h
deleted file mode 100644 (file)
index a839ad2..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * 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 __OBJECT_DETECTION_H__
-#define __OBJECT_DETECTION_H__
-
-#include <queue>
-#include <thread>
-#include <mutex>
-#include <atomic>
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-#include "mv_private.h"
-
-#include "EngineConfig.h"
-#include "inference_engine_common_impl.h"
-#include "Inference.h"
-#include "object_detection_type.h"
-#include "MetaParser.h"
-#include "ObjectDetectionParser.h"
-#include "machine_learning_config.h"
-#include "machine_learning_preprocess.h"
-#include "iobject_detection.h"
-#include "async_manager.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class ObjectDetection : public IObjectDetection
-{
-private:
-       ObjectDetectionTaskType _task_type { ObjectDetectionTaskType::OBJECT_DETECTION_TASK_NONE };
-       std::unique_ptr<AsyncManager<T, ObjectDetectionResult> > _async_manager;
-       ObjectDetectionResult _current_result;
-
-       void loadLabel();
-       void getEngineList();
-       void getDeviceList(const std::string &engine_type);
-       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
-       std::shared_ptr<MetaInfo> getInputMetaInfo();
-
-protected:
-       std::unique_ptr<mediavision::inference::Inference> _inference;
-       std::shared_ptr<MachineLearningConfig> _config;
-       std::vector<std::string> _labels;
-       std::vector<std::string> _valid_backends;
-       std::vector<std::string> _valid_devices;
-       Preprocess _preprocess;
-
-       void getOutputNames(std::vector<std::string> &names);
-       void getOutputTensor(std::string target_name, std::vector<float> &tensor);
-       void inference(std::vector<std::vector<T> > &inputVectors);
-       virtual ObjectDetectionResult &result() = 0;
-
-public:
-       explicit ObjectDetection(ObjectDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       virtual ~ObjectDetection() = default;
-
-       void preDestroy() override;
-       ObjectDetectionTaskType getTaskType() override;
-       void setUserModel(std::string model_file, std::string meta_file, std::string label_file);
-       void setEngineInfo(std::string engine_type_name, std::string device_type_name) override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void configure() override;
-       void prepare() override;
-       void perform(mv_source_h &mv_src) override;
-       void performAsync(ObjectDetectionInput &input) override;
-       ObjectDetectionResult &getOutput() override;
-       ObjectDetectionResult &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/object_detection_adapter.h b/mv_machine_learning/object_detection/include/object_detection_adapter.h
deleted file mode 100644 (file)
index bec6c56..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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 __OBJECT_DETECTION_ADAPTER_H__
-#define __OBJECT_DETECTION_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "machine_learning_config.h"
-#include "mobilenet_v1_ssd.h"
-#include "mobilenet_v2_ssd.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class ObjectDetectionAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<IObjectDetection> _object_detection;
-       std::shared_ptr<MachineLearningConfig> _config;
-       const std::string _config_file_name = "object_detection.json";
-       const std::string _plugin_config_file_name = "object_detection_plugin.json";
-
-       void create(std::string model_name = "");
-       template<typename U> void create(ObjectDetectionTaskType task_type);
-       ObjectDetectionTaskType convertToTaskType(std::string model_name);
-
-public:
-       ObjectDetectionAdapter();
-       ~ObjectDetectionAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       void configure() override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/object_detection_external.h b/mv_machine_learning/object_detection/include/object_detection_external.h
deleted file mode 100644 (file)
index ff63117..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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 { ObjectDetectionTaskType::OBJECT_DETECTION_TASK_NONE };
-       ObjectDetectionResult _current_result;
-
-public:
-       ObjectDetectionExternal(ObjectDetectionTaskType task_type, const std::string &plugin_name);
-       virtual ~ObjectDetectionExternal();
-
-       void preDestroy() override;
-       ObjectDetectionTaskType getTaskType() override;
-       void setEngineInfo(std::string engine_type, std::string device_type) override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, const unsigned int device_index) override;
-       void configure() override;
-       void prepare() override;
-       void perform(mv_source_h &mv_src) override;
-       void performAsync(ObjectDetectionInput &input) override;
-       ObjectDetectionResult &getOutput() override;
-       ObjectDetectionResult &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
index 467374b56c600c0b6230827a608654e0bafcfd5e..b5e3b944a795db92323dd611930504a4d63140ca 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <mv_common.h>
 #include <mv_inference_type.h>
-#include "MachineLearningType.h"
+#include "mv_ml_types.h"
 
 namespace mediavision
 {
diff --git a/mv_machine_learning/object_detection/src/FaceDetectionAdapter.cpp b/mv_machine_learning/object_detection/src/FaceDetectionAdapter.cpp
new file mode 100644 (file)
index 0000000..3018844
--- /dev/null
@@ -0,0 +1,180 @@
+/**
+ * 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 "MvMlException.h"
+#include "FaceDetectionAdapter.h"
+#include "ObjectDetectionExternal.h"
+#include "mv_object_detection_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
+{
+FaceDetectionAdapter::FaceDetectionAdapter()
+{
+       _config = make_shared<Config>();
+
+       // If the model type needs external plugin then bypass to load the meta file and just create the external plugin.
+       // In this case, external plugin will use its own meta file approach regardless of Mediavision's one.
+       _config->parsePluginConfigFile(_plugin_config_file_name);
+       if (!_config->isPluginUsed())
+               _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+FaceDetectionAdapter::~FaceDetectionAdapter()
+{
+       _object_detection->preDestroy();
+}
+
+template<typename U> void FaceDetectionAdapter::create(ObjectDetectionTaskType task_type)
+{
+       switch (task_type) {
+       case ObjectDetectionTaskType::FD_MOBILENET_V1_SSD:
+               _object_detection = make_unique<MobilenetV1Ssd<U> >(task_type, _config);
+               break;
+       default:
+               throw InvalidOperation("Invalid face detection task type.");
+       }
+       // TODO.
+}
+
+void FaceDetectionAdapter::create(string model_name)
+{
+       if (model_name.empty())
+               model_name = _config->getDefaultModelName();
+
+       auto task_type = convertToTaskType(model_name);
+
+       if (_config->isPluginUsed()) {
+               const auto &plugin_name = _config->getPluginFileName();
+
+               _object_detection = make_unique<ObjectDetectionExternal>(task_type, plugin_name.c_str());
+               return;
+       }
+
+       _config->loadMetaFile(make_unique<ObjectDetectionParser>(static_cast<int>(task_type)));
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               create<unsigned char>(task_type);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               create<float>(task_type);
+               break;
+       default:
+               throw InvalidOperation("Invalid face detection data type.");
+       }
+}
+
+ObjectDetectionTaskType FaceDetectionAdapter::convertToTaskType(string 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 == "FD_MOBILENET_V1_SSD")
+               return ObjectDetectionTaskType::FD_MOBILENET_V1_SSD;
+       if (model_name == "OD_TRIV2")
+               return ObjectDetectionTaskType::OD_TRIV2;
+       else if (model_name == "FD_TRIV2")
+               return ObjectDetectionTaskType::FD_TRIV2;
+       // TODO.
+
+       throw InvalidParameter("Invalid face detection model name.");
+}
+
+void FaceDetectionAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                               const string &model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               create(model_name);
+       } catch (const BaseException &e) {
+               LOGW("A given model name is invalid so default task type will be used.");
+       }
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+}
+
+void FaceDetectionAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _object_detection->setEngineInfo(string(engine_type), string(device_type));
+}
+
+void FaceDetectionAdapter::configure()
+{
+       _object_detection->configure();
+}
+
+unsigned int FaceDetectionAdapter::getNumberOfEngines()
+{
+       return _object_detection->getNumberOfEngines();
+}
+
+const string &FaceDetectionAdapter::getEngineType(unsigned int engine_index)
+{
+       return _object_detection->getEngineType(engine_index);
+}
+
+unsigned int FaceDetectionAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _object_detection->getNumberOfDevices(engine_type);
+}
+
+const string &FaceDetectionAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _object_detection->getDeviceType(engine_type, device_index);
+}
+
+void FaceDetectionAdapter::prepare()
+{
+       _object_detection->prepare();
+}
+
+void FaceDetectionAdapter::perform(InputBaseType &input)
+{
+       _object_detection->perform(input.inference_src);
+}
+
+void FaceDetectionAdapter::performAsync(InputBaseType &input)
+{
+       _object_detection->performAsync(static_cast<ObjectDetectionInput &>(input));
+}
+
+OutputBaseType &FaceDetectionAdapter::getOutput()
+{
+       return _object_detection->getOutput();
+}
+
+OutputBaseType &FaceDetectionAdapter::getOutputCache()
+{
+       return _object_detection->getOutputCache();
+}
+
+}
+}
diff --git a/mv_machine_learning/object_detection/src/MobilenetV1Ssd.cpp b/mv_machine_learning/object_detection/src/MobilenetV1Ssd.cpp
new file mode 100644 (file)
index 0000000..cb3c7ef
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * 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 <string.h>
+#include <map>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "mv_object_detection_config.h"
+#include "MobilenetV1Ssd.h"
+#include "Postprocess.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+MobilenetV1Ssd<T>::MobilenetV1Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<Config> config)
+               : ObjectDetection<T>(task_type, config), _result()
+{}
+
+template<typename T> MobilenetV1Ssd<T>::~MobilenetV1Ssd()
+{}
+
+template<typename T> ObjectDetectionResult &MobilenetV1Ssd<T>::result()
+{
+       // Clear _result object because result() function can be called every time user wants
+       // so make sure to clear existing result data before getting the data again.
+       _result = ObjectDetectionResult();
+
+       vector<string> names;
+
+       ObjectDetection<T>::getOutputNames(names);
+
+       vector<float> number_tensor;
+
+       // TFLite_Detection_PostProcess:3
+       ObjectDetection<T>::getOutputTensor(names[3], number_tensor);
+
+       vector<float> label_tensor;
+
+       // TFLite_Detection_PostProcess:1
+       ObjectDetection<T>::getOutputTensor(names[1], label_tensor);
+
+       vector<float> score_tensor;
+       map<float, unsigned int, std::greater<float> > sorted_score;
+
+       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[2]);
+       auto decodingScore = static_pointer_cast<DecodingScore>(scoreMetaInfo->decodingTypeMap[DecodingType::SCORE]);
+
+       // TFLite_Detection_PostProcess:2
+       ObjectDetection<T>::getOutputTensor(names[2], score_tensor);
+       for (size_t idx = 0; idx < score_tensor.size(); ++idx) {
+               if (decodingScore->threshold > score_tensor[idx])
+                       continue;
+
+               sorted_score[score_tensor[idx]] = idx;
+       }
+
+       auto boxMetaInfo = _config->getOutputMetaMap().at(names[0]);
+       auto decodingBox = static_pointer_cast<DecodingBox>(boxMetaInfo->decodingTypeMap[DecodingType::BOX]);
+       vector<float> box_tensor;
+
+       ObjectDetection<T>::getOutputTensor(names[0], box_tensor);
+
+       for (auto &score : sorted_score) {
+               _result.number_of_objects++;
+               // second is idx
+               _result.names.push_back(_labels[label_tensor[score.second]]);
+               _result.indices.push_back(_result.number_of_objects - 1);
+               _result.confidences.push_back(score.first);
+
+               vector<unsigned int> &order = decodingBox->order;
+
+               _result.left.push_back(
+                               static_cast<int>(box_tensor[score.second * 4 + order[0]] * _preprocess.getImageWidth()[0]));
+               _result.top.push_back(
+                               static_cast<int>(box_tensor[score.second * 4 + order[1]] * _preprocess.getImageHeight()[0]));
+               _result.right.push_back(
+                               static_cast<int>(box_tensor[score.second * 4 + order[2]] * _preprocess.getImageWidth()[0]));
+               _result.bottom.push_back(
+                               static_cast<int>(box_tensor[score.second * 4 + order[3]] * _preprocess.getImageHeight()[0]));
+
+               LOGI("idx = %d, name = %s, score = %f, %dx%d, %dx%d", score.second,
+                        _result.names[_result.number_of_objects - 1].c_str(), _result.confidences[_result.number_of_objects - 1],
+                        _result.left[_result.number_of_objects - 1], _result.top[_result.number_of_objects - 1],
+                        _result.right[_result.number_of_objects - 1], _result.bottom[_result.number_of_objects - 1]);
+
+               if (decodingScore->topNumber == _result.number_of_objects)
+                       break;
+       }
+
+       return _result;
+}
+
+template class MobilenetV1Ssd<float>;
+template class MobilenetV1Ssd<unsigned char>;
+
+}
+}
index 066fa853c220a9abbf745d6283fb1544294dadce..42c3526dabc22eb775196a4f12d12873c8514555 100644 (file)
@@ -18,9 +18,9 @@
 #include <string>
 #include <queue>
 #include <algorithm>
-#include "machine_learning_exception.h"
+#include "MvMlException.h"
 #include "MobilenetV2AnchorParser.h"
-#include "common.h"
+#include "meta_common.h"
 
 using namespace std;
 using namespace mediavision::machine_learning::exception;
diff --git a/mv_machine_learning/object_detection/src/MobilenetV2Ssd.cpp b/mv_machine_learning/object_detection/src/MobilenetV2Ssd.cpp
new file mode 100644 (file)
index 0000000..47ed03a
--- /dev/null
@@ -0,0 +1,269 @@
+/**
+ * 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 <string.h>
+#include <map>
+#include <algorithm>
+#include <iostream>
+
+#include "MvMlException.h"
+#include "mv_object_detection_config.h"
+#include "MobilenetV2Ssd.h"
+#include "Postprocess.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+MobilenetV2Ssd<T>::MobilenetV2Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<Config> config)
+               : ObjectDetection<T>(task_type, config), _result()
+{}
+
+template<typename T> MobilenetV2Ssd<T>::~MobilenetV2Ssd()
+{}
+
+static bool compareScore(Box box0, Box box1)
+{
+       return box0.score > box1.score;
+}
+
+static float calcIntersectionOverUnion(Box box0, Box box1)
+{
+       float area0 = box0.location.width * box0.location.height;
+       float area1 = box1.location.width * box1.location.height;
+
+       if (area0 <= 0.0f || area1 <= 0.0f)
+               return 0.0f;
+
+       float sx0 = box0.location.x - box0.location.width * 0.5f;
+       float sy0 = box0.location.y - box0.location.height * 0.5f;
+       float ex0 = box0.location.x + box0.location.width * 0.5f;
+       float ey0 = box0.location.y + box0.location.height * 0.5f;
+       float sx1 = box1.location.x - box1.location.width * 0.5f;
+       float sy1 = box1.location.y - box1.location.height * 0.5f;
+       float ex1 = box1.location.x + box1.location.width * 0.5f;
+       float ey1 = box1.location.y + box1.location.height * 0.5f;
+
+       float xmin0 = min(sx0, ex0);
+       float ymin0 = min(sy0, ey0);
+       float xmax0 = max(sx0, ex0);
+       float ymax0 = max(sy0, ey0);
+       float xmin1 = min(sx1, ex1);
+       float ymin1 = min(sy1, ey1);
+       float xmax1 = max(sx1, ex1);
+       float ymax1 = max(sy1, ey1);
+
+       float intersectXmin = max(xmin0, xmin1);
+       float intersectYmin = max(ymin0, ymin1);
+       float intersectXmax = min(xmax0, xmax1);
+       float intersectYmax = min(ymax0, ymax1);
+
+       float intersectArea = max((intersectYmax - intersectYmin), 0.0f) * max((intersectXmax - intersectXmin), 0.0f);
+
+       return intersectArea / (area0 + area1 - intersectArea);
+}
+
+template<typename T>
+void MobilenetV2Ssd<T>::ApplyNms(vector<vector<Box> > &box_lists, BoxNmsMode mode, float threshold,
+                                                                vector<Box> &box_vector)
+{
+       LOGI("ENTER");
+
+       if (mode != BoxNmsMode::STANDARD) {
+               LOGI("Skip Nms");
+               return;
+       }
+
+       LOGI("threshold: %.3f", threshold);
+
+       bool isIgnore = false;
+       vector<Box> candidate_box_vec;
+
+       for (auto &box_list : box_lists) {
+               if (box_list.size() <= 0)
+                       continue;
+
+               sort(box_list.begin(), box_list.end(), compareScore);
+               candidate_box_vec.clear();
+
+               for (auto &decoded_box : box_list) {
+                       isIgnore = false;
+
+                       for (auto candidate_box = candidate_box_vec.rbegin(); candidate_box != candidate_box_vec.rend();
+                                ++candidate_box) {
+                               // compare decoded_box with previous one
+                               float iouValue = calcIntersectionOverUnion(decoded_box, (*candidate_box));
+
+                               LOGI("iouValue: %.3f", iouValue);
+
+                               if (iouValue >= threshold) {
+                                       isIgnore = true;
+                                       break;
+                               }
+                       }
+
+                       if (!isIgnore)
+                               candidate_box_vec.push_back(decoded_box);
+               }
+
+               if (candidate_box_vec.size() > 0)
+                       box_vector.insert(box_vector.begin(), candidate_box_vec.begin(), candidate_box_vec.end());
+       }
+
+       LOGI("LEAVE");
+}
+
+template<typename T>
+Box MobilenetV2Ssd<T>::decodeBox(const DecodingBox *decodingBox, vector<float> &bb_tensor, int idx, float score,
+                                                                int label, int box_offset)
+{
+       // assume type is (cx,cy,w,h)
+       // left or cx
+       float cx = bb_tensor[idx * box_offset + decodingBox->order[0]];
+       // top or cy
+       float cy = bb_tensor[idx * box_offset + decodingBox->order[1]];
+       // right or width
+       float cWidth = bb_tensor[idx * box_offset + decodingBox->order[2]];
+       // bottom or height
+       float cHeight = bb_tensor[idx * box_offset + decodingBox->order[3]];
+
+       LOGI("cx:%.2f, cy:%.2f, cW:%.2f, cH:%.2f", cx, cy, cWidth, cHeight);
+
+       Box box = { .index = label, .score = score, .location = cv::Rect2f(cx, cy, cWidth, cHeight) };
+
+       return box;
+}
+
+template<typename T>
+Box MobilenetV2Ssd<T>::decodeBoxWithAnchor(const BoxAnchorParam *boxAnchorParam, Box &box, cv::Rect2f &anchor)
+{
+       if (boxAnchorParam->isFixedAnchorSize) {
+               box.location.x += anchor.x;
+               box.location.y += anchor.y;
+       } else {
+               box.location.x = box.location.x / boxAnchorParam->xScale * anchor.width + anchor.x;
+               box.location.y = box.location.y / boxAnchorParam->yScale * anchor.height + anchor.y;
+       }
+
+       if (boxAnchorParam->isExponentialBoxScale) {
+               box.location.width = anchor.width * exp(box.location.width / boxAnchorParam->wScale);
+               box.location.height = anchor.height * exp(box.location.height / boxAnchorParam->hScale);
+       } else {
+               box.location.width = anchor.width * box.location.width / boxAnchorParam->wScale;
+               box.location.height = anchor.height * box.location.height / boxAnchorParam->hScale;
+       }
+
+       return box;
+}
+
+template<typename T> ObjectDetectionResult &MobilenetV2Ssd<T>::result()
+{
+       // Clear _result object because result() function can be called every time user wants
+       // so make sure to clear existing result data before getting the data again.
+       _result = ObjectDetectionResult();
+
+       vector<string> names;
+
+       ObjectDetection<T>::getOutputNames(names);
+
+       vector<float> score_tensor;
+
+       // raw_outputs/class_predictions
+       ObjectDetection<T>::getOutputTensor(names[1], score_tensor);
+
+       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[1]);
+       auto decodingScore = static_pointer_cast<DecodingScore>(scoreMetaInfo->decodingTypeMap[DecodingType::SCORE]);
+
+       auto boxMetaInfo = _config->getOutputMetaMap().at(names[0]);
+       auto decodingBox = static_pointer_cast<DecodingBox>(boxMetaInfo->decodingTypeMap[DecodingType::BOX]);
+       auto anchorParam = static_pointer_cast<BoxAnchorParam>(decodingBox->decodingInfoMap[BoxDecodingType::SSD_ANCHOR]);
+       unsigned int number_of_objects = scoreMetaInfo->dims[2]; // Shape is 1 x 2034 x 91
+
+       vector<float> bb_tensor;
+
+       // raw_outputs/box_encodings
+       ObjectDetection<T>::getOutputTensor(names[0], bb_tensor);
+
+       vector<Box> box_vec;
+       vector<vector<Box> > box_list_vec;
+       int box_offset = boxMetaInfo->dims[2]; // Shape is 1 x 2034 x 4
+
+       for (unsigned int object_idx = 0; object_idx < number_of_objects; ++object_idx) {
+               int anchor_idx = -1;
+
+               box_vec.clear();
+
+               for (auto &anchor : anchorParam->anchorBox) {
+                       anchor_idx++;
+
+                       float score = score_tensor[anchor_idx * number_of_objects + object_idx];
+                       if (score <= decodingScore->threshold)
+                               continue;
+
+                       Box box = decodeBox(decodingBox.get(), bb_tensor, anchor_idx, score, object_idx, box_offset);
+                       box_vec.push_back(decodeBoxWithAnchor(anchorParam.get(), box, anchor));
+               }
+
+               box_list_vec.push_back(box_vec);
+       }
+
+       vector<Box> result_box_vec;
+
+       if (!box_list_vec.empty()) {
+               auto anchorNmsParam = static_pointer_cast<BoxNmsParam>(decodingBox->decodingInfoMap[BoxDecodingType::NMS]);
+               ApplyNms(box_list_vec, anchorNmsParam->mode, anchorNmsParam->iouThreshold, result_box_vec);
+       }
+
+       for (auto &box : result_box_vec) {
+               _result.number_of_objects++;
+               _result.names.push_back(_labels[box.index]);
+               _result.indices.push_back(_result.number_of_objects - 1);
+               _result.confidences.push_back(box.score);
+
+               auto src_width = static_cast<double>(_preprocess.getImageWidth()[0]);
+               auto src_height = static_cast<double>(_preprocess.getImageHeight()[0]);
+               auto half_width = box.location.x - box.location.width * 0.5f;
+               auto half_height = box.location.y - box.location.height * 0.5f;
+
+               _result.left.push_back(static_cast<int>(half_width * src_width));
+               _result.top.push_back(static_cast<int>(half_height * src_height));
+               _result.right.push_back(static_cast<int>(half_width * src_width) +
+                                                               static_cast<int>(box.location.width * src_width));
+               _result.bottom.push_back(static_cast<int>(half_height * src_height) +
+                                                                static_cast<int>(box.location.height * src_height));
+
+               LOGI("idx = %d, name = %s, score = %f, %dx%d, %dx%d", box.index,
+                        _result.names[_result.number_of_objects - 1].c_str(), _result.confidences[_result.number_of_objects - 1],
+                        _result.left[_result.number_of_objects - 1], _result.top[_result.number_of_objects - 1],
+                        _result.right[_result.number_of_objects - 1], _result.bottom[_result.number_of_objects - 1]);
+
+               if (decodingScore->topNumber == _result.number_of_objects)
+                       break;
+       }
+
+       return _result;
+}
+
+template class MobilenetV2Ssd<float>;
+template class MobilenetV2Ssd<unsigned char>;
+
+}
+}
diff --git a/mv_machine_learning/object_detection/src/ObjectDetection.cpp b/mv_machine_learning/object_detection/src/ObjectDetection.cpp
new file mode 100644 (file)
index 0000000..ea31f32
--- /dev/null
@@ -0,0 +1,342 @@
+/**
+ * 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 <string.h>
+#include <fstream>
+#include <map>
+#include <memory>
+
+#include "MvMlException.h"
+#include "common.h"
+#include "mv_object_detection_config.h"
+#include "ObjectDetection.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+ObjectDetection<T>::ObjectDetection(ObjectDetectionTaskType task_type, shared_ptr<Config> config)
+               : _task_type(task_type), _config(config)
+{
+       _inference = make_unique<Inference>();
+}
+
+template<typename T> void ObjectDetection<T>::preDestroy()
+{
+       if (!_async_manager)
+               return;
+
+       _async_manager->stop();
+}
+
+template<typename T> ObjectDetectionTaskType ObjectDetection<T>::getTaskType()
+{
+       return _task_type;
+}
+
+template<typename T> void ObjectDetection<T>::getEngineList()
+{
+       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
+               auto backend = _inference->getSupportedInferenceBackend(idx);
+               // TODO. we need to describe what inference engines are supported by each Task API,
+               //       and based on it, below inference engine types should be checked
+               //       if a given type is supported by this Task API later. As of now, tflite only.
+               if (backend.second == true && backend.first.compare("tflite") == 0)
+                       _valid_backends.push_back(backend.first);
+       }
+}
+
+template<typename T> void ObjectDetection<T>::getDeviceList(const string &engine_type)
+{
+       // TODO. add device types available for a given engine type later.
+       //       In default, cpu and gpu only.
+       _valid_devices.push_back("cpu");
+       _valid_devices.push_back("gpu");
+}
+
+template<typename T> void ObjectDetection<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
+{
+       if (engine_type_name.empty() || device_type_name.empty())
+               throw InvalidParameter("Invalid engine info.");
+
+       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);
+
+       int engine_type = GetBackendType(engine_type_name);
+       int device_type = GetDeviceType(device_type_name);
+
+       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);
+}
+
+template<typename T> unsigned int ObjectDetection<T>::getNumberOfEngines()
+{
+       if (!_valid_backends.empty()) {
+               return _valid_backends.size();
+       }
+
+       getEngineList();
+       return _valid_backends.size();
+}
+
+template<typename T> const string &ObjectDetection<T>::getEngineType(unsigned int engine_index)
+{
+       if (!_valid_backends.empty()) {
+               if (_valid_backends.size() <= engine_index)
+                       throw InvalidParameter("Invalid engine index.");
+
+               return _valid_backends[engine_index];
+       }
+
+       getEngineList();
+
+       if (_valid_backends.size() <= engine_index)
+               throw InvalidParameter("Invalid engine index.");
+
+       return _valid_backends[engine_index];
+}
+
+template<typename T> unsigned int ObjectDetection<T>::getNumberOfDevices(const string &engine_type)
+{
+       if (!_valid_devices.empty()) {
+               return _valid_devices.size();
+       }
+
+       getDeviceList(engine_type);
+       return _valid_devices.size();
+}
+
+template<typename T>
+const string &ObjectDetection<T>::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       if (!_valid_devices.empty()) {
+               if (_valid_devices.size() <= device_index)
+                       throw InvalidParameter("Invalid device index.");
+
+               return _valid_devices[device_index];
+       }
+
+       getDeviceList(engine_type);
+
+       if (_valid_devices.size() <= device_index)
+               throw InvalidParameter("Invalid device index.");
+
+       return _valid_devices[device_index];
+}
+
+template<typename T> void ObjectDetection<T>::loadLabel()
+{
+       if (_config->getLabelFilePath().empty())
+               return;
+
+       ifstream readFile;
+
+       _labels.clear();
+       readFile.open(_config->getLabelFilePath().c_str());
+
+       if (readFile.fail())
+               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
+
+       string line;
+
+       while (getline(readFile, line))
+               _labels.push_back(line);
+
+       readFile.close();
+}
+
+template<typename T> void ObjectDetection<T>::configure()
+{
+       loadLabel();
+
+       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+template<typename T> void ObjectDetection<T>::prepare()
+{
+       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(_config->getOutputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+       _inference->configureModelFiles("", _config->getModelFilePath(), "");
+
+       // Request to load model files to a backend engine.
+       ret = _inference->load();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to load model files.");
+}
+
+template<typename T> shared_ptr<MetaInfo> ObjectDetection<T>::getInputMetaInfo()
+{
+       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
+       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
+
+       // TODO. consider using multiple tensors later.
+       if (tensor_info_map.size() != 1)
+               throw InvalidOperation("Input tensor count not invalid.");
+
+       auto tensor_buffer_iter = tensor_info_map.begin();
+
+       // Get the meta information corresponding to a given input tensor name.
+       return _config->getInputMetaMap()[tensor_buffer_iter->first];
+}
+
+template<typename T>
+void ObjectDetection<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
+{
+       LOGI("ENTER");
+
+       PreprocessConfig config = { false,
+                                                               metaInfo->colorSpace,
+                                                               metaInfo->dataType,
+                                                               metaInfo->getChannel(),
+                                                               metaInfo->getWidth(),
+                                                               metaInfo->getHeight() };
+
+       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
+       if (normalization) {
+               config.normalize = normalization->use;
+               config.mean = normalization->mean;
+               config.std = normalization->std;
+       }
+
+       auto quantization =
+                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
+       if (quantization) {
+               config.quantize = quantization->use;
+               config.scale = quantization->scale;
+               config.zeropoint = quantization->zeropoint;
+       }
+
+       _preprocess.setConfig(config);
+       _preprocess.run<T>(mv_src, inputVector);
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ObjectDetection<T>::inference(vector<vector<T> > &inputVectors)
+{
+       LOGI("ENTER");
+
+       int ret = _inference->run<T>(inputVectors);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to run inference");
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ObjectDetection<T>::perform(mv_source_h &mv_src)
+{
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(mv_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       inference(inputVectors);
+}
+
+template<typename T> void ObjectDetection<T>::performAsync(ObjectDetectionInput &input)
+{
+       if (!_async_manager) {
+               _async_manager = make_unique<AsyncManager<T, ObjectDetectionResult> >([this]() {
+                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
+
+                       inference(inputQueue.inputs);
+
+                       ObjectDetectionResult &resultQueue = result();
+
+                       resultQueue.frame_number = inputQueue.frame_number;
+                       _async_manager->pushToOutput(resultQueue);
+               });
+       }
+
+       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
+       vector<T> inputVector;
+
+       preprocess(input.inference_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+       _async_manager->push(inputVectors);
+}
+
+template<typename T> ObjectDetectionResult &ObjectDetection<T>::getOutput()
+{
+       if (_async_manager) {
+               if (!_async_manager->isWorking())
+                       throw InvalidOperation("Object detection has been already destroyed so invalid operation.");
+
+               _current_result = _async_manager->pop();
+       } else {
+               // TODO. Check if inference request is completed or not here.
+               //       If not then throw an exception.
+               _current_result = result();
+       }
+
+       return _current_result;
+}
+
+template<typename T> ObjectDetectionResult &ObjectDetection<T>::getOutputCache()
+{
+       return _current_result;
+}
+
+template<typename T> void ObjectDetection<T>::getOutputNames(vector<string> &names)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+
+       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
+               names.push_back(it->first);
+}
+
+template<typename T> void ObjectDetection<T>::getOutputTensor(string target_name, vector<float> &tensor)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+
+       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
+       if (!tensor_buffer)
+               throw InvalidOperation("Fail to get tensor buffer.");
+
+       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
+
+       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
+}
+
+template class ObjectDetection<float>;
+template class ObjectDetection<unsigned char>;
+
+}
+}
diff --git a/mv_machine_learning/object_detection/src/ObjectDetectionAdapter.cpp b/mv_machine_learning/object_detection/src/ObjectDetectionAdapter.cpp
new file mode 100644 (file)
index 0000000..1b7e4c6
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * 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 "MvMlException.h"
+#include "ObjectDetectionAdapter.h"
+#include "ObjectDetectionExternal.h"
+#include "mv_object_detection_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
+{
+ObjectDetectionAdapter::ObjectDetectionAdapter()
+{
+       _config = make_shared<Config>();
+
+       // If the model type needs external plugin then bypass to load the meta file and just create the external plugin.
+       // In this case, external plugin will use its own meta file approach regardless of Mediavision's one.
+       _config->parsePluginConfigFile(_plugin_config_file_name);
+       if (!_config->isPluginUsed())
+               _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+ObjectDetectionAdapter::~ObjectDetectionAdapter()
+{
+       _object_detection->preDestroy();
+}
+
+template<typename U> void ObjectDetectionAdapter::create(ObjectDetectionTaskType task_type)
+{
+       switch (task_type) {
+       case ObjectDetectionTaskType::MOBILENET_V1_SSD:
+               _object_detection = make_unique<MobilenetV1Ssd<U> >(task_type, _config);
+               break;
+       case ObjectDetectionTaskType::MOBILENET_V2_SSD:
+               _object_detection = make_unique<MobilenetV2Ssd<U> >(task_type, _config);
+               break;
+       default:
+               throw InvalidOperation("Invalid object detection task type.");
+       }
+       // TODO.
+}
+
+void ObjectDetectionAdapter::create(string model_name)
+{
+       if (model_name.empty())
+               model_name = _config->getDefaultModelName();
+
+       auto task_type = convertToTaskType(model_name);
+
+       if (_config->isPluginUsed()) {
+               const auto &plugin_name = _config->getPluginFileName();
+
+               _object_detection = make_unique<ObjectDetectionExternal>(task_type, plugin_name.c_str());
+               return;
+       }
+
+       _config->loadMetaFile(make_unique<ObjectDetectionParser>(static_cast<int>(task_type)));
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               create<unsigned char>(task_type);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               create<float>(task_type);
+               break;
+       default:
+               throw InvalidOperation("Invalid object detection data type.");
+       }
+}
+
+ObjectDetectionTaskType ObjectDetectionAdapter::convertToTaskType(string 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 == "OD_TRIV2")
+               return ObjectDetectionTaskType::OD_TRIV2;
+       else if (model_name == "FD_TRIV2")
+               return ObjectDetectionTaskType::FD_TRIV2;
+       else if (model_name == "MOBILENET_V1_SSD")
+               return ObjectDetectionTaskType::MOBILENET_V1_SSD;
+       else if (model_name == "MOBILENET_V2_SSD")
+               return ObjectDetectionTaskType::MOBILENET_V2_SSD;
+       // TODO.
+
+       throw InvalidParameter("Invalid object detection model name.");
+}
+
+void ObjectDetectionAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                                 const string &model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               create(model_name);
+       } catch (const BaseException &e) {
+               LOGW("A given model name is invalid so default task type will be used.");
+       }
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+}
+
+void ObjectDetectionAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _object_detection->setEngineInfo(string(engine_type), string(device_type));
+}
+
+void ObjectDetectionAdapter::configure()
+{
+       _object_detection->configure();
+}
+
+unsigned int ObjectDetectionAdapter::getNumberOfEngines()
+{
+       return _object_detection->getNumberOfEngines();
+}
+
+const string &ObjectDetectionAdapter::getEngineType(unsigned int engine_index)
+{
+       return _object_detection->getEngineType(engine_index);
+}
+
+unsigned int ObjectDetectionAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _object_detection->getNumberOfDevices(engine_type);
+}
+
+const string &ObjectDetectionAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _object_detection->getDeviceType(engine_type, device_index);
+}
+
+void ObjectDetectionAdapter::prepare()
+{
+       _object_detection->prepare();
+}
+
+void ObjectDetectionAdapter::perform(InputBaseType &input)
+{
+       _object_detection->perform(input.inference_src);
+}
+
+OutputBaseType &ObjectDetectionAdapter::getOutput()
+{
+       return _object_detection->getOutput();
+}
+
+OutputBaseType &ObjectDetectionAdapter::getOutputCache()
+{
+       return _object_detection->getOutputCache();
+}
+
+void ObjectDetectionAdapter::performAsync(InputBaseType &input)
+{
+       _object_detection->performAsync(static_cast<ObjectDetectionInput &>(input));
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/src/ObjectDetectionExternal.cpp b/mv_machine_learning/object_detection/src/ObjectDetectionExternal.cpp
new file mode 100644 (file)
index 0000000..2af7c8a
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ * 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 "MvMlException.h"
+#include "ObjectDetectionExternal.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+typedef IObjectDetection *create_t(ObjectDetectionTaskType task_type);
+typedef void destroy_t(IObjectDetection *);
+
+ObjectDetectionExternal::ObjectDetectionExternal(ObjectDetectionTaskType task_type, const string &plugin_name)
+               : _plugin_handle(), _object_detection_plugin()
+{
+       // Load external object detection library.
+       LOGI("lib: %s", plugin_name.c_str());
+       _plugin_handle = dlopen(plugin_name.c_str(), 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(task_type);
+       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::setEngineInfo(string engine_type, string device_type)
+{
+       _object_detection_plugin->setEngineInfo(engine_type, device_type);
+}
+
+unsigned int ObjectDetectionExternal::getNumberOfEngines()
+{
+       return _object_detection_plugin->getNumberOfEngines();
+}
+
+const string &ObjectDetectionExternal::getEngineType(unsigned int engine_index)
+{
+       return _object_detection_plugin->getEngineType(engine_index);
+}
+
+unsigned int ObjectDetectionExternal::getNumberOfDevices(const string &engine_type)
+{
+       return _object_detection_plugin->getNumberOfDevices(engine_type);
+}
+
+const string &ObjectDetectionExternal::getDeviceType(const string &engine_type, const unsigned int device_index)
+{
+       return _object_detection_plugin->getDeviceType(engine_type, device_index);
+}
+
+void ObjectDetectionExternal::configure()
+{
+       _object_detection_plugin->configure();
+}
+
+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()
+{
+       _current_result = _object_detection_plugin->getOutput();
+
+       return _current_result;
+}
+
+ObjectDetectionResult &ObjectDetectionExternal::getOutputCache()
+{
+       return _current_result;
+}
+
+}
+}
\ No newline at end of file
index 4505297504c842b74ebe195682dc0b2f51a901fe..d4400424e4d6d626697bd208007a942f2cc498ab 100644 (file)
@@ -15,7 +15,7 @@
  */
 #include <memory>
 
-#include "machine_learning_exception.h"
+#include "MvMlException.h"
 #include "ObjectDetectionParser.h"
 #include "object_detection_type.h"
 #include "MobilenetV2AnchorParser.h"
diff --git a/mv_machine_learning/object_detection/src/face_detection_adapter.cpp b/mv_machine_learning/object_detection/src/face_detection_adapter.cpp
deleted file mode 100644 (file)
index 99eaa95..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/**
- * 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 "face_detection_adapter.h"
-#include "object_detection_external.h"
-#include "mv_object_detection_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
-{
-FaceDetectionAdapter::FaceDetectionAdapter()
-{
-       _config = make_shared<MachineLearningConfig>();
-
-       // If the model type needs external plugin then bypass to load the meta file and just create the external plugin.
-       // In this case, external plugin will use its own meta file approach regardless of Mediavision's one.
-       _config->parsePluginConfigFile(_plugin_config_file_name);
-       if (!_config->isPluginUsed())
-               _config->parseConfigFile(_config_file_name);
-
-       create(_config->getDefaultModelName());
-}
-
-FaceDetectionAdapter::~FaceDetectionAdapter()
-{
-       _object_detection->preDestroy();
-}
-
-template<typename U> void FaceDetectionAdapter::create(ObjectDetectionTaskType task_type)
-{
-       switch (task_type) {
-       case ObjectDetectionTaskType::FD_MOBILENET_V1_SSD:
-               _object_detection = make_unique<MobilenetV1Ssd<U> >(task_type, _config);
-               break;
-       default:
-               throw InvalidOperation("Invalid face detection task type.");
-       }
-       // TODO.
-}
-
-void FaceDetectionAdapter::create(string model_name)
-{
-       if (model_name.empty())
-               model_name = _config->getDefaultModelName();
-
-       auto task_type = convertToTaskType(model_name);
-
-       if (_config->isPluginUsed()) {
-               const auto &plugin_name = _config->getPluginFileName();
-
-               _object_detection = make_unique<ObjectDetectionExternal>(task_type, plugin_name.c_str());
-               return;
-       }
-
-       _config->loadMetaFile(make_unique<ObjectDetectionParser>(static_cast<int>(task_type)));
-       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
-
-       switch (dataType) {
-       case MV_INFERENCE_DATA_UINT8:
-               create<unsigned char>(task_type);
-               break;
-       case MV_INFERENCE_DATA_FLOAT32:
-               create<float>(task_type);
-               break;
-       default:
-               throw InvalidOperation("Invalid face detection data type.");
-       }
-}
-
-ObjectDetectionTaskType FaceDetectionAdapter::convertToTaskType(string 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 == "FD_MOBILENET_V1_SSD")
-               return ObjectDetectionTaskType::FD_MOBILENET_V1_SSD;
-       if (model_name == "OD_TRIV2")
-               return ObjectDetectionTaskType::OD_TRIV2;
-       else if (model_name == "FD_TRIV2")
-               return ObjectDetectionTaskType::FD_TRIV2;
-       // TODO.
-
-       throw InvalidParameter("Invalid face detection model name.");
-}
-
-void FaceDetectionAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                               const string &model_name)
-{
-       try {
-               _config->setUserModel(model_file, meta_file, label_file);
-               create(model_name);
-       } catch (const BaseException &e) {
-               LOGW("A given model name is invalid so default task type will be used.");
-       }
-
-       if (model_file.empty() && meta_file.empty()) {
-               LOGW("Given model info is invalid so default model info will be used instead.");
-               return;
-       }
-}
-
-void FaceDetectionAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       _object_detection->setEngineInfo(string(engine_type), string(device_type));
-}
-
-void FaceDetectionAdapter::configure()
-{
-       _object_detection->configure();
-}
-
-unsigned int FaceDetectionAdapter::getNumberOfEngines()
-{
-       return _object_detection->getNumberOfEngines();
-}
-
-const string &FaceDetectionAdapter::getEngineType(unsigned int engine_index)
-{
-       return _object_detection->getEngineType(engine_index);
-}
-
-unsigned int FaceDetectionAdapter::getNumberOfDevices(const string &engine_type)
-{
-       return _object_detection->getNumberOfDevices(engine_type);
-}
-
-const string &FaceDetectionAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _object_detection->getDeviceType(engine_type, device_index);
-}
-
-void FaceDetectionAdapter::prepare()
-{
-       _object_detection->prepare();
-}
-
-void FaceDetectionAdapter::perform(InputBaseType &input)
-{
-       _object_detection->perform(input.inference_src);
-}
-
-void FaceDetectionAdapter::performAsync(InputBaseType &input)
-{
-       _object_detection->performAsync(static_cast<ObjectDetectionInput &>(input));
-}
-
-OutputBaseType &FaceDetectionAdapter::getOutput()
-{
-       return _object_detection->getOutput();
-}
-
-OutputBaseType &FaceDetectionAdapter::getOutputCache()
-{
-       return _object_detection->getOutputCache();
-}
-
-}
-}
diff --git a/mv_machine_learning/object_detection/src/mobilenet_v1_ssd.cpp b/mv_machine_learning/object_detection/src/mobilenet_v1_ssd.cpp
deleted file mode 100644 (file)
index 5dcbed0..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * 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 <string.h>
-#include <map>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "mv_object_detection_config.h"
-#include "mobilenet_v1_ssd.h"
-#include "Postprocess.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-MobilenetV1Ssd<T>::MobilenetV1Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config)
-               : ObjectDetection<T>(task_type, config), _result()
-{}
-
-template<typename T> MobilenetV1Ssd<T>::~MobilenetV1Ssd()
-{}
-
-template<typename T> ObjectDetectionResult &MobilenetV1Ssd<T>::result()
-{
-       // Clear _result object because result() function can be called every time user wants
-       // so make sure to clear existing result data before getting the data again.
-       _result = ObjectDetectionResult();
-
-       vector<string> names;
-
-       ObjectDetection<T>::getOutputNames(names);
-
-       vector<float> number_tensor;
-
-       // TFLite_Detection_PostProcess:3
-       ObjectDetection<T>::getOutputTensor(names[3], number_tensor);
-
-       vector<float> label_tensor;
-
-       // TFLite_Detection_PostProcess:1
-       ObjectDetection<T>::getOutputTensor(names[1], label_tensor);
-
-       vector<float> score_tensor;
-       map<float, unsigned int, std::greater<float> > sorted_score;
-
-       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[2]);
-       auto decodingScore = static_pointer_cast<DecodingScore>(scoreMetaInfo->decodingTypeMap[DecodingType::SCORE]);
-
-       // TFLite_Detection_PostProcess:2
-       ObjectDetection<T>::getOutputTensor(names[2], score_tensor);
-       for (size_t idx = 0; idx < score_tensor.size(); ++idx) {
-               if (decodingScore->threshold > score_tensor[idx])
-                       continue;
-
-               sorted_score[score_tensor[idx]] = idx;
-       }
-
-       auto boxMetaInfo = _config->getOutputMetaMap().at(names[0]);
-       auto decodingBox = static_pointer_cast<DecodingBox>(boxMetaInfo->decodingTypeMap[DecodingType::BOX]);
-       vector<float> box_tensor;
-
-       ObjectDetection<T>::getOutputTensor(names[0], box_tensor);
-
-       for (auto &score : sorted_score) {
-               _result.number_of_objects++;
-               // second is idx
-               _result.names.push_back(_labels[label_tensor[score.second]]);
-               _result.indices.push_back(_result.number_of_objects - 1);
-               _result.confidences.push_back(score.first);
-
-               vector<unsigned int> &order = decodingBox->order;
-
-               _result.left.push_back(
-                               static_cast<int>(box_tensor[score.second * 4 + order[0]] * _preprocess.getImageWidth()[0]));
-               _result.top.push_back(
-                               static_cast<int>(box_tensor[score.second * 4 + order[1]] * _preprocess.getImageHeight()[0]));
-               _result.right.push_back(
-                               static_cast<int>(box_tensor[score.second * 4 + order[2]] * _preprocess.getImageWidth()[0]));
-               _result.bottom.push_back(
-                               static_cast<int>(box_tensor[score.second * 4 + order[3]] * _preprocess.getImageHeight()[0]));
-
-               LOGI("idx = %d, name = %s, score = %f, %dx%d, %dx%d", score.second,
-                        _result.names[_result.number_of_objects - 1].c_str(), _result.confidences[_result.number_of_objects - 1],
-                        _result.left[_result.number_of_objects - 1], _result.top[_result.number_of_objects - 1],
-                        _result.right[_result.number_of_objects - 1], _result.bottom[_result.number_of_objects - 1]);
-
-               if (decodingScore->topNumber == _result.number_of_objects)
-                       break;
-       }
-
-       return _result;
-}
-
-template class MobilenetV1Ssd<float>;
-template class MobilenetV1Ssd<unsigned char>;
-
-}
-}
diff --git a/mv_machine_learning/object_detection/src/mobilenet_v2_ssd.cpp b/mv_machine_learning/object_detection/src/mobilenet_v2_ssd.cpp
deleted file mode 100644 (file)
index 41afeb3..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/**
- * 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 <string.h>
-#include <map>
-#include <algorithm>
-#include <iostream>
-
-#include "machine_learning_exception.h"
-#include "mv_object_detection_config.h"
-#include "mobilenet_v2_ssd.h"
-#include "Postprocess.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-MobilenetV2Ssd<T>::MobilenetV2Ssd(ObjectDetectionTaskType task_type, std::shared_ptr<MachineLearningConfig> config)
-               : ObjectDetection<T>(task_type, config), _result()
-{}
-
-template<typename T> MobilenetV2Ssd<T>::~MobilenetV2Ssd()
-{}
-
-static bool compareScore(Box box0, Box box1)
-{
-       return box0.score > box1.score;
-}
-
-static float calcIntersectionOverUnion(Box box0, Box box1)
-{
-       float area0 = box0.location.width * box0.location.height;
-       float area1 = box1.location.width * box1.location.height;
-
-       if (area0 <= 0.0f || area1 <= 0.0f)
-               return 0.0f;
-
-       float sx0 = box0.location.x - box0.location.width * 0.5f;
-       float sy0 = box0.location.y - box0.location.height * 0.5f;
-       float ex0 = box0.location.x + box0.location.width * 0.5f;
-       float ey0 = box0.location.y + box0.location.height * 0.5f;
-       float sx1 = box1.location.x - box1.location.width * 0.5f;
-       float sy1 = box1.location.y - box1.location.height * 0.5f;
-       float ex1 = box1.location.x + box1.location.width * 0.5f;
-       float ey1 = box1.location.y + box1.location.height * 0.5f;
-
-       float xmin0 = min(sx0, ex0);
-       float ymin0 = min(sy0, ey0);
-       float xmax0 = max(sx0, ex0);
-       float ymax0 = max(sy0, ey0);
-       float xmin1 = min(sx1, ex1);
-       float ymin1 = min(sy1, ey1);
-       float xmax1 = max(sx1, ex1);
-       float ymax1 = max(sy1, ey1);
-
-       float intersectXmin = max(xmin0, xmin1);
-       float intersectYmin = max(ymin0, ymin1);
-       float intersectXmax = min(xmax0, xmax1);
-       float intersectYmax = min(ymax0, ymax1);
-
-       float intersectArea = max((intersectYmax - intersectYmin), 0.0f) * max((intersectXmax - intersectXmin), 0.0f);
-
-       return intersectArea / (area0 + area1 - intersectArea);
-}
-
-template<typename T>
-void MobilenetV2Ssd<T>::ApplyNms(vector<vector<Box> > &box_lists, BoxNmsMode mode, float threshold,
-                                                                vector<Box> &box_vector)
-{
-       LOGI("ENTER");
-
-       if (mode != BoxNmsMode::STANDARD) {
-               LOGI("Skip Nms");
-               return;
-       }
-
-       LOGI("threshold: %.3f", threshold);
-
-       bool isIgnore = false;
-       vector<Box> candidate_box_vec;
-
-       for (auto &box_list : box_lists) {
-               if (box_list.size() <= 0)
-                       continue;
-
-               sort(box_list.begin(), box_list.end(), compareScore);
-               candidate_box_vec.clear();
-
-               for (auto &decoded_box : box_list) {
-                       isIgnore = false;
-
-                       for (auto candidate_box = candidate_box_vec.rbegin(); candidate_box != candidate_box_vec.rend();
-                                ++candidate_box) {
-                               // compare decoded_box with previous one
-                               float iouValue = calcIntersectionOverUnion(decoded_box, (*candidate_box));
-
-                               LOGI("iouValue: %.3f", iouValue);
-
-                               if (iouValue >= threshold) {
-                                       isIgnore = true;
-                                       break;
-                               }
-                       }
-
-                       if (!isIgnore)
-                               candidate_box_vec.push_back(decoded_box);
-               }
-
-               if (candidate_box_vec.size() > 0)
-                       box_vector.insert(box_vector.begin(), candidate_box_vec.begin(), candidate_box_vec.end());
-       }
-
-       LOGI("LEAVE");
-}
-
-template<typename T>
-Box MobilenetV2Ssd<T>::decodeBox(const DecodingBox *decodingBox, vector<float> &bb_tensor, int idx, float score,
-                                                                int label, int box_offset)
-{
-       // assume type is (cx,cy,w,h)
-       // left or cx
-       float cx = bb_tensor[idx * box_offset + decodingBox->order[0]];
-       // top or cy
-       float cy = bb_tensor[idx * box_offset + decodingBox->order[1]];
-       // right or width
-       float cWidth = bb_tensor[idx * box_offset + decodingBox->order[2]];
-       // bottom or height
-       float cHeight = bb_tensor[idx * box_offset + decodingBox->order[3]];
-
-       LOGI("cx:%.2f, cy:%.2f, cW:%.2f, cH:%.2f", cx, cy, cWidth, cHeight);
-
-       Box box = { .index = label, .score = score, .location = cv::Rect2f(cx, cy, cWidth, cHeight) };
-
-       return box;
-}
-
-template<typename T>
-Box MobilenetV2Ssd<T>::decodeBoxWithAnchor(const BoxAnchorParam *boxAnchorParam, Box &box, cv::Rect2f &anchor)
-{
-       if (boxAnchorParam->isFixedAnchorSize) {
-               box.location.x += anchor.x;
-               box.location.y += anchor.y;
-       } else {
-               box.location.x = box.location.x / boxAnchorParam->xScale * anchor.width + anchor.x;
-               box.location.y = box.location.y / boxAnchorParam->yScale * anchor.height + anchor.y;
-       }
-
-       if (boxAnchorParam->isExponentialBoxScale) {
-               box.location.width = anchor.width * exp(box.location.width / boxAnchorParam->wScale);
-               box.location.height = anchor.height * exp(box.location.height / boxAnchorParam->hScale);
-       } else {
-               box.location.width = anchor.width * box.location.width / boxAnchorParam->wScale;
-               box.location.height = anchor.height * box.location.height / boxAnchorParam->hScale;
-       }
-
-       return box;
-}
-
-template<typename T> ObjectDetectionResult &MobilenetV2Ssd<T>::result()
-{
-       // Clear _result object because result() function can be called every time user wants
-       // so make sure to clear existing result data before getting the data again.
-       _result = ObjectDetectionResult();
-
-       vector<string> names;
-
-       ObjectDetection<T>::getOutputNames(names);
-
-       vector<float> score_tensor;
-
-       // raw_outputs/class_predictions
-       ObjectDetection<T>::getOutputTensor(names[1], score_tensor);
-
-       auto scoreMetaInfo = _config->getOutputMetaMap().at(names[1]);
-       auto decodingScore = static_pointer_cast<DecodingScore>(scoreMetaInfo->decodingTypeMap[DecodingType::SCORE]);
-
-       auto boxMetaInfo = _config->getOutputMetaMap().at(names[0]);
-       auto decodingBox = static_pointer_cast<DecodingBox>(boxMetaInfo->decodingTypeMap[DecodingType::BOX]);
-       auto anchorParam = static_pointer_cast<BoxAnchorParam>(decodingBox->decodingInfoMap[BoxDecodingType::SSD_ANCHOR]);
-       unsigned int number_of_objects = scoreMetaInfo->dims[2]; // Shape is 1 x 2034 x 91
-
-       vector<float> bb_tensor;
-
-       // raw_outputs/box_encodings
-       ObjectDetection<T>::getOutputTensor(names[0], bb_tensor);
-
-       vector<Box> box_vec;
-       vector<vector<Box> > box_list_vec;
-       int box_offset = boxMetaInfo->dims[2]; // Shape is 1 x 2034 x 4
-
-       for (unsigned int object_idx = 0; object_idx < number_of_objects; ++object_idx) {
-               int anchor_idx = -1;
-
-               box_vec.clear();
-
-               for (auto &anchor : anchorParam->anchorBox) {
-                       anchor_idx++;
-
-                       float score = score_tensor[anchor_idx * number_of_objects + object_idx];
-                       if (score <= decodingScore->threshold)
-                               continue;
-
-                       Box box = decodeBox(decodingBox.get(), bb_tensor, anchor_idx, score, object_idx, box_offset);
-                       box_vec.push_back(decodeBoxWithAnchor(anchorParam.get(), box, anchor));
-               }
-
-               box_list_vec.push_back(box_vec);
-       }
-
-       vector<Box> result_box_vec;
-
-       if (!box_list_vec.empty()) {
-               auto anchorNmsParam = static_pointer_cast<BoxNmsParam>(decodingBox->decodingInfoMap[BoxDecodingType::NMS]);
-               ApplyNms(box_list_vec, anchorNmsParam->mode, anchorNmsParam->iouThreshold, result_box_vec);
-       }
-
-       for (auto &box : result_box_vec) {
-               _result.number_of_objects++;
-               _result.names.push_back(_labels[box.index]);
-               _result.indices.push_back(_result.number_of_objects - 1);
-               _result.confidences.push_back(box.score);
-
-               auto src_width = static_cast<double>(_preprocess.getImageWidth()[0]);
-               auto src_height = static_cast<double>(_preprocess.getImageHeight()[0]);
-               auto half_width = box.location.x - box.location.width * 0.5f;
-               auto half_height = box.location.y - box.location.height * 0.5f;
-
-               _result.left.push_back(static_cast<int>(half_width * src_width));
-               _result.top.push_back(static_cast<int>(half_height * src_height));
-               _result.right.push_back(static_cast<int>(half_width * src_width) +
-                                                               static_cast<int>(box.location.width * src_width));
-               _result.bottom.push_back(static_cast<int>(half_height * src_height) +
-                                                                static_cast<int>(box.location.height * src_height));
-
-               LOGI("idx = %d, name = %s, score = %f, %dx%d, %dx%d", box.index,
-                        _result.names[_result.number_of_objects - 1].c_str(), _result.confidences[_result.number_of_objects - 1],
-                        _result.left[_result.number_of_objects - 1], _result.top[_result.number_of_objects - 1],
-                        _result.right[_result.number_of_objects - 1], _result.bottom[_result.number_of_objects - 1]);
-
-               if (decodingScore->topNumber == _result.number_of_objects)
-                       break;
-       }
-
-       return _result;
-}
-
-template class MobilenetV2Ssd<float>;
-template class MobilenetV2Ssd<unsigned char>;
-
-}
-}
index f5470d1ac80a78c645ad6078f18623885d1648c2..b73cbb3dd3eb4cc98559165901d34c5794f4c474 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "itask.h"
+#include "ITask.h"
 #include "mv_face_detection_internal.h"
-#include "face_detection_adapter.h"
-#include "machine_learning_exception.h"
-#include "MachineLearningNative.h"
+#include "FaceDetectionAdapter.h"
+#include "MvMlException.h"
+#include "native_capi.h"
 #include "object_detection_type.h"
-#include "context.h"
+#include "Context.h"
 
 #include <new>
 #include <unistd.h>
index 4fd9b9d4ea1117ff1ea9bbc55c06f3fae28a93dc..b492d34ca201306278c022b048c4193f919ad766 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "itask.h"
+#include "ITask.h"
 #include "mv_object_detection_internal.h"
-#include "object_detection_adapter.h"
-#include "machine_learning_exception.h"
-#include "MachineLearningNative.h"
+#include "ObjectDetectionAdapter.h"
+#include "MvMlException.h"
+#include "native_capi.h"
 #include "object_detection_type.h"
-#include "context.h"
+#include "Context.h"
 
 #include <new>
 #include <unistd.h>
diff --git a/mv_machine_learning/object_detection/src/object_detection.cpp b/mv_machine_learning/object_detection/src/object_detection.cpp
deleted file mode 100644 (file)
index 539dd18..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/**
- * 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 <string.h>
-#include <fstream>
-#include <map>
-#include <memory>
-
-#include "machine_learning_exception.h"
-#include "mv_machine_learning_common.h"
-#include "mv_object_detection_config.h"
-#include "object_detection.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace MediaVision::Common;
-using namespace mediavision::common;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-ObjectDetection<T>::ObjectDetection(ObjectDetectionTaskType task_type, shared_ptr<MachineLearningConfig> config)
-               : _task_type(task_type), _config(config)
-{
-       _inference = make_unique<Inference>();
-}
-
-template<typename T> void ObjectDetection<T>::preDestroy()
-{
-       if (!_async_manager)
-               return;
-
-       _async_manager->stop();
-}
-
-template<typename T> ObjectDetectionTaskType ObjectDetection<T>::getTaskType()
-{
-       return _task_type;
-}
-
-template<typename T> void ObjectDetection<T>::getEngineList()
-{
-       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
-               auto backend = _inference->getSupportedInferenceBackend(idx);
-               // TODO. we need to describe what inference engines are supported by each Task API,
-               //       and based on it, below inference engine types should be checked
-               //       if a given type is supported by this Task API later. As of now, tflite only.
-               if (backend.second == true && backend.first.compare("tflite") == 0)
-                       _valid_backends.push_back(backend.first);
-       }
-}
-
-template<typename T> void ObjectDetection<T>::getDeviceList(const string &engine_type)
-{
-       // TODO. add device types available for a given engine type later.
-       //       In default, cpu and gpu only.
-       _valid_devices.push_back("cpu");
-       _valid_devices.push_back("gpu");
-}
-
-template<typename T> void ObjectDetection<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
-{
-       if (engine_type_name.empty() || device_type_name.empty())
-               throw InvalidParameter("Invalid engine info.");
-
-       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);
-
-       int engine_type = GetBackendType(engine_type_name);
-       int device_type = GetDeviceType(device_type_name);
-
-       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);
-}
-
-template<typename T> unsigned int ObjectDetection<T>::getNumberOfEngines()
-{
-       if (!_valid_backends.empty()) {
-               return _valid_backends.size();
-       }
-
-       getEngineList();
-       return _valid_backends.size();
-}
-
-template<typename T> const string &ObjectDetection<T>::getEngineType(unsigned int engine_index)
-{
-       if (!_valid_backends.empty()) {
-               if (_valid_backends.size() <= engine_index)
-                       throw InvalidParameter("Invalid engine index.");
-
-               return _valid_backends[engine_index];
-       }
-
-       getEngineList();
-
-       if (_valid_backends.size() <= engine_index)
-               throw InvalidParameter("Invalid engine index.");
-
-       return _valid_backends[engine_index];
-}
-
-template<typename T> unsigned int ObjectDetection<T>::getNumberOfDevices(const string &engine_type)
-{
-       if (!_valid_devices.empty()) {
-               return _valid_devices.size();
-       }
-
-       getDeviceList(engine_type);
-       return _valid_devices.size();
-}
-
-template<typename T>
-const string &ObjectDetection<T>::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       if (!_valid_devices.empty()) {
-               if (_valid_devices.size() <= device_index)
-                       throw InvalidParameter("Invalid device index.");
-
-               return _valid_devices[device_index];
-       }
-
-       getDeviceList(engine_type);
-
-       if (_valid_devices.size() <= device_index)
-               throw InvalidParameter("Invalid device index.");
-
-       return _valid_devices[device_index];
-}
-
-template<typename T> void ObjectDetection<T>::loadLabel()
-{
-       if (_config->getLabelFilePath().empty())
-               return;
-
-       ifstream readFile;
-
-       _labels.clear();
-       readFile.open(_config->getLabelFilePath().c_str());
-
-       if (readFile.fail())
-               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
-
-       string line;
-
-       while (getline(readFile, line))
-               _labels.push_back(line);
-
-       readFile.close();
-}
-
-template<typename T> void ObjectDetection<T>::configure()
-{
-       loadLabel();
-
-       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to bind a backend engine.");
-}
-
-template<typename T> void ObjectDetection<T>::prepare()
-{
-       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(_config->getOutputMetaMap());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to configure output tensor info from meta file.");
-
-       _inference->configureModelFiles("", _config->getModelFilePath(), "");
-
-       // Request to load model files to a backend engine.
-       ret = _inference->load();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to load model files.");
-}
-
-template<typename T> shared_ptr<MetaInfo> ObjectDetection<T>::getInputMetaInfo()
-{
-       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
-       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
-
-       // TODO. consider using multiple tensors later.
-       if (tensor_info_map.size() != 1)
-               throw InvalidOperation("Input tensor count not invalid.");
-
-       auto tensor_buffer_iter = tensor_info_map.begin();
-
-       // Get the meta information corresponding to a given input tensor name.
-       return _config->getInputMetaMap()[tensor_buffer_iter->first];
-}
-
-template<typename T>
-void ObjectDetection<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
-{
-       LOGI("ENTER");
-
-       PreprocessConfig config = { false,
-                                                               metaInfo->colorSpace,
-                                                               metaInfo->dataType,
-                                                               metaInfo->getChannel(),
-                                                               metaInfo->getWidth(),
-                                                               metaInfo->getHeight() };
-
-       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
-       if (normalization) {
-               config.normalize = normalization->use;
-               config.mean = normalization->mean;
-               config.std = normalization->std;
-       }
-
-       auto quantization =
-                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
-       if (quantization) {
-               config.quantize = quantization->use;
-               config.scale = quantization->scale;
-               config.zeropoint = quantization->zeropoint;
-       }
-
-       _preprocess.setConfig(config);
-       _preprocess.run<T>(mv_src, inputVector);
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ObjectDetection<T>::inference(vector<vector<T> > &inputVectors)
-{
-       LOGI("ENTER");
-
-       int ret = _inference->run<T>(inputVectors);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to run inference");
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ObjectDetection<T>::perform(mv_source_h &mv_src)
-{
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(mv_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       inference(inputVectors);
-}
-
-template<typename T> void ObjectDetection<T>::performAsync(ObjectDetectionInput &input)
-{
-       if (!_async_manager) {
-               _async_manager = make_unique<AsyncManager<T, ObjectDetectionResult> >([this]() {
-                       AsyncInputQueue<T> inputQueue = _async_manager->popFromInput();
-
-                       inference(inputQueue.inputs);
-
-                       ObjectDetectionResult &resultQueue = result();
-
-                       resultQueue.frame_number = inputQueue.frame_number;
-                       _async_manager->pushToOutput(resultQueue);
-               });
-       }
-
-       shared_ptr<MetaInfo> metaInfo = getInputMetaInfo();
-       vector<T> inputVector;
-
-       preprocess(input.inference_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-       _async_manager->push(inputVectors);
-}
-
-template<typename T> ObjectDetectionResult &ObjectDetection<T>::getOutput()
-{
-       if (_async_manager) {
-               if (!_async_manager->isWorking())
-                       throw InvalidOperation("Object detection has been already destroyed so invalid operation.");
-
-               _current_result = _async_manager->pop();
-       } else {
-               // TODO. Check if inference request is completed or not here.
-               //       If not then throw an exception.
-               _current_result = result();
-       }
-
-       return _current_result;
-}
-
-template<typename T> ObjectDetectionResult &ObjectDetection<T>::getOutputCache()
-{
-       return _current_result;
-}
-
-template<typename T> void ObjectDetection<T>::getOutputNames(vector<string> &names)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
-
-       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
-               names.push_back(it->first);
-}
-
-template<typename T> void ObjectDetection<T>::getOutputTensor(string target_name, vector<float> &tensor)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-
-       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
-       if (!tensor_buffer)
-               throw InvalidOperation("Fail to get tensor buffer.");
-
-       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
-
-       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
-}
-
-template class ObjectDetection<float>;
-template class ObjectDetection<unsigned char>;
-
-}
-}
diff --git a/mv_machine_learning/object_detection/src/object_detection_adapter.cpp b/mv_machine_learning/object_detection/src/object_detection_adapter.cpp
deleted file mode 100644 (file)
index cc88302..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * 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 "object_detection_adapter.h"
-#include "object_detection_external.h"
-#include "mv_object_detection_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
-{
-ObjectDetectionAdapter::ObjectDetectionAdapter()
-{
-       _config = make_shared<MachineLearningConfig>();
-
-       // If the model type needs external plugin then bypass to load the meta file and just create the external plugin.
-       // In this case, external plugin will use its own meta file approach regardless of Mediavision's one.
-       _config->parsePluginConfigFile(_plugin_config_file_name);
-       if (!_config->isPluginUsed())
-               _config->parseConfigFile(_config_file_name);
-
-       create(_config->getDefaultModelName());
-}
-
-ObjectDetectionAdapter::~ObjectDetectionAdapter()
-{
-       _object_detection->preDestroy();
-}
-
-template<typename U> void ObjectDetectionAdapter::create(ObjectDetectionTaskType task_type)
-{
-       switch (task_type) {
-       case ObjectDetectionTaskType::MOBILENET_V1_SSD:
-               _object_detection = make_unique<MobilenetV1Ssd<U> >(task_type, _config);
-               break;
-       case ObjectDetectionTaskType::MOBILENET_V2_SSD:
-               _object_detection = make_unique<MobilenetV2Ssd<U> >(task_type, _config);
-               break;
-       default:
-               throw InvalidOperation("Invalid object detection task type.");
-       }
-       // TODO.
-}
-
-void ObjectDetectionAdapter::create(string model_name)
-{
-       if (model_name.empty())
-               model_name = _config->getDefaultModelName();
-
-       auto task_type = convertToTaskType(model_name);
-
-       if (_config->isPluginUsed()) {
-               const auto &plugin_name = _config->getPluginFileName();
-
-               _object_detection = make_unique<ObjectDetectionExternal>(task_type, plugin_name.c_str());
-               return;
-       }
-
-       _config->loadMetaFile(make_unique<ObjectDetectionParser>(static_cast<int>(task_type)));
-       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
-
-       switch (dataType) {
-       case MV_INFERENCE_DATA_UINT8:
-               create<unsigned char>(task_type);
-               break;
-       case MV_INFERENCE_DATA_FLOAT32:
-               create<float>(task_type);
-               break;
-       default:
-               throw InvalidOperation("Invalid object detection data type.");
-       }
-}
-
-ObjectDetectionTaskType ObjectDetectionAdapter::convertToTaskType(string 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 == "OD_TRIV2")
-               return ObjectDetectionTaskType::OD_TRIV2;
-       else if (model_name == "FD_TRIV2")
-               return ObjectDetectionTaskType::FD_TRIV2;
-       else if (model_name == "MOBILENET_V1_SSD")
-               return ObjectDetectionTaskType::MOBILENET_V1_SSD;
-       else if (model_name == "MOBILENET_V2_SSD")
-               return ObjectDetectionTaskType::MOBILENET_V2_SSD;
-       // TODO.
-
-       throw InvalidParameter("Invalid object detection model name.");
-}
-
-void ObjectDetectionAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                                 const string &model_name)
-{
-       try {
-               _config->setUserModel(model_file, meta_file, label_file);
-               create(model_name);
-       } catch (const BaseException &e) {
-               LOGW("A given model name is invalid so default task type will be used.");
-       }
-
-       if (model_file.empty() && meta_file.empty()) {
-               LOGW("Given model info is invalid so default model info will be used instead.");
-               return;
-       }
-}
-
-void ObjectDetectionAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       _object_detection->setEngineInfo(string(engine_type), string(device_type));
-}
-
-void ObjectDetectionAdapter::configure()
-{
-       _object_detection->configure();
-}
-
-unsigned int ObjectDetectionAdapter::getNumberOfEngines()
-{
-       return _object_detection->getNumberOfEngines();
-}
-
-const string &ObjectDetectionAdapter::getEngineType(unsigned int engine_index)
-{
-       return _object_detection->getEngineType(engine_index);
-}
-
-unsigned int ObjectDetectionAdapter::getNumberOfDevices(const string &engine_type)
-{
-       return _object_detection->getNumberOfDevices(engine_type);
-}
-
-const string &ObjectDetectionAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _object_detection->getDeviceType(engine_type, device_index);
-}
-
-void ObjectDetectionAdapter::prepare()
-{
-       _object_detection->prepare();
-}
-
-void ObjectDetectionAdapter::perform(InputBaseType &input)
-{
-       _object_detection->perform(input.inference_src);
-}
-
-OutputBaseType &ObjectDetectionAdapter::getOutput()
-{
-       return _object_detection->getOutput();
-}
-
-OutputBaseType &ObjectDetectionAdapter::getOutputCache()
-{
-       return _object_detection->getOutputCache();
-}
-
-void ObjectDetectionAdapter::performAsync(InputBaseType &input)
-{
-       _object_detection->performAsync(static_cast<ObjectDetectionInput &>(input));
-}
-
-}
-}
\ No newline at end of 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
deleted file mode 100644 (file)
index 1829cb7..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * 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(ObjectDetectionTaskType task_type);
-typedef void destroy_t(IObjectDetection *);
-
-ObjectDetectionExternal::ObjectDetectionExternal(ObjectDetectionTaskType task_type, const string &plugin_name)
-               : _plugin_handle(), _object_detection_plugin()
-{
-       // Load external object detection library.
-       LOGI("lib: %s", plugin_name.c_str());
-       _plugin_handle = dlopen(plugin_name.c_str(), 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(task_type);
-       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::setEngineInfo(string engine_type, string device_type)
-{
-       _object_detection_plugin->setEngineInfo(engine_type, device_type);
-}
-
-unsigned int ObjectDetectionExternal::getNumberOfEngines()
-{
-       return _object_detection_plugin->getNumberOfEngines();
-}
-
-const string &ObjectDetectionExternal::getEngineType(unsigned int engine_index)
-{
-       return _object_detection_plugin->getEngineType(engine_index);
-}
-
-unsigned int ObjectDetectionExternal::getNumberOfDevices(const string &engine_type)
-{
-       return _object_detection_plugin->getNumberOfDevices(engine_type);
-}
-
-const string &ObjectDetectionExternal::getDeviceType(const string &engine_type, const unsigned int device_index)
-{
-       return _object_detection_plugin->getDeviceType(engine_type, device_index);
-}
-
-void ObjectDetectionExternal::configure()
-{
-       _object_detection_plugin->configure();
-}
-
-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()
-{
-       _current_result = _object_detection_plugin->getOutput();
-
-       return _current_result;
-}
-
-ObjectDetectionResult &ObjectDetectionExternal::getOutputCache()
-{
-       return _current_result;
-}
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/include/IObjectDetection3d.h b/mv_machine_learning/object_detection_3d/include/IObjectDetection3d.h
new file mode 100644 (file)
index 0000000..1f1fa05
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * 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 __IOBJECT_DETECTION_3D_H__
+#define __IOBJECT_DETECTION_3D_H__
+
+#include <mv_common.h>
+
+#include "object_detection_3d_type.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class IObjectDetection3d
+{
+public:
+       virtual ~IObjectDetection3d() {};
+
+       virtual ObjectDetection3dTaskType getTaskType() = 0;
+       virtual void setEngineInfo(std::string engine_type_name, std::string device_type_name) = 0;
+       virtual unsigned int getNumberOfEngines() = 0;
+       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
+       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
+       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
+       virtual std::shared_ptr<MetaInfo> getInputMetaInfo() = 0;
+       virtual void configure() = 0;
+       virtual void prepare() = 0;
+       virtual void perform(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo) = 0;
+       virtual ObjectDetection3dResult &result() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/include/ObjectDetection3d.h b/mv_machine_learning/object_detection_3d/include/ObjectDetection3d.h
new file mode 100644 (file)
index 0000000..e2b347a
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * 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 __OBJECT_DETECTION_3D_H__
+#define __OBJECT_DETECTION_3D_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+#include "mv_private.h"
+
+#include "EngineConfig.h"
+#include "inference_engine_common_impl.h"
+#include "Inference.h"
+#include "object_detection_3d_type.h"
+#include "IObjectDetection3d.h"
+#include "MetaParser.h"
+#include "MvMlConfig.h"
+#include "ObjectDetection3dParser.h"
+#include "MvMlPreprocess.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class ObjectDetection3d : public IObjectDetection3d
+{
+private:
+       ObjectDetection3dTaskType _task_type;
+
+       void loadLabel();
+       void getEngineList();
+       void getDeviceList(const std::string &engine_type);
+
+protected:
+       std::unique_ptr<mediavision::inference::Inference> _inference;
+       std::shared_ptr<Config> _config;
+       std::vector<std::string> _labels;
+       std::vector<std::string> _valid_backends;
+       std::vector<std::string> _valid_devices;
+       Preprocess _preprocess;
+
+       void getOutputNames(std::vector<std::string> &names);
+       void getOutputTensor(std::string &target_name, std::vector<float> &tensor);
+       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
+       void inference(std::vector<std::vector<T> > &inputVectors);
+
+public:
+       ObjectDetection3d(ObjectDetection3dTaskType task_type, std::shared_ptr<Config> config);
+       virtual ~ObjectDetection3d() = default;
+
+       ObjectDetection3dTaskType getTaskType();
+       void setEngineInfo(std::string engine_type_name, std::string device_type_name);
+       unsigned int getNumberOfEngines();
+       const std::string &getEngineType(unsigned int engine_index);
+       unsigned int getNumberOfDevices(const std::string &engine_type);
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index);
+       std::shared_ptr<MetaInfo> getInputMetaInfo();
+       void configure();
+       void prepare();
+       void perform(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo);
+       virtual ObjectDetection3dResult &result() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/include/ObjectDetection3dAdapter.h b/mv_machine_learning/object_detection_3d/include/ObjectDetection3dAdapter.h
new file mode 100644 (file)
index 0000000..dbb89b6
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * 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 __OBJECT_DETECTION_3D_ADAPTER_H__
+#define __OBJECT_DETECTION_3D_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ITask.h"
+#include "MvMlConfig.h"
+#include "Objectron.h"
+#include "IObjectDetection3d.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class ObjectDetection3dAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<IObjectDetection3d> _object_detection_3d;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "object_detection_3d.json";
+
+       void create(const std::string &model_name);
+       template<typename U> void create(ObjectDetection3dTaskType task_type);
+       ObjectDetection3dTaskType convertToTaskType(std::string model_name);
+
+public:
+       ObjectDetection3dAdapter();
+       ~ObjectDetection3dAdapter();
+
+       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
+                                         const std::string &model_name) override;
+       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
+       unsigned int getNumberOfEngines() override;
+       const std::string &getEngineType(unsigned int engine_index) override;
+       unsigned int getNumberOfDevices(const std::string &engine_type) override;
+       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
+       void configure() override;
+       void prepare() override;
+       void perform(InputBaseType &input) override;
+       void performAsync(InputBaseType &input) override;
+       OutputBaseType &getOutput() override;
+       OutputBaseType &getOutputCache() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/include/Objectron.h b/mv_machine_learning/object_detection_3d/include/Objectron.h
new file mode 100644 (file)
index 0000000..3fa8875
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * 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 __OBJECTRON_H__
+#define __OBJECTRON_H__
+
+#include <memory>
+#include <mv_common.h>
+#include "mv_private.h"
+#include "MvMlConfig.h"
+
+#include "ObjectDetection3d.h"
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class Objectron : public ObjectDetection3d<T>
+{
+       using ObjectDetection3d<T>::_preprocess;
+       using ObjectDetection3d<T>::_inference;
+       using ObjectDetection3d<T>::_config;
+
+private:
+       ObjectDetection3dResult _result;
+
+public:
+       Objectron(ObjectDetection3dTaskType task_type, std::shared_ptr<Config> config);
+       ~Objectron();
+
+       ObjectDetection3dResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/include/iobject_detection_3d.h b/mv_machine_learning/object_detection_3d/include/iobject_detection_3d.h
deleted file mode 100644 (file)
index 1f1fa05..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * 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 __IOBJECT_DETECTION_3D_H__
-#define __IOBJECT_DETECTION_3D_H__
-
-#include <mv_common.h>
-
-#include "object_detection_3d_type.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class IObjectDetection3d
-{
-public:
-       virtual ~IObjectDetection3d() {};
-
-       virtual ObjectDetection3dTaskType getTaskType() = 0;
-       virtual void setEngineInfo(std::string engine_type_name, std::string device_type_name) = 0;
-       virtual unsigned int getNumberOfEngines() = 0;
-       virtual const std::string &getEngineType(unsigned int engine_index) = 0;
-       virtual unsigned int getNumberOfDevices(const std::string &engine_type) = 0;
-       virtual const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) = 0;
-       virtual std::shared_ptr<MetaInfo> getInputMetaInfo() = 0;
-       virtual void configure() = 0;
-       virtual void prepare() = 0;
-       virtual void perform(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo) = 0;
-       virtual ObjectDetection3dResult &result() = 0;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/include/object_detection_3d.h b/mv_machine_learning/object_detection_3d/include/object_detection_3d.h
deleted file mode 100644 (file)
index 9fc7306..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * 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 __OBJECT_DETECTION_3D_H__
-#define __OBJECT_DETECTION_3D_H__
-
-#include <mv_common.h>
-#include <mv_inference_type.h>
-#include "mv_private.h"
-
-#include "EngineConfig.h"
-#include "inference_engine_common_impl.h"
-#include "Inference.h"
-#include "object_detection_3d_type.h"
-#include "iobject_detection_3d.h"
-#include "MetaParser.h"
-#include "machine_learning_config.h"
-#include "ObjectDetection3dParser.h"
-#include "machine_learning_preprocess.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class ObjectDetection3d : public IObjectDetection3d
-{
-private:
-       ObjectDetection3dTaskType _task_type;
-
-       void loadLabel();
-       void getEngineList();
-       void getDeviceList(const std::string &engine_type);
-
-protected:
-       std::unique_ptr<mediavision::inference::Inference> _inference;
-       std::shared_ptr<MachineLearningConfig> _config;
-       std::vector<std::string> _labels;
-       std::vector<std::string> _valid_backends;
-       std::vector<std::string> _valid_devices;
-       Preprocess _preprocess;
-
-       void getOutputNames(std::vector<std::string> &names);
-       void getOutputTensor(std::string &target_name, std::vector<float> &tensor);
-       void preprocess(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo, std::vector<T> &inputVector);
-       void inference(std::vector<std::vector<T> > &inputVectors);
-
-public:
-       ObjectDetection3d(ObjectDetection3dTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       virtual ~ObjectDetection3d() = default;
-
-       ObjectDetection3dTaskType getTaskType();
-       void setEngineInfo(std::string engine_type_name, std::string device_type_name);
-       unsigned int getNumberOfEngines();
-       const std::string &getEngineType(unsigned int engine_index);
-       unsigned int getNumberOfDevices(const std::string &engine_type);
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index);
-       std::shared_ptr<MetaInfo> getInputMetaInfo();
-       void configure();
-       void prepare();
-       void perform(mv_source_h &mv_src, std::shared_ptr<MetaInfo> metaInfo);
-       virtual ObjectDetection3dResult &result() = 0;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/include/object_detection_3d_adapter.h b/mv_machine_learning/object_detection_3d/include/object_detection_3d_adapter.h
deleted file mode 100644 (file)
index b657b08..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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 __OBJECT_DETECTION_3D_ADAPTER_H__
-#define __OBJECT_DETECTION_3D_ADAPTER_H__
-
-#include <dlog.h>
-
-#include "EngineConfig.h"
-#include "itask.h"
-#include "machine_learning_config.h"
-#include "objectron.h"
-#include "iobject_detection_3d.h"
-
-namespace mediavision
-{
-namespace machine_learning
-{
-class ObjectDetection3dAdapter : public mediavision::common::ITask
-{
-private:
-       std::unique_ptr<IObjectDetection3d> _object_detection_3d;
-       std::shared_ptr<MachineLearningConfig> _config;
-       const std::string _config_file_name = "object_detection_3d.json";
-
-       void create(const std::string &model_name);
-       template<typename U> void create(ObjectDetection3dTaskType task_type);
-       ObjectDetection3dTaskType convertToTaskType(std::string model_name);
-
-public:
-       ObjectDetection3dAdapter();
-       ~ObjectDetection3dAdapter();
-
-       void setModelInfo(const std::string &model_file, const std::string &meta_file, const std::string &label_file,
-                                         const std::string &model_name) override;
-       void setEngineInfo(const std::string &engine_type, const std::string &device_type) override;
-       unsigned int getNumberOfEngines() override;
-       const std::string &getEngineType(unsigned int engine_index) override;
-       unsigned int getNumberOfDevices(const std::string &engine_type) override;
-       const std::string &getDeviceType(const std::string &engine_type, unsigned int device_index) override;
-       void configure() override;
-       void prepare() override;
-       void perform(InputBaseType &input) override;
-       void performAsync(InputBaseType &input) override;
-       OutputBaseType &getOutput() override;
-       OutputBaseType &getOutputCache() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
index bd866018f2ac2e8b738074bf10052d467cac4662..ecbfd0b83d6f16e6a4093bec880a2bc53eca6981 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <mv_common.h>
 #include <mv_inference_type.h>
-#include "MachineLearningType.h"
+#include "mv_ml_types.h"
 
 namespace mediavision
 {
diff --git a/mv_machine_learning/object_detection_3d/include/objectron.h b/mv_machine_learning/object_detection_3d/include/objectron.h
deleted file mode 100644 (file)
index ca0cf99..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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 __OBJECTRON_H__
-#define __OBJECTRON_H__
-
-#include <memory>
-#include <mv_common.h>
-#include "mv_private.h"
-#include "machine_learning_config.h"
-
-#include "object_detection_3d.h"
-#include <mv_inference_type.h>
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T> class Objectron : public ObjectDetection3d<T>
-{
-       using ObjectDetection3d<T>::_preprocess;
-       using ObjectDetection3d<T>::_inference;
-       using ObjectDetection3d<T>::_config;
-
-private:
-       ObjectDetection3dResult _result;
-
-public:
-       Objectron(ObjectDetection3dTaskType task_type, std::shared_ptr<MachineLearningConfig> config);
-       ~Objectron();
-
-       ObjectDetection3dResult &result() override;
-};
-
-} // machine_learning
-} // mediavision
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/src/ObjectDetection3d.cpp b/mv_machine_learning/object_detection_3d/src/ObjectDetection3d.cpp
new file mode 100644 (file)
index 0000000..120f647
--- /dev/null
@@ -0,0 +1,291 @@
+/**
+ * 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 <string.h>
+#include <fstream>
+#include <map>
+#include <memory>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "common.h"
+#include "ObjectDetection3d.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+ObjectDetection3d<T>::ObjectDetection3d(ObjectDetection3dTaskType task_type, std::shared_ptr<Config> config)
+               : _task_type(task_type), _config(config)
+{
+       _inference = make_unique<Inference>();
+}
+
+template<typename T> ObjectDetection3dTaskType ObjectDetection3d<T>::getTaskType()
+{
+       return _task_type;
+}
+
+template<typename T> void ObjectDetection3d<T>::getEngineList()
+{
+       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
+               auto backend = _inference->getSupportedInferenceBackend(idx);
+               // TODO. we need to describe what inference engines are supported by each Task API,
+               //       and based on it, below inference engine types should be checked
+               //       if a given type is supported by this Task API later. As of now, tflite only.
+               if (backend.second == true && backend.first.compare("tflite") == 0)
+                       _valid_backends.push_back(backend.first);
+       }
+}
+
+template<typename T> void ObjectDetection3d<T>::getDeviceList(const string &engine_type)
+{
+       // TODO. add device types available for a given engine type later.
+       //       In default, cpu and gpu only.
+       _valid_devices.push_back("cpu");
+       _valid_devices.push_back("gpu");
+}
+
+template<typename T>
+void ObjectDetection3d<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
+{
+       if (engine_type_name.empty() || device_type_name.empty())
+               throw InvalidParameter("Invalid engine info.");
+
+       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);
+
+       int engine_type = GetBackendType(engine_type_name);
+       int device_type = GetDeviceType(device_type_name);
+
+       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);
+}
+
+template<typename T> unsigned int ObjectDetection3d<T>::getNumberOfEngines()
+{
+       if (!_valid_backends.empty()) {
+               return _valid_backends.size();
+       }
+
+       getEngineList();
+       return _valid_backends.size();
+}
+
+template<typename T> const string &ObjectDetection3d<T>::getEngineType(unsigned int engine_index)
+{
+       if (!_valid_backends.empty()) {
+               if (_valid_backends.size() <= engine_index)
+                       throw InvalidParameter("Invalid engine index.");
+
+               return _valid_backends[engine_index];
+       }
+
+       getEngineList();
+
+       if (_valid_backends.size() <= engine_index)
+               throw InvalidParameter("Invalid engine index.");
+
+       return _valid_backends[engine_index];
+}
+
+template<typename T> unsigned int ObjectDetection3d<T>::getNumberOfDevices(const string &engine_type)
+{
+       if (!_valid_devices.empty()) {
+               return _valid_devices.size();
+       }
+
+       getDeviceList(engine_type);
+       return _valid_devices.size();
+}
+
+template<typename T>
+const string &ObjectDetection3d<T>::getDeviceType(const string &engine_type, const unsigned int device_index)
+{
+       if (!_valid_devices.empty()) {
+               if (_valid_devices.size() <= device_index)
+                       throw InvalidParameter("Invalid device index.");
+
+               return _valid_devices[device_index];
+       }
+
+       getDeviceList(engine_type);
+
+       if (_valid_devices.size() <= device_index)
+               throw InvalidParameter("Invalid device index.");
+
+       return _valid_devices[device_index];
+}
+
+template<typename T> void ObjectDetection3d<T>::loadLabel()
+{
+       if (_config->getLabelFilePath().empty())
+               return;
+
+       ifstream readFile { _config->getLabelFilePath() };
+
+       _labels.clear();
+
+       if (readFile.fail())
+               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
+
+       string line;
+
+       while (getline(readFile, line))
+               _labels.push_back(line);
+}
+
+template<typename T> void ObjectDetection3d<T>::configure()
+{
+       loadLabel();
+
+       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+template<typename T> void ObjectDetection3d<T>::prepare()
+{
+       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(_config->getOutputMetaMap());
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+       _inference->configureModelFiles("", _config->getModelFilePath(), "");
+
+       // Request to load model files to a backend engine.
+       ret = _inference->load();
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to load model files.");
+}
+
+template<typename T> shared_ptr<MetaInfo> ObjectDetection3d<T>::getInputMetaInfo()
+{
+       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
+       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
+
+       // TODO. consider using multiple tensors later.
+       if (tensor_info_map.size() != 1)
+               throw InvalidOperation("Input tensor count not invalid.");
+
+       auto tensor_buffer_iter = tensor_info_map.begin();
+
+       // Get the meta information corresponding to a given input tensor name.
+       return _config->getInputMetaMap()[tensor_buffer_iter->first];
+}
+
+template<typename T>
+void ObjectDetection3d<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
+{
+       LOGI("ENTER");
+
+       PreprocessConfig config = { false,
+                                                               metaInfo->colorSpace,
+                                                               metaInfo->dataType,
+                                                               metaInfo->getChannel(),
+                                                               metaInfo->getWidth(),
+                                                               metaInfo->getHeight() };
+
+       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
+       if (normalization) {
+               config.normalize = normalization->use;
+               config.mean = normalization->mean;
+               config.std = normalization->std;
+       }
+
+       auto quantization =
+                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
+       if (quantization) {
+               config.quantize = quantization->use;
+               config.scale = quantization->scale;
+               config.zeropoint = quantization->zeropoint;
+       }
+
+       _preprocess.setConfig(config);
+       _preprocess.run<T>(mv_src, inputVector);
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ObjectDetection3d<T>::inference(vector<vector<T> > &inputVectors)
+{
+       LOGI("ENTER");
+
+       int ret = _inference->run<T>(inputVectors);
+       if (ret != MEDIA_VISION_ERROR_NONE)
+               throw InvalidOperation("Fail to run inference");
+
+       LOGI("LEAVE");
+}
+
+template<typename T> void ObjectDetection3d<T>::perform(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo)
+{
+       vector<T> inputVector;
+
+       preprocess(mv_src, metaInfo, inputVector);
+
+       vector<vector<T> > inputVectors = { inputVector };
+
+       inference(inputVectors);
+}
+
+template<typename T> void ObjectDetection3d<T>::getOutputNames(vector<string> &names)
+{
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+
+       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
+               names.push_back(it->first);
+}
+
+template<typename T> void ObjectDetection3d<T>::getOutputTensor(string &target_name, vector<float> &tensor)
+{
+       LOGI("ENTER");
+
+       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
+
+       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
+       if (!tensor_buffer)
+               throw InvalidOperation("Fail to get tensor buffer.");
+
+       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
+
+       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
+
+       LOGI("LEAVE");
+}
+
+template class ObjectDetection3d<float>;
+template class ObjectDetection3d<unsigned char>;
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/src/ObjectDetection3dAdapter.cpp b/mv_machine_learning/object_detection_3d/src/ObjectDetection3dAdapter.cpp
new file mode 100644 (file)
index 0000000..bb2bace
--- /dev/null
@@ -0,0 +1,155 @@
+/**
+ * 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 "MvMlException.h"
+#include "ObjectDetection3dAdapter.h"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+ObjectDetection3dAdapter::ObjectDetection3dAdapter()
+{
+       _config = make_shared<Config>();
+       _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+ObjectDetection3dAdapter::~ObjectDetection3dAdapter()
+{}
+
+template<typename U> void ObjectDetection3dAdapter::create(ObjectDetection3dTaskType task_type)
+{
+       switch (task_type) {
+       case ObjectDetection3dTaskType::OBJECTRON:
+               _object_detection_3d = make_unique<Objectron<U> >(task_type, _config);
+               break;
+       default:
+               throw InvalidOperation("Invalid object detection 3d task type.");
+       }
+}
+
+void ObjectDetection3dAdapter::create(const string &model_name)
+{
+       ObjectDetection3dTaskType task_type = convertToTaskType(model_name);
+       _config->loadMetaFile(make_unique<ObjectDetection3dParser>(static_cast<int>(task_type)));
+       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
+
+       switch (dataType) {
+       case MV_INFERENCE_DATA_UINT8:
+               create<unsigned char>(task_type);
+               break;
+       case MV_INFERENCE_DATA_FLOAT32:
+               create<float>(task_type);
+               break;
+       default:
+               throw InvalidOperation("Invalid object detection 3d data type.");
+       }
+}
+
+ObjectDetection3dTaskType ObjectDetection3dAdapter::convertToTaskType(string 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 == "OBJECTRON")
+               return ObjectDetection3dTaskType::OBJECTRON;
+
+       throw InvalidParameter("Invalid object detection 3d model name.");
+}
+
+void ObjectDetection3dAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
+                                                                                       const string &model_name)
+{
+       try {
+               _config->setUserModel(model_file, meta_file, label_file);
+               create(model_name);
+       } catch (const BaseException &e) {
+               LOGW("A given model name is invalid so default task type will be used.");
+       }
+
+       if (model_file.empty() && meta_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
+}
+
+void ObjectDetection3dAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _object_detection_3d->setEngineInfo(string(engine_type), string(device_type));
+}
+
+void ObjectDetection3dAdapter::configure()
+{
+       _object_detection_3d->configure();
+}
+
+unsigned int ObjectDetection3dAdapter::getNumberOfEngines()
+{
+       return _object_detection_3d->getNumberOfEngines();
+}
+
+const string &ObjectDetection3dAdapter::getEngineType(unsigned int engine_index)
+{
+       return _object_detection_3d->getEngineType(engine_index);
+}
+
+unsigned int ObjectDetection3dAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _object_detection_3d->getNumberOfDevices(engine_type);
+}
+
+const string &ObjectDetection3dAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _object_detection_3d->getDeviceType(engine_type, device_index);
+}
+
+void ObjectDetection3dAdapter::prepare()
+{
+       _object_detection_3d->prepare();
+}
+
+void ObjectDetection3dAdapter::perform(InputBaseType &input)
+{
+       shared_ptr<MetaInfo> metaInfo = _object_detection_3d->getInputMetaInfo();
+       _object_detection_3d->perform(input.inference_src, metaInfo);
+}
+
+void ObjectDetection3dAdapter::performAsync(InputBaseType &input)
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+OutputBaseType &ObjectDetection3dAdapter::getOutput()
+{
+       return _object_detection_3d->result();
+}
+
+OutputBaseType &ObjectDetection3dAdapter::getOutputCache()
+{
+       throw InvalidOperation("Not support yet.");
+}
+
+}
+}
\ No newline at end of file
index 373ef5c23e4c2ecdac0c8b720394e98adc7f2439..37d2bf9f2b871bd55af1b80e3ba74521ac3c669b 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include <iostream>
-#include "machine_learning_exception.h"
+#include "MvMlException.h"
 #include "ObjectDetection3dParser.h"
 
 using namespace std;
diff --git a/mv_machine_learning/object_detection_3d/src/Objectron.cpp b/mv_machine_learning/object_detection_3d/src/Objectron.cpp
new file mode 100644 (file)
index 0000000..cc0bdb1
--- /dev/null
@@ -0,0 +1,92 @@
+/**
+ * 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 <string.h>
+#include <map>
+#include <algorithm>
+
+#include "MvMlException.h"
+#include "Objectron.h"
+#include "Postprocess.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T>
+Objectron<T>::Objectron(ObjectDetection3dTaskType task_type, std::shared_ptr<Config> config)
+               : ObjectDetection3d<T>(task_type, config), _result()
+{}
+
+template<typename T> Objectron<T>::~Objectron()
+{}
+
+template<typename T> ObjectDetection3dResult &Objectron<T>::result()
+{
+       vector<string> names;
+
+       ObjectDetection3d<T>::getOutputNames(names);
+
+       vector<float> keypoints;
+
+       ObjectDetection3d<T>::getOutputTensor(names[1], keypoints);
+
+       size_t output_size = keypoints.size();
+
+       Postprocess postprocess({ _preprocess.getImageWidth()[0], _preprocess.getImageHeight()[0],
+                                                         _inference->getInputWidth(), _inference->getInputHeight() });
+
+       _result = ObjectDetection3dResult();
+
+       for (size_t idx = 0; idx < output_size; idx += 2) {
+               _result.x_vec.push_back(postprocess.getScaledX(keypoints[idx]));
+               _result.y_vec.push_back(postprocess.getScaledY(keypoints[idx + 1]));
+       }
+
+       _result.number_of_points = output_size / 2;
+
+       vector<float> probability_vec;
+
+       // names[0] is "Identity"
+       ObjectDetection3d<T>::getOutputTensor(names[0], probability_vec);
+
+       _result.probability = static_cast<unsigned int>(probability_vec[0] * 100);
+
+       try {
+               // names[1] is "Identity_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)
+                       _result.edge_index_vec.push_back({ decodingBox->edges[idx], decodingBox->edges[idx + 1] });
+
+               _result.number_of_edges = decodingBox->edges.size();
+       } catch (const std::exception &e) {
+               throw InvalidOperation("Invalid meta info access.");
+       }
+
+       return _result;
+}
+
+template class Objectron<float>;
+template class Objectron<unsigned char>;
+
+}
+}
index ff238ce679d563ba15e305a76889c575e9d0e188..d43b5c489d61b647f44dd1e537e57dc9dc182985 100644 (file)
 
 #include "mv_private.h"
 #include "mv_feature_key.h"
-#include "itask.h"
+#include "ITask.h"
 #include "mv_object_detection_3d_internal.h"
-#include "object_detection_3d_adapter.h"
-#include "machine_learning_exception.h"
-#include "MachineLearningNative.h"
+#include "ObjectDetection3dAdapter.h"
+#include "MvMlException.h"
+#include "native_capi.h"
 #include "object_detection_3d_type.h"
-#include "context.h"
+#include "Context.h"
 
 #include <new>
 #include <unistd.h>
diff --git a/mv_machine_learning/object_detection_3d/src/object_detection_3d.cpp b/mv_machine_learning/object_detection_3d/src/object_detection_3d.cpp
deleted file mode 100644 (file)
index 46ade6d..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/**
- * 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 <string.h>
-#include <fstream>
-#include <map>
-#include <memory>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "mv_machine_learning_common.h"
-#include "object_detection_3d.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace MediaVision::Common;
-using namespace mediavision::common;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-ObjectDetection3d<T>::ObjectDetection3d(ObjectDetection3dTaskType task_type,
-                                                                               std::shared_ptr<MachineLearningConfig> config)
-               : _task_type(task_type), _config(config)
-{
-       _inference = make_unique<Inference>();
-}
-
-template<typename T> ObjectDetection3dTaskType ObjectDetection3d<T>::getTaskType()
-{
-       return _task_type;
-}
-
-template<typename T> void ObjectDetection3d<T>::getEngineList()
-{
-       for (auto idx = MV_INFERENCE_BACKEND_NONE + 1; idx < MV_INFERENCE_BACKEND_MAX; ++idx) {
-               auto backend = _inference->getSupportedInferenceBackend(idx);
-               // TODO. we need to describe what inference engines are supported by each Task API,
-               //       and based on it, below inference engine types should be checked
-               //       if a given type is supported by this Task API later. As of now, tflite only.
-               if (backend.second == true && backend.first.compare("tflite") == 0)
-                       _valid_backends.push_back(backend.first);
-       }
-}
-
-template<typename T> void ObjectDetection3d<T>::getDeviceList(const string &engine_type)
-{
-       // TODO. add device types available for a given engine type later.
-       //       In default, cpu and gpu only.
-       _valid_devices.push_back("cpu");
-       _valid_devices.push_back("gpu");
-}
-
-template<typename T>
-void ObjectDetection3d<T>::setEngineInfo(std::string engine_type_name, std::string device_type_name)
-{
-       if (engine_type_name.empty() || device_type_name.empty())
-               throw InvalidParameter("Invalid engine info.");
-
-       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);
-
-       int engine_type = GetBackendType(engine_type_name);
-       int device_type = GetDeviceType(device_type_name);
-
-       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);
-}
-
-template<typename T> unsigned int ObjectDetection3d<T>::getNumberOfEngines()
-{
-       if (!_valid_backends.empty()) {
-               return _valid_backends.size();
-       }
-
-       getEngineList();
-       return _valid_backends.size();
-}
-
-template<typename T> const string &ObjectDetection3d<T>::getEngineType(unsigned int engine_index)
-{
-       if (!_valid_backends.empty()) {
-               if (_valid_backends.size() <= engine_index)
-                       throw InvalidParameter("Invalid engine index.");
-
-               return _valid_backends[engine_index];
-       }
-
-       getEngineList();
-
-       if (_valid_backends.size() <= engine_index)
-               throw InvalidParameter("Invalid engine index.");
-
-       return _valid_backends[engine_index];
-}
-
-template<typename T> unsigned int ObjectDetection3d<T>::getNumberOfDevices(const string &engine_type)
-{
-       if (!_valid_devices.empty()) {
-               return _valid_devices.size();
-       }
-
-       getDeviceList(engine_type);
-       return _valid_devices.size();
-}
-
-template<typename T>
-const string &ObjectDetection3d<T>::getDeviceType(const string &engine_type, const unsigned int device_index)
-{
-       if (!_valid_devices.empty()) {
-               if (_valid_devices.size() <= device_index)
-                       throw InvalidParameter("Invalid device index.");
-
-               return _valid_devices[device_index];
-       }
-
-       getDeviceList(engine_type);
-
-       if (_valid_devices.size() <= device_index)
-               throw InvalidParameter("Invalid device index.");
-
-       return _valid_devices[device_index];
-}
-
-template<typename T> void ObjectDetection3d<T>::loadLabel()
-{
-       if (_config->getLabelFilePath().empty())
-               return;
-
-       ifstream readFile { _config->getLabelFilePath() };
-
-       _labels.clear();
-
-       if (readFile.fail())
-               throw InvalidOperation("Fail to open " + _config->getLabelFilePath() + " file.");
-
-       string line;
-
-       while (getline(readFile, line))
-               _labels.push_back(line);
-}
-
-template<typename T> void ObjectDetection3d<T>::configure()
-{
-       loadLabel();
-
-       int ret = _inference->bind(_config->getBackendType(), _config->getTargetDeviceType());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to bind a backend engine.");
-}
-
-template<typename T> void ObjectDetection3d<T>::prepare()
-{
-       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(_config->getOutputMetaMap());
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to configure output tensor info from meta file.");
-
-       _inference->configureModelFiles("", _config->getModelFilePath(), "");
-
-       // Request to load model files to a backend engine.
-       ret = _inference->load();
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to load model files.");
-}
-
-template<typename T> shared_ptr<MetaInfo> ObjectDetection3d<T>::getInputMetaInfo()
-{
-       TensorBuffer &tensor_buffer = _inference->getInputTensorBuffer();
-       IETensorBuffer &tensor_info_map = tensor_buffer.getIETensorBuffer();
-
-       // TODO. consider using multiple tensors later.
-       if (tensor_info_map.size() != 1)
-               throw InvalidOperation("Input tensor count not invalid.");
-
-       auto tensor_buffer_iter = tensor_info_map.begin();
-
-       // Get the meta information corresponding to a given input tensor name.
-       return _config->getInputMetaMap()[tensor_buffer_iter->first];
-}
-
-template<typename T>
-void ObjectDetection3d<T>::preprocess(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo, vector<T> &inputVector)
-{
-       LOGI("ENTER");
-
-       PreprocessConfig config = { false,
-                                                               metaInfo->colorSpace,
-                                                               metaInfo->dataType,
-                                                               metaInfo->getChannel(),
-                                                               metaInfo->getWidth(),
-                                                               metaInfo->getHeight() };
-
-       auto normalization = static_pointer_cast<DecodingNormal>(metaInfo->decodingTypeMap.at(DecodingType::NORMAL));
-       if (normalization) {
-               config.normalize = normalization->use;
-               config.mean = normalization->mean;
-               config.std = normalization->std;
-       }
-
-       auto quantization =
-                       static_pointer_cast<DecodingQuantization>(metaInfo->decodingTypeMap.at(DecodingType::QUANTIZATION));
-       if (quantization) {
-               config.quantize = quantization->use;
-               config.scale = quantization->scale;
-               config.zeropoint = quantization->zeropoint;
-       }
-
-       _preprocess.setConfig(config);
-       _preprocess.run<T>(mv_src, inputVector);
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ObjectDetection3d<T>::inference(vector<vector<T> > &inputVectors)
-{
-       LOGI("ENTER");
-
-       int ret = _inference->run<T>(inputVectors);
-       if (ret != MEDIA_VISION_ERROR_NONE)
-               throw InvalidOperation("Fail to run inference");
-
-       LOGI("LEAVE");
-}
-
-template<typename T> void ObjectDetection3d<T>::perform(mv_source_h &mv_src, shared_ptr<MetaInfo> metaInfo)
-{
-       vector<T> inputVector;
-
-       preprocess(mv_src, metaInfo, inputVector);
-
-       vector<vector<T> > inputVectors = { inputVector };
-
-       inference(inputVectors);
-}
-
-template<typename T> void ObjectDetection3d<T>::getOutputNames(vector<string> &names)
-{
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-       IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
-
-       for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++)
-               names.push_back(it->first);
-}
-
-template<typename T> void ObjectDetection3d<T>::getOutputTensor(string &target_name, vector<float> &tensor)
-{
-       LOGI("ENTER");
-
-       TensorBuffer &tensor_buffer_obj = _inference->getOutputTensorBuffer();
-
-       inference_engine_tensor_buffer *tensor_buffer = tensor_buffer_obj.getTensorBuffer(target_name);
-       if (!tensor_buffer)
-               throw InvalidOperation("Fail to get tensor buffer.");
-
-       auto raw_buffer = static_cast<float *>(tensor_buffer->buffer);
-
-       copy(&raw_buffer[0], &raw_buffer[tensor_buffer->size / sizeof(float)], back_inserter(tensor));
-
-       LOGI("LEAVE");
-}
-
-template class ObjectDetection3d<float>;
-template class ObjectDetection3d<unsigned char>;
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/src/object_detection_3d_adapter.cpp b/mv_machine_learning/object_detection_3d/src/object_detection_3d_adapter.cpp
deleted file mode 100644 (file)
index 74e6af3..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/**
- * 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 "object_detection_3d_adapter.h"
-
-using namespace std;
-using namespace MediaVision::Common;
-using namespace mediavision::machine_learning;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-ObjectDetection3dAdapter::ObjectDetection3dAdapter()
-{
-       _config = make_shared<MachineLearningConfig>();
-       _config->parseConfigFile(_config_file_name);
-
-       create(_config->getDefaultModelName());
-}
-
-ObjectDetection3dAdapter::~ObjectDetection3dAdapter()
-{}
-
-template<typename U> void ObjectDetection3dAdapter::create(ObjectDetection3dTaskType task_type)
-{
-       switch (task_type) {
-       case ObjectDetection3dTaskType::OBJECTRON:
-               _object_detection_3d = make_unique<Objectron<U> >(task_type, _config);
-               break;
-       default:
-               throw InvalidOperation("Invalid object detection 3d task type.");
-       }
-}
-
-void ObjectDetection3dAdapter::create(const string &model_name)
-{
-       ObjectDetection3dTaskType task_type = convertToTaskType(model_name);
-       _config->loadMetaFile(make_unique<ObjectDetection3dParser>(static_cast<int>(task_type)));
-       mv_inference_data_type_e dataType = _config->getInputMetaMap().begin()->second->dataType;
-
-       switch (dataType) {
-       case MV_INFERENCE_DATA_UINT8:
-               create<unsigned char>(task_type);
-               break;
-       case MV_INFERENCE_DATA_FLOAT32:
-               create<float>(task_type);
-               break;
-       default:
-               throw InvalidOperation("Invalid object detection 3d data type.");
-       }
-}
-
-ObjectDetection3dTaskType ObjectDetection3dAdapter::convertToTaskType(string 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 == "OBJECTRON")
-               return ObjectDetection3dTaskType::OBJECTRON;
-
-       throw InvalidParameter("Invalid object detection 3d model name.");
-}
-
-void ObjectDetection3dAdapter::setModelInfo(const string &model_file, const string &meta_file, const string &label_file,
-                                                                                       const string &model_name)
-{
-       try {
-               _config->setUserModel(model_file, meta_file, label_file);
-               create(model_name);
-       } catch (const BaseException &e) {
-               LOGW("A given model name is invalid so default task type will be used.");
-       }
-
-       if (model_file.empty() && meta_file.empty()) {
-               LOGW("Given model info is invalid so default model info will be used instead.");
-               return;
-       }
-}
-
-void ObjectDetection3dAdapter::setEngineInfo(const string &engine_type, const string &device_type)
-{
-       _object_detection_3d->setEngineInfo(string(engine_type), string(device_type));
-}
-
-void ObjectDetection3dAdapter::configure()
-{
-       _object_detection_3d->configure();
-}
-
-unsigned int ObjectDetection3dAdapter::getNumberOfEngines()
-{
-       return _object_detection_3d->getNumberOfEngines();
-}
-
-const string &ObjectDetection3dAdapter::getEngineType(unsigned int engine_index)
-{
-       return _object_detection_3d->getEngineType(engine_index);
-}
-
-unsigned int ObjectDetection3dAdapter::getNumberOfDevices(const string &engine_type)
-{
-       return _object_detection_3d->getNumberOfDevices(engine_type);
-}
-
-const string &ObjectDetection3dAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
-{
-       return _object_detection_3d->getDeviceType(engine_type, device_index);
-}
-
-void ObjectDetection3dAdapter::prepare()
-{
-       _object_detection_3d->prepare();
-}
-
-void ObjectDetection3dAdapter::perform(InputBaseType &input)
-{
-       shared_ptr<MetaInfo> metaInfo = _object_detection_3d->getInputMetaInfo();
-       _object_detection_3d->perform(input.inference_src, metaInfo);
-}
-
-void ObjectDetection3dAdapter::performAsync(InputBaseType &input)
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-OutputBaseType &ObjectDetection3dAdapter::getOutput()
-{
-       return _object_detection_3d->result();
-}
-
-OutputBaseType &ObjectDetection3dAdapter::getOutputCache()
-{
-       throw InvalidOperation("Not support yet.");
-}
-
-}
-}
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection_3d/src/objectron.cpp b/mv_machine_learning/object_detection_3d/src/objectron.cpp
deleted file mode 100644 (file)
index 2452866..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * 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 <string.h>
-#include <map>
-#include <algorithm>
-
-#include "machine_learning_exception.h"
-#include "objectron.h"
-#include "Postprocess.h"
-
-using namespace std;
-using namespace mediavision::inference;
-using namespace mediavision::machine_learning::exception;
-
-namespace mediavision
-{
-namespace machine_learning
-{
-template<typename T>
-Objectron<T>::Objectron(ObjectDetection3dTaskType task_type, std::shared_ptr<MachineLearningConfig> config)
-               : ObjectDetection3d<T>(task_type, config), _result()
-{}
-
-template<typename T> Objectron<T>::~Objectron()
-{}
-
-template<typename T> ObjectDetection3dResult &Objectron<T>::result()
-{
-       vector<string> names;
-
-       ObjectDetection3d<T>::getOutputNames(names);
-
-       vector<float> keypoints;
-
-       ObjectDetection3d<T>::getOutputTensor(names[1], keypoints);
-
-       size_t output_size = keypoints.size();
-
-       Postprocess postprocess({ _preprocess.getImageWidth()[0], _preprocess.getImageHeight()[0],
-                                                         _inference->getInputWidth(), _inference->getInputHeight() });
-
-       _result = ObjectDetection3dResult();
-
-       for (size_t idx = 0; idx < output_size; idx += 2) {
-               _result.x_vec.push_back(postprocess.getScaledX(keypoints[idx]));
-               _result.y_vec.push_back(postprocess.getScaledY(keypoints[idx + 1]));
-       }
-
-       _result.number_of_points = output_size / 2;
-
-       vector<float> probability_vec;
-
-       // names[0] is "Identity"
-       ObjectDetection3d<T>::getOutputTensor(names[0], probability_vec);
-
-       _result.probability = static_cast<unsigned int>(probability_vec[0] * 100);
-
-       try {
-               // names[1] is "Identity_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)
-                       _result.edge_index_vec.push_back({ decodingBox->edges[idx], decodingBox->edges[idx + 1] });
-
-               _result.number_of_edges = decodingBox->edges.size();
-       } catch (const std::exception &e) {
-               throw InvalidOperation("Invalid meta info access.");
-       }
-
-       return _result;
-}
-
-template class Objectron<float>;
-template class Objectron<unsigned char>;
-
-}
-}
diff --git a/mv_machine_learning/training/include/DataSetManager.h b/mv_machine_learning/training/include/DataSetManager.h
new file mode 100644 (file)
index 0000000..b526e7e
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * 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 __DATA_SET_MANAGER_H__
+#define __DATA_SET_MANAGER_H__
+
+#include <fstream>
+#include <vector>
+#include <map>
+
+#include "FeatureVectorManager.h"
+
+class DataSetManager
+{
+protected:
+       std::map<unsigned int, unsigned int> _fv_cnt_per_label;
+       std::vector<std::vector<float> > _data;
+       std::vector<std::vector<float> > _labels;
+       std::vector<unsigned int> _label_index;
+       size_t _feature_vector_size {};
+       size_t _label_count {};
+
+public:
+       DataSetManager();
+       virtual ~DataSetManager();
+
+       void clear();
+       bool isFeatureVectorDuplicated(const std::vector<float> &vec);
+       std::vector<std::vector<float> > &getData(void);
+       std::vector<std::vector<float> > &getLabel(void);
+       size_t getFeaVecSize(void);
+       std::vector<unsigned int> &getLabelIdx(void);
+
+       virtual bool isFeatureVectorAllowed(unsigned int label_idx) = 0;
+       virtual void loadDataSet(const std::string &file_name, unsigned int new_label_cnt) = 0;
+       virtual void addDataSet(std::vector<float> &feature_vec, unsigned int label_idx, unsigned int label_cnt) = 0;
+};
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/training/include/FeatureVectorManager.h b/mv_machine_learning/training/include/FeatureVectorManager.h
new file mode 100644 (file)
index 0000000..5dce36f
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * 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 __FEATURE_VECTOR_MANAGER_H__
+#define __FEATURE_VECTOR_MANAGER_H__
+
+#include <string>
+#include <vector>
+
+#include <opencv2/opencv.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+
+#include "file_util.h"
+
+struct FeaVecHeader {
+       unsigned int signature;
+       size_t feature_size;
+       size_t label_cnt;
+       unsigned int data_set_cnt;
+};
+
+class FeatureVectorManager
+{
+protected:
+       std::string _feature_vector_file;
+
+public:
+       FeatureVectorManager(const std::string feature_vector_file = "feature_vector_file.dat");
+       virtual ~FeatureVectorManager() = default;
+
+       const std::string &getFileName();
+
+       static void getVecFromImg(const std::string image_file, std::vector<float> &vec, unsigned int width,
+                                                         unsigned int height);
+       static void getVecFromRGB(unsigned char *in_data, std::vector<float> &vec, unsigned int width, unsigned int height,
+                                                         size_t re_width, size_t re_height);
+       static void getVecFromXRGB(unsigned char *in_data, std::vector<float> &vec, unsigned int in_width,
+                                                          unsigned int in_height, unsigned int re_width, unsigned int re_height);
+
+       virtual void updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) = 0;
+       virtual void storeData(std::vector<std::vector<float> > &features_vec, std::vector<unsigned int> &label_index) = 0;
+       virtual void remove() = 0;
+
+       static constexpr unsigned int feature_vector_signature = 0xFEA09841;
+};
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/training/include/LabelManager.h b/mv_machine_learning/training/include/LabelManager.h
new file mode 100644 (file)
index 0000000..325c1ab
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * 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 __LABEL_MANAGER_H__
+#define __LABEL_MANAGER_H__
+
+#include <string.h>
+#include <iostream>
+#include <fstream>
+#include <istream>
+#include <algorithm>
+#include <vector>
+#include <map>
+
+#include "file_util.h"
+
+class LabelManager
+{
+private:
+       std::vector<std::string> _labels;
+       std::string _label_file;
+       float _decision_threshold;
+       static constexpr float _decision_weight = 0.01;
+
+public:
+       LabelManager(std::string label_file, double decision_threshold);
+       ~LabelManager();
+       float getDecisionThreshold();
+       float getDecisionWeight();
+       unsigned int getLabelIndex(const std::string &given_label);
+       bool isExist(const std::string given_label);
+       void removeLabel(const std::string given_label);
+       void getLabelString(std::string &label, const int idx);
+       void addLabelToFile(std::string given_label);
+       void importLabel(void);
+       const std::vector<std::string> &getLabels(void);
+       size_t getMaxLabel();
+       void removeFile();
+       bool isEmpty();
+};
+
+#endif
diff --git a/mv_machine_learning/training/include/TrainingModel.h b/mv_machine_learning/training/include/TrainingModel.h
new file mode 100644 (file)
index 0000000..f153fc6
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * 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 __TRAINING_MODEL_H__
+#define __TRAINING_MODEL_H__
+
+#include <iostream>
+#include <map>
+
+#include <mv_inference_type.h>
+
+#include "training_engine_error.h"
+#include "training_engine_common_impl.h"
+#include "inference_engine_common_impl.h"
+#include "DataSetManager.h"
+#include "FeatureVectorManager.h"
+
+struct TrainingEngineBackendInfo {
+       std::vector<std::string> input_layer_names;
+       std::vector<std::string> output_layer_names;
+       std::vector<inference_engine_tensor_info> input_tensor_info;
+       std::vector<inference_engine_tensor_info> output_tensor_info;
+       training_engine_optimizer_property optimizer_property {};
+       training_engine_compile_property compile_property {};
+};
+
+class TrainingModel
+{
+private:
+       virtual void saveModel(const std::string file_path) = 0;
+       virtual void removeModel(const std::string file_path) = 0;
+
+protected:
+       std::unique_ptr<TrainingEngineInterface::Common::TrainingEngineCommon> _training;
+       std::unique_ptr<training_engine_model> _model;
+       std::unique_ptr<training_engine_dataset> _data_set;
+       std::string _internal_model_file;
+
+public:
+       TrainingModel(const training_backend_type_e backend_type, const training_target_type_e target_type,
+                                 const std::vector<size_t> input_tensor_shape, const std::string internal_model_file);
+       virtual ~TrainingModel();
+
+       void applyDataSet(std::unique_ptr<DataSetManager> &data_set);
+       void clearDataSet();
+       void compile();
+       void train();
+       void removeModel();
+       void getWeights(float **weights, size_t *size, std::string name);
+
+       virtual void configureModel(int num_of_class) = 0;
+       virtual TrainingEngineBackendInfo &getTrainingEngineInfo() = 0;
+};
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/training/include/data_set_manager.h b/mv_machine_learning/training/include/data_set_manager.h
deleted file mode 100644 (file)
index e59d9c5..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * 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 __DATA_SET_MANAGER_H__
-#define __DATA_SET_MANAGER_H__
-
-#include <fstream>
-#include <vector>
-#include <map>
-
-#include "feature_vector_manager.h"
-
-class DataSetManager
-{
-protected:
-       std::map<unsigned int, unsigned int> _fv_cnt_per_label;
-       std::vector<std::vector<float> > _data;
-       std::vector<std::vector<float> > _labels;
-       std::vector<unsigned int> _label_index;
-       size_t _feature_vector_size {};
-       size_t _label_count {};
-
-public:
-       DataSetManager();
-       virtual ~DataSetManager();
-
-       void clear();
-       bool isFeatureVectorDuplicated(const std::vector<float> &vec);
-       std::vector<std::vector<float> > &getData(void);
-       std::vector<std::vector<float> > &getLabel(void);
-       size_t getFeaVecSize(void);
-       std::vector<unsigned int> &getLabelIdx(void);
-
-       virtual bool isFeatureVectorAllowed(unsigned int label_idx) = 0;
-       virtual void loadDataSet(const std::string &file_name, unsigned int new_label_cnt) = 0;
-       virtual void addDataSet(std::vector<float> &feature_vec, unsigned int label_idx, unsigned int label_cnt) = 0;
-};
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/training/include/feature_vector_manager.h b/mv_machine_learning/training/include/feature_vector_manager.h
deleted file mode 100644 (file)
index 5dce36f..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * 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 __FEATURE_VECTOR_MANAGER_H__
-#define __FEATURE_VECTOR_MANAGER_H__
-
-#include <string>
-#include <vector>
-
-#include <opencv2/opencv.hpp>
-#include <opencv2/imgproc/imgproc.hpp>
-
-#include "file_util.h"
-
-struct FeaVecHeader {
-       unsigned int signature;
-       size_t feature_size;
-       size_t label_cnt;
-       unsigned int data_set_cnt;
-};
-
-class FeatureVectorManager
-{
-protected:
-       std::string _feature_vector_file;
-
-public:
-       FeatureVectorManager(const std::string feature_vector_file = "feature_vector_file.dat");
-       virtual ~FeatureVectorManager() = default;
-
-       const std::string &getFileName();
-
-       static void getVecFromImg(const std::string image_file, std::vector<float> &vec, unsigned int width,
-                                                         unsigned int height);
-       static void getVecFromRGB(unsigned char *in_data, std::vector<float> &vec, unsigned int width, unsigned int height,
-                                                         size_t re_width, size_t re_height);
-       static void getVecFromXRGB(unsigned char *in_data, std::vector<float> &vec, unsigned int in_width,
-                                                          unsigned int in_height, unsigned int re_width, unsigned int re_height);
-
-       virtual void updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) = 0;
-       virtual void storeData(std::vector<std::vector<float> > &features_vec, std::vector<unsigned int> &label_index) = 0;
-       virtual void remove() = 0;
-
-       static constexpr unsigned int feature_vector_signature = 0xFEA09841;
-};
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/training/include/label_manager.h b/mv_machine_learning/training/include/label_manager.h
deleted file mode 100644 (file)
index 325c1ab..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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 __LABEL_MANAGER_H__
-#define __LABEL_MANAGER_H__
-
-#include <string.h>
-#include <iostream>
-#include <fstream>
-#include <istream>
-#include <algorithm>
-#include <vector>
-#include <map>
-
-#include "file_util.h"
-
-class LabelManager
-{
-private:
-       std::vector<std::string> _labels;
-       std::string _label_file;
-       float _decision_threshold;
-       static constexpr float _decision_weight = 0.01;
-
-public:
-       LabelManager(std::string label_file, double decision_threshold);
-       ~LabelManager();
-       float getDecisionThreshold();
-       float getDecisionWeight();
-       unsigned int getLabelIndex(const std::string &given_label);
-       bool isExist(const std::string given_label);
-       void removeLabel(const std::string given_label);
-       void getLabelString(std::string &label, const int idx);
-       void addLabelToFile(std::string given_label);
-       void importLabel(void);
-       const std::vector<std::string> &getLabels(void);
-       size_t getMaxLabel();
-       void removeFile();
-       bool isEmpty();
-};
-
-#endif
diff --git a/mv_machine_learning/training/include/training_model.h b/mv_machine_learning/training/include/training_model.h
deleted file mode 100644 (file)
index 97f87aa..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * 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 __TRAINING_MODEL_H__
-#define __TRAINING_MODEL_H__
-
-#include <iostream>
-#include <map>
-
-#include <mv_inference_type.h>
-
-#include "training_engine_error.h"
-#include "training_engine_common_impl.h"
-#include "inference_engine_common_impl.h"
-#include "data_set_manager.h"
-#include "feature_vector_manager.h"
-
-struct TrainingEngineBackendInfo {
-       std::vector<std::string> input_layer_names;
-       std::vector<std::string> output_layer_names;
-       std::vector<inference_engine_tensor_info> input_tensor_info;
-       std::vector<inference_engine_tensor_info> output_tensor_info;
-       training_engine_optimizer_property optimizer_property {};
-       training_engine_compile_property compile_property {};
-};
-
-class TrainingModel
-{
-private:
-       virtual void saveModel(const std::string file_path) = 0;
-       virtual void removeModel(const std::string file_path) = 0;
-
-protected:
-       std::unique_ptr<TrainingEngineInterface::Common::TrainingEngineCommon> _training;
-       std::unique_ptr<training_engine_model> _model;
-       std::unique_ptr<training_engine_dataset> _data_set;
-       std::string _internal_model_file;
-
-public:
-       TrainingModel(const training_backend_type_e backend_type, const training_target_type_e target_type,
-                                 const std::vector<size_t> input_tensor_shape, const std::string internal_model_file);
-       virtual ~TrainingModel();
-
-       void applyDataSet(std::unique_ptr<DataSetManager> &data_set);
-       void clearDataSet();
-       void compile();
-       void train();
-       void removeModel();
-       void getWeights(float **weights, size_t *size, std::string name);
-
-       virtual void configureModel(int num_of_class) = 0;
-       virtual TrainingEngineBackendInfo &getTrainingEngineInfo() = 0;
-};
-
-#endif
\ No newline at end of file
diff --git a/mv_machine_learning/training/src/DataSetManager.cpp b/mv_machine_learning/training/src/DataSetManager.cpp
new file mode 100644 (file)
index 0000000..d7c552b
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * 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 "DataSetManager.h"
+
+using namespace std;
+
+DataSetManager::DataSetManager() : _data(), _labels(), _label_index(), _feature_vector_size(), _label_count()
+{}
+
+DataSetManager::~DataSetManager()
+{
+       clear();
+}
+
+void DataSetManager::clear()
+{
+       for (auto &data : _data)
+               data.clear();
+
+       _data.clear();
+
+       for (auto &label : _labels)
+               label.clear();
+
+       _labels.clear();
+       _label_index.clear();
+       _fv_cnt_per_label.clear();
+}
+
+bool DataSetManager::isFeatureVectorDuplicated(const vector<float> &vec)
+{
+       if (_data.empty())
+               return false;
+
+       for (const auto &data : _data)
+               if (data == vec)
+                       return true;
+
+       return false;
+}
+
+vector<vector<float> > &DataSetManager::getData(void)
+{
+       return _data;
+}
+
+vector<vector<float> > &DataSetManager::getLabel(void)
+{
+       return _labels;
+}
+
+size_t DataSetManager::getFeaVecSize(void)
+{
+       return _feature_vector_size;
+}
+
+vector<unsigned int> &DataSetManager::getLabelIdx(void)
+{
+       return _label_index;
+}
\ No newline at end of file
diff --git a/mv_machine_learning/training/src/FeatureVectorManager.cpp b/mv_machine_learning/training/src/FeatureVectorManager.cpp
new file mode 100644 (file)
index 0000000..eb24340
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * 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 <opencv2/opencv.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+
+#include "MvMlException.h"
+#include "FeatureVectorManager.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+FeatureVectorManager::FeatureVectorManager(const string feature_vector_file) : _feature_vector_file(feature_vector_file)
+{}
+
+const string &FeatureVectorManager::getFileName()
+{
+       return _feature_vector_file;
+}
+
+void FeatureVectorManager::getVecFromImg(const string image_file, vector<float> &vec, unsigned int width,
+                                                                                unsigned int height)
+{
+       cv::Mat src, dst;
+
+       if (!FaceRecogUtil::isImageFile(image_file))
+               throw InvalidOperation("Invalid image file.");
+
+       src = cv::imread(image_file);
+
+       if (!src.data)
+               throw InvalidOperation("Invalid image data.");
+
+       cv::cvtColor(src, src, cv::COLOR_BGR2RGB);
+
+       cv::Mat resized;
+
+       resize(src, resized, cv::Size(width, height), 0, 0, cv::INTER_CUBIC);
+
+       cv::Mat floatSrc;
+
+       resized.convertTo(floatSrc, CV_32FC3);
+
+       cv::Mat meant = cv::Mat(floatSrc.size(), CV_32FC3, cv::Scalar(127.5f, 127.5f, 127.5f));
+
+       cv::subtract(floatSrc, meant, dst);
+       dst /= 127.5f;
+
+       vec.assign((float *) dst.data, (float *) dst.data + dst.total() * dst.channels());
+}
+
+void FeatureVectorManager::getVecFromRGB(unsigned char *in_data, vector<float> &vec, unsigned int width,
+                                                                                unsigned int height, size_t re_width, size_t re_height)
+{
+       cv::Mat cvSrc = cv::Mat(cv::Size(width, height), CV_MAKETYPE(CV_8U, 3), in_data).clone();
+
+       cv::Mat resized;
+
+       resize(cvSrc, resized, cv::Size(re_width, re_height), 0, 0, cv::INTER_CUBIC);
+
+       cv::Mat floatSrc;
+
+       resized.convertTo(floatSrc, CV_32FC3);
+
+       cv::Mat meant = cv::Mat(floatSrc.size(), CV_32FC3, cv::Scalar(127.5f, 127.5f, 127.5f));
+       cv::Mat dst;
+
+       cv::subtract(floatSrc, meant, dst);
+       dst /= 127.5f;
+
+       vec.assign((float *) dst.data, (float *) dst.data + dst.total() * dst.channels());
+}
+
+void FeatureVectorManager::getVecFromXRGB(unsigned char *in_data, vector<float> &vec, unsigned int in_width,
+                                                                                 unsigned int in_height, unsigned int re_width, unsigned int re_height)
+{
+       cv::Mat argb(cv::Size(in_width, in_height), CV_8UC4, in_data);
+
+       cv::Mat split_rgbx[4];
+       cv::split(argb, split_rgbx);
+       cv::Mat split[] = { split_rgbx[0], split_rgbx[1], split_rgbx[2] };
+       cv::Mat rgb;
+       cv::merge(split, 3, rgb);
+
+       cv::Mat resized;
+
+       resize(rgb, resized, cv::Size(re_width, re_height), 0, 0, cv::INTER_CUBIC);
+
+       cv::Mat floatSrc;
+
+       resized.convertTo(floatSrc, CV_32FC3);
+
+       cv::Mat meant = cv::Mat(floatSrc.size(), CV_32FC3, cv::Scalar(127.5f, 127.5f, 127.5f));
+
+       cv::Mat dst;
+
+       cv::subtract(floatSrc, meant, dst);
+       dst /= 127.5f;
+
+       vec.assign((float *) dst.data, (float *) dst.data + dst.total() * dst.channels());
+}
\ No newline at end of file
diff --git a/mv_machine_learning/training/src/LabelManager.cpp b/mv_machine_learning/training/src/LabelManager.cpp
new file mode 100644 (file)
index 0000000..b033541
--- /dev/null
@@ -0,0 +1,178 @@
+/**
+ * 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 <dlog.h>
+#include <mv_private.h>
+
+#include "MvMlException.h"
+#include "LabelManager.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+LabelManager::LabelManager(string label_file, double decision_threshold) : _labels(), _label_file(label_file)
+{
+       _decision_threshold = decision_threshold;
+
+       LOGD("labal file path is %s", label_file.c_str());
+       LOGD("decision_threshold value is %lf", _decision_threshold);
+}
+
+LabelManager::~LabelManager()
+{}
+
+float LabelManager::getDecisionThreshold()
+{
+       return _decision_threshold;
+}
+
+float LabelManager::getDecisionWeight()
+{
+       return _decision_weight;
+}
+
+unsigned int LabelManager::getLabelIndex(const string &given_label)
+{
+       importLabel();
+
+       auto iter = find(_labels.begin(), _labels.end(), given_label);
+       if (iter == _labels.end())
+               throw InvalidOperation("Label index not found.");
+
+       return distance(_labels.begin(), iter);
+}
+
+void LabelManager::removeLabel(const string given_label)
+{
+       ifstream readFile { _label_file };
+
+       string new_label_file = _label_file + ".new";
+       ofstream writeFile { new_label_file, ios::out | ios::binary };
+
+       if (readFile.fail() || !writeFile.is_open()) {
+               throw InvalidOperation("Fail to open label file for read/write.");
+       }
+
+       std::streampos total_length = 0;
+       string line;
+
+       while (getline(readFile, line)) {
+               total_length = readFile.tellg();
+               if (line != given_label)
+                       writeFile.write(line.c_str(), static_cast<streamsize>(line.size())).write("\n", 1);
+       }
+
+       readFile.close();
+       writeFile.close();
+
+       if (total_length == writeFile.tellp()) {
+               if (::remove(new_label_file.c_str()) == -1)
+                       throw InvalidOperation("Fail to remove label file.");
+       }
+
+       if (::remove(_label_file.c_str()) == -1)
+               throw InvalidOperation("Fail to remove label file.");
+
+       if (::rename(new_label_file.c_str(), _label_file.c_str()) == -1)
+               throw InvalidOperation("Fail to rename new labal file to original one.");
+
+       // Update _labels because label file is changed.
+       importLabel();
+}
+
+void LabelManager::getLabelString(string &label, const int idx)
+{
+       if (idx < 0 || _labels.size() <= static_cast<size_t>(idx))
+               throw InvalidOperation("A given label index is invalid.");
+
+       label = _labels[idx];
+}
+
+void LabelManager::addLabelToFile(string given_label)
+{
+       ofstream writeFile;
+
+       writeFile.open(_label_file.c_str(), ios::out | ios::app);
+
+       if (!writeFile.is_open())
+               throw InvalidOperation("Fail to open " + _label_file + " file.");
+
+       given_label += "\n";
+       writeFile.write(given_label.c_str(), static_cast<streamsize>(given_label.size()));
+       writeFile.close();
+}
+
+void LabelManager::importLabel(void)
+{
+       // just return if label file doesn't exist.
+       if (!FaceRecogUtil::isFileExist(_label_file))
+               return;
+
+       ifstream readFile;
+
+       readFile.open(_label_file);
+
+       if (readFile.fail())
+               throw InvalidOperation("Fail to open " + _label_file + " file.");
+
+       string line;
+
+       _labels.clear();
+
+       while (getline(readFile, line)) {
+               // If a given label alreadys in the label file then just skip.
+               if (isExist(line))
+                       continue;
+
+               _labels.push_back(line);
+       }
+
+       readFile.close();
+
+       LOGD("%zu labels have been imported", _labels.size());
+}
+
+const std::vector<std::string> &LabelManager::getLabels(void)
+{
+       return _labels;
+}
+
+bool LabelManager::isExist(const string given_label)
+{
+       // return false if label file doesn't exist.
+       if (!FaceRecogUtil::isFileExist(_label_file))
+               return false;
+
+       return (find(_labels.begin(), _labels.end(), given_label) != _labels.end());
+}
+
+size_t LabelManager::getMaxLabel()
+{
+       return _labels.size();
+}
+
+void LabelManager::removeFile()
+{
+       // Remove existing files forcely.
+       int ret = ::remove(_label_file.c_str());
+       if (ret)
+               throw InvalidOperation("Fail to remove label file.");
+}
+
+bool LabelManager::isEmpty()
+{
+       return _labels.empty();
+}
diff --git a/mv_machine_learning/training/src/TrainingModel.cpp b/mv_machine_learning/training/src/TrainingModel.cpp
new file mode 100644 (file)
index 0000000..e35adf7
--- /dev/null
@@ -0,0 +1,126 @@
+/**
+ * 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 <string.h>
+#include <fstream>
+#include <istream>
+#include <tuple>
+#include <map>
+#include <algorithm>
+
+#include <sys/stat.h>
+
+#include <dlog.h>
+#include <mv_private.h>
+
+#include "MvMlException.h"
+#include "TrainingModel.h"
+
+using namespace std;
+using namespace TrainingEngineInterface::Common;
+using namespace mediavision::machine_learning::exception;
+
+TrainingModel::TrainingModel(const training_backend_type_e backend_type, const training_target_type_e target_type,
+                                                        vector<size_t> input_tensor_shape, const string internal_model_file)
+{
+       _internal_model_file = internal_model_file;
+       _training = make_unique<TrainingEngineInterface::Common::TrainingEngineCommon>();
+
+       training_engine_config config = { "", backend_type, target_type };
+       int ret = _training->BindBackend(&config);
+       if (ret != TRAINING_ENGINE_ERROR_NONE)
+               throw InvalidOperation("Fail to bind backend engine.");
+
+       training_engine_capacity capacity = { TRAINING_TENSOR_SHAPE_MIN };
+       ret = _training->GetBackendCapacity(capacity);
+       if (ret != TRAINING_ENGINE_ERROR_NONE)
+               throw InvalidOperation("Fail to get backend capacity.");
+}
+
+TrainingModel::~TrainingModel()
+{
+       if (_training)
+               _training->UnbindBackend();
+}
+
+void TrainingModel::applyDataSet(unique_ptr<DataSetManager> &data_set)
+{
+       auto &values = data_set->getData();
+       auto &labels = data_set->getLabel();
+
+       LOGD("Generating feature vectors for training");
+
+       _data_set = _training->CreateDataset();
+       if (!_data_set)
+               throw InvalidOperation("Fail to create a dataset.");
+
+       int ret;
+
+       for (size_t idx = 0; idx < values.size(); ++idx) {
+               ret = _training->AddDataToDataset(_data_set.get(), values[idx], labels[idx], TRAINING_DATASET_TYPE_TRAIN);
+               if (ret != TRAINING_ENGINE_ERROR_NONE)
+                       throw InvalidOperation("Fail to add data to dataset.", ret);
+       }
+
+       ret = _training->SetDataset(_model.get(), _data_set.get());
+       if (ret != TRAINING_ENGINE_ERROR_NONE)
+               throw InvalidOperation("Fail to set dataset to model.", ret);
+}
+
+void TrainingModel::clearDataSet()
+{
+       _training->DestroyDataset(_data_set.get());
+}
+
+void TrainingModel::compile()
+{
+       auto optimizer = _training->CreateOptimizer(TRAINING_OPTIMIZER_TYPE_SGD);
+       if (!optimizer)
+               throw InvalidOperation("Fail to create a optimizer.");
+
+       int ret = _training->SetOptimizerProperty(optimizer.get(), getTrainingEngineInfo().optimizer_property);
+       if (ret != TRAINING_ENGINE_ERROR_NONE)
+               throw InvalidOperation("Fail to set optimizer property.", ret);
+
+       ret = _training->AddOptimizer(_model.get(), optimizer.get());
+       if (ret != TRAINING_ENGINE_ERROR_NONE)
+               throw InvalidOperation("Fail to add optimizer to model.", ret);
+
+       ret = _training->CompileModel(_model.get(), getTrainingEngineInfo().compile_property);
+       if (ret != TRAINING_ENGINE_ERROR_NONE)
+               throw InvalidOperation("Fail to compile model.", ret);
+}
+
+void TrainingModel::train()
+{
+       training_engine_model_property model_property;
+       int ret = _training->TrainModel(_model.get(), model_property);
+       if (ret != TRAINING_ENGINE_ERROR_NONE)
+               throw InvalidOperation("Fail to train model.", ret);
+
+       // Save model file.
+       saveModel(_internal_model_file);
+}
+
+void TrainingModel::getWeights(float **weights, size_t *size, std::string name)
+{
+       // TODO.
+}
+
+void TrainingModel::removeModel()
+{
+       removeModel(_internal_model_file);
+}
\ No newline at end of file
diff --git a/mv_machine_learning/training/src/data_set_manager.cpp b/mv_machine_learning/training/src/data_set_manager.cpp
deleted file mode 100644 (file)
index ed69fbb..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 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 "data_set_manager.h"
-
-using namespace std;
-
-DataSetManager::DataSetManager() : _data(), _labels(), _label_index(), _feature_vector_size(), _label_count()
-{}
-
-DataSetManager::~DataSetManager()
-{
-       clear();
-}
-
-void DataSetManager::clear()
-{
-       for (auto &data : _data)
-               data.clear();
-
-       _data.clear();
-
-       for (auto &label : _labels)
-               label.clear();
-
-       _labels.clear();
-       _label_index.clear();
-       _fv_cnt_per_label.clear();
-}
-
-bool DataSetManager::isFeatureVectorDuplicated(const vector<float> &vec)
-{
-       if (_data.empty())
-               return false;
-
-       for (const auto &data : _data)
-               if (data == vec)
-                       return true;
-
-       return false;
-}
-
-vector<vector<float> > &DataSetManager::getData(void)
-{
-       return _data;
-}
-
-vector<vector<float> > &DataSetManager::getLabel(void)
-{
-       return _labels;
-}
-
-size_t DataSetManager::getFeaVecSize(void)
-{
-       return _feature_vector_size;
-}
-
-vector<unsigned int> &DataSetManager::getLabelIdx(void)
-{
-       return _label_index;
-}
\ No newline at end of file
diff --git a/mv_machine_learning/training/src/feature_vector_manager.cpp b/mv_machine_learning/training/src/feature_vector_manager.cpp
deleted file mode 100644 (file)
index d49964b..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * 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 <opencv2/opencv.hpp>
-#include <opencv2/imgproc/imgproc.hpp>
-
-#include "machine_learning_exception.h"
-#include "feature_vector_manager.h"
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-FeatureVectorManager::FeatureVectorManager(const string feature_vector_file) : _feature_vector_file(feature_vector_file)
-{}
-
-const string &FeatureVectorManager::getFileName()
-{
-       return _feature_vector_file;
-}
-
-void FeatureVectorManager::getVecFromImg(const string image_file, vector<float> &vec, unsigned int width,
-                                                                                unsigned int height)
-{
-       cv::Mat src, dst;
-
-       if (!FaceRecogUtil::isImageFile(image_file))
-               throw InvalidOperation("Invalid image file.");
-
-       src = cv::imread(image_file);
-
-       if (!src.data)
-               throw InvalidOperation("Invalid image data.");
-
-       cv::cvtColor(src, src, cv::COLOR_BGR2RGB);
-
-       cv::Mat resized;
-
-       resize(src, resized, cv::Size(width, height), 0, 0, cv::INTER_CUBIC);
-
-       cv::Mat floatSrc;
-
-       resized.convertTo(floatSrc, CV_32FC3);
-
-       cv::Mat meant = cv::Mat(floatSrc.size(), CV_32FC3, cv::Scalar(127.5f, 127.5f, 127.5f));
-
-       cv::subtract(floatSrc, meant, dst);
-       dst /= 127.5f;
-
-       vec.assign((float *) dst.data, (float *) dst.data + dst.total() * dst.channels());
-}
-
-void FeatureVectorManager::getVecFromRGB(unsigned char *in_data, vector<float> &vec, unsigned int width,
-                                                                                unsigned int height, size_t re_width, size_t re_height)
-{
-       cv::Mat cvSrc = cv::Mat(cv::Size(width, height), CV_MAKETYPE(CV_8U, 3), in_data).clone();
-
-       cv::Mat resized;
-
-       resize(cvSrc, resized, cv::Size(re_width, re_height), 0, 0, cv::INTER_CUBIC);
-
-       cv::Mat floatSrc;
-
-       resized.convertTo(floatSrc, CV_32FC3);
-
-       cv::Mat meant = cv::Mat(floatSrc.size(), CV_32FC3, cv::Scalar(127.5f, 127.5f, 127.5f));
-       cv::Mat dst;
-
-       cv::subtract(floatSrc, meant, dst);
-       dst /= 127.5f;
-
-       vec.assign((float *) dst.data, (float *) dst.data + dst.total() * dst.channels());
-}
-
-void FeatureVectorManager::getVecFromXRGB(unsigned char *in_data, vector<float> &vec, unsigned int in_width,
-                                                                                 unsigned int in_height, unsigned int re_width, unsigned int re_height)
-{
-       cv::Mat argb(cv::Size(in_width, in_height), CV_8UC4, in_data);
-
-       cv::Mat split_rgbx[4];
-       cv::split(argb, split_rgbx);
-       cv::Mat split[] = { split_rgbx[0], split_rgbx[1], split_rgbx[2] };
-       cv::Mat rgb;
-       cv::merge(split, 3, rgb);
-
-       cv::Mat resized;
-
-       resize(rgb, resized, cv::Size(re_width, re_height), 0, 0, cv::INTER_CUBIC);
-
-       cv::Mat floatSrc;
-
-       resized.convertTo(floatSrc, CV_32FC3);
-
-       cv::Mat meant = cv::Mat(floatSrc.size(), CV_32FC3, cv::Scalar(127.5f, 127.5f, 127.5f));
-
-       cv::Mat dst;
-
-       cv::subtract(floatSrc, meant, dst);
-       dst /= 127.5f;
-
-       vec.assign((float *) dst.data, (float *) dst.data + dst.total() * dst.channels());
-}
\ No newline at end of file
diff --git a/mv_machine_learning/training/src/label_manager.cpp b/mv_machine_learning/training/src/label_manager.cpp
deleted file mode 100644 (file)
index 0a3e72d..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-/**
- * 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 <dlog.h>
-#include <mv_private.h>
-
-#include "machine_learning_exception.h"
-#include "label_manager.h"
-
-using namespace std;
-using namespace mediavision::machine_learning::exception;
-
-LabelManager::LabelManager(string label_file, double decision_threshold) : _labels(), _label_file(label_file)
-{
-       _decision_threshold = decision_threshold;
-
-       LOGD("labal file path is %s", label_file.c_str());
-       LOGD("decision_threshold value is %lf", _decision_threshold);
-}
-
-LabelManager::~LabelManager()
-{}
-
-float LabelManager::getDecisionThreshold()
-{
-       return _decision_threshold;
-}
-
-float LabelManager::getDecisionWeight()
-{
-       return _decision_weight;
-}
-
-unsigned int LabelManager::getLabelIndex(const string &given_label)
-{
-       importLabel();
-
-       auto iter = find(_labels.begin(), _labels.end(), given_label);
-       if (iter == _labels.end())
-               throw InvalidOperation("Label index not found.");
-
-       return distance(_labels.begin(), iter);
-}
-
-void LabelManager::removeLabel(const string given_label)
-{
-       ifstream readFile { _label_file };
-
-       string new_label_file = _label_file + ".new";
-       ofstream writeFile { new_label_file, ios::out | ios::binary };
-
-       if (readFile.fail() || !writeFile.is_open()) {
-               throw InvalidOperation("Fail to open label file for read/write.");
-       }
-
-       std::streampos total_length = 0;
-       string line;
-
-       while (getline(readFile, line)) {
-               total_length = readFile.tellg();
-               if (line != given_label)
-                       writeFile.write(line.c_str(), static_cast<streamsize>(line.size())).write("\n", 1);
-       }
-
-       readFile.close();
-       writeFile.close();
-
-       if (total_length == writeFile.tellp()) {
-               if (::remove(new_label_file.c_str()) == -1)
-                       throw InvalidOperation("Fail to remove label file.");
-       }
-
-       if (::remove(_label_file.c_str()) == -1)
-               throw InvalidOperation("Fail to remove label file.");
-
-       if (::rename(new_label_file.c_str(), _label_file.c_str()) == -1)
-               throw InvalidOperation("Fail to rename new labal file to original one.");
-
-       // Update _labels because label file is changed.
-       importLabel();
-}
-
-void LabelManager::getLabelString(string &label, const int idx)
-{
-       if (idx < 0 || _labels.size() <= static_cast<size_t>(idx))
-               throw InvalidOperation("A given label index is invalid.");
-
-       label = _labels[idx];
-}
-
-void LabelManager::addLabelToFile(string given_label)
-{
-       ofstream writeFile;
-
-       writeFile.open(_label_file.c_str(), ios::out | ios::app);
-
-       if (!writeFile.is_open())
-               throw InvalidOperation("Fail to open " + _label_file + " file.");
-
-       given_label += "\n";
-       writeFile.write(given_label.c_str(), static_cast<streamsize>(given_label.size()));
-       writeFile.close();
-}
-
-void LabelManager::importLabel(void)
-{
-       // just return if label file doesn't exist.
-       if (!FaceRecogUtil::isFileExist(_label_file))
-               return;
-
-       ifstream readFile;
-
-       readFile.open(_label_file);
-
-       if (readFile.fail())
-               throw InvalidOperation("Fail to open " + _label_file + " file.");
-
-       string line;
-
-       _labels.clear();
-
-       while (getline(readFile, line)) {
-               // If a given label alreadys in the label file then just skip.
-               if (isExist(line))
-                       continue;
-
-               _labels.push_back(line);
-       }
-
-       readFile.close();
-
-       LOGD("%zu labels have been imported", _labels.size());
-}
-
-const std::vector<std::string> &LabelManager::getLabels(void)
-{
-       return _labels;
-}
-
-bool LabelManager::isExist(const string given_label)
-{
-       // return false if label file doesn't exist.
-       if (!FaceRecogUtil::isFileExist(_label_file))
-               return false;
-
-       return (find(_labels.begin(), _labels.end(), given_label) != _labels.end());
-}
-
-size_t LabelManager::getMaxLabel()
-{
-       return _labels.size();
-}
-
-void LabelManager::removeFile()
-{
-       // Remove existing files forcely.
-       int ret = ::remove(_label_file.c_str());
-       if (ret)
-               throw InvalidOperation("Fail to remove label file.");
-}
-
-bool LabelManager::isEmpty()
-{
-       return _labels.empty();
-}
diff --git a/mv_machine_learning/training/src/training_model.cpp b/mv_machine_learning/training/src/training_model.cpp
deleted file mode 100644 (file)
index 749714a..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * 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 <string.h>
-#include <fstream>
-#include <istream>
-#include <tuple>
-#include <map>
-#include <algorithm>
-
-#include <sys/stat.h>
-
-#include <dlog.h>
-#include <mv_private.h>
-
-#include "machine_learning_exception.h"
-#include "training_model.h"
-
-using namespace std;
-using namespace TrainingEngineInterface::Common;
-using namespace mediavision::machine_learning::exception;
-
-TrainingModel::TrainingModel(const training_backend_type_e backend_type, const training_target_type_e target_type,
-                                                        vector<size_t> input_tensor_shape, const string internal_model_file)
-{
-       _internal_model_file = internal_model_file;
-       _training = make_unique<TrainingEngineInterface::Common::TrainingEngineCommon>();
-
-       training_engine_config config = { "", backend_type, target_type };
-       int ret = _training->BindBackend(&config);
-       if (ret != TRAINING_ENGINE_ERROR_NONE)
-               throw InvalidOperation("Fail to bind backend engine.");
-
-       training_engine_capacity capacity = { TRAINING_TENSOR_SHAPE_MIN };
-       ret = _training->GetBackendCapacity(capacity);
-       if (ret != TRAINING_ENGINE_ERROR_NONE)
-               throw InvalidOperation("Fail to get backend capacity.");
-}
-
-TrainingModel::~TrainingModel()
-{
-       if (_training)
-               _training->UnbindBackend();
-}
-
-void TrainingModel::applyDataSet(unique_ptr<DataSetManager> &data_set)
-{
-       auto &values = data_set->getData();
-       auto &labels = data_set->getLabel();
-
-       LOGD("Generating feature vectors for training");
-
-       _data_set = _training->CreateDataset();
-       if (!_data_set)
-               throw InvalidOperation("Fail to create a dataset.");
-
-       int ret;
-
-       for (size_t idx = 0; idx < values.size(); ++idx) {
-               ret = _training->AddDataToDataset(_data_set.get(), values[idx], labels[idx], TRAINING_DATASET_TYPE_TRAIN);
-               if (ret != TRAINING_ENGINE_ERROR_NONE)
-                       throw InvalidOperation("Fail to add data to dataset.", ret);
-       }
-
-       ret = _training->SetDataset(_model.get(), _data_set.get());
-       if (ret != TRAINING_ENGINE_ERROR_NONE)
-               throw InvalidOperation("Fail to set dataset to model.", ret);
-}
-
-void TrainingModel::clearDataSet()
-{
-       _training->DestroyDataset(_data_set.get());
-}
-
-void TrainingModel::compile()
-{
-       auto optimizer = _training->CreateOptimizer(TRAINING_OPTIMIZER_TYPE_SGD);
-       if (!optimizer)
-               throw InvalidOperation("Fail to create a optimizer.");
-
-       int ret = _training->SetOptimizerProperty(optimizer.get(), getTrainingEngineInfo().optimizer_property);
-       if (ret != TRAINING_ENGINE_ERROR_NONE)
-               throw InvalidOperation("Fail to set optimizer property.", ret);
-
-       ret = _training->AddOptimizer(_model.get(), optimizer.get());
-       if (ret != TRAINING_ENGINE_ERROR_NONE)
-               throw InvalidOperation("Fail to add optimizer to model.", ret);
-
-       ret = _training->CompileModel(_model.get(), getTrainingEngineInfo().compile_property);
-       if (ret != TRAINING_ENGINE_ERROR_NONE)
-               throw InvalidOperation("Fail to compile model.", ret);
-}
-
-void TrainingModel::train()
-{
-       training_engine_model_property model_property;
-       int ret = _training->TrainModel(_model.get(), model_property);
-       if (ret != TRAINING_ENGINE_ERROR_NONE)
-               throw InvalidOperation("Fail to train model.", ret);
-
-       // Save model file.
-       saveModel(_internal_model_file);
-}
-
-void TrainingModel::getWeights(float **weights, size_t *size, std::string name)
-{
-       // TODO.
-}
-
-void TrainingModel::removeModel()
-{
-       removeModel(_internal_model_file);
-}
\ No newline at end of file
index 9f93e8831f3302594077651e14d673be4d183f2f..461e13d7ee84e4cc4a4be9ec7c9b054f7e0bb504 100644 (file)
@@ -411,10 +411,10 @@ find . -name '*.gcno' -not -path "./test/*" -not -path "./mv_machine_learning/*"
 
 %files machine_learning-devel
 %{_includedir}/media/mv_infer*.h
-%{_includedir}/media/machine_learning_exception.h
-%{_includedir}/media/machine_learning_config.h
-%{_includedir}/media/MachineLearningType.h
-%{_includedir}/media/machine_learning_preprocess.h
+%{_includedir}/media/MvMlException.h
+%{_includedir}/media/MvMlConfig.h
+%{_includedir}/media/mv_ml_types.h
+%{_includedir}/media/MvMlPreprocess.h
 %{_libdir}/pkgconfig/*inference.pc
 %if "%{enable_ml_face_recognition}" == "1"
 %{_includedir}/media/mv_face_recognition*.h
@@ -431,7 +431,7 @@ find . -name '*.gcno' -not -path "./test/*" -not -path "./mv_machine_learning/*"
 %{_includedir}/media/mv_object_detection_type.h
 %{_includedir}/media/mv_face_detection_internal.h
 %{_includedir}/media/mv_face_detection_type.h
-%{_includedir}/media/iobject_detection.h
+%{_includedir}/media/IObjectDetection.h
 %{_includedir}/media/object_detection_type.h
 %{_libdir}/pkgconfig/*object-detection.pc
 %endif
@@ -450,7 +450,7 @@ find . -name '*.gcno' -not -path "./test/*" -not -path "./mv_machine_learning/*"
 %if "%{enable_ml_image_segmentation}" == "1"
 %{_includedir}/media/mv_selfie_segmentation_internal.h
 %{_includedir}/media/mv_selfie_segmentation_type.h
-%{_includedir}/media/iimage_segmentation.h
+%{_includedir}/media/IImageSegmentation.h
 %{_includedir}/media/image_segmentation_type.h
 %{_libdir}/pkgconfig/*image-segmentation.pc
 %endif