mv_machine_learning: add hand landmark detection model support 99/317599/3
authorInki Dae <inki.dae@samsung.com>
Tue, 16 Jul 2024 07:52:18 +0000 (16:52 +0900)
committerInki Dae <inki.dae@samsung.com>
Mon, 23 Sep 2024 06:51:44 +0000 (06:51 +0000)
Change-Id: I997373757edb91bb6ef08dee4a7e3320df4837ba
Signed-off-by: Inki Dae <inki.dae@samsung.com>
15 files changed:
CMakeLists.txt
include/mv_hand_landmark.h [new file with mode: 0644]
include/mv_hand_landmark_internal.h [new file with mode: 0644]
include/mv_hand_landmark_type.h [new file with mode: 0644]
mv_machine_learning/common/meta/include/types.h
mv_machine_learning/common/meta/src/PostprocessParser.cpp
mv_machine_learning/landmark_detection/CMakeLists.txt
mv_machine_learning/landmark_detection/include/HandLander.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/HandLandmarkAdapter.h [new file with mode: 0644]
mv_machine_learning/landmark_detection/include/landmark_detection_type.h
mv_machine_learning/landmark_detection/meta/hand_landmark.json [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/HandLander.cpp [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/HandLandmarkAdapter.cpp [new file with mode: 0644]
mv_machine_learning/landmark_detection/src/mv_hand_landmark.cpp [new file with mode: 0644]
packaging/capi-media-vision.spec

index efa3523a5a255c3026bfbacdda1592fba15a2c83..d86eecba1e58dd70508d91a84f328658dc685690 100644 (file)
@@ -259,6 +259,7 @@ if (${ENABLE_ML_LANDMARK_DETECTION})
     install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${fw_name}-landmark-detection.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
     install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/landmark_detection/meta/facial_landmark.json DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
     install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/landmark_detection/meta/pose_landmark.json DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
+    install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/landmark_detection/meta/hand_landmark.json DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
        list(APPEND TOTAL_REQUIRED ${PC_NAME})
        list(APPEND TOTAL_LDFLAGS ${PC_LDFLAGS})
 endif()
diff --git a/include/mv_hand_landmark.h b/include/mv_hand_landmark.h
new file mode 100644 (file)
index 0000000..6f8d113
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2024 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 __TIZEN_MEDIAVISION_MV_HAND_LANDMARK_H__
+#define __TIZEN_MEDIAVISION_MV_HAND_LANDMARK_H__
+
+#include <mv_common.h>
+#include <mv_hand_landmark_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_hand_landmark.h
+ * @internal
+ * @brief  This file contains the Inference based Media Vision API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_HAND_LANDMARK_MODULE
+ * @{
+ */
+
+/**
+ * @internal
+ * @brief Creates a inference handle for hand landmark object.
+ * @details Use this function to create a inference handle. After the creation
+ *          the hand landmark task has to be prepared with
+ *          mv_hand_landmark_prepare() function to prepare a network
+ *          for the inference.
+ *
+ * @since_tizen 9.0
+ *
+ * @remarks The @a handle should be released using mv_hand_landmark_destroy().
+ *
+ * @param[out] handle    The handle to the inference to be created.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @code
+ * #include <mv_hand_landmark.h>
+ * ...
+ * mv_hand_landmark_h handle = NULL;
+ * mv_hand_landmark_create(&handle);
+ * ...
+ * mv_hand_landmark_destroy(handle);
+ * @endcode
+ *
+ * @see mv_hand_landmark_destroy()
+ * @see mv_hand_landmark_prepare()
+ */
+int mv_hand_landmark_create(mv_hand_landmark_h *handle);
+
+/**
+ * @internal
+ * @brief Destroys inference handle and releases all its resources.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle    The handle to the inference to be destroyed.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create inference handle by using mv_hand_landmark_create()
+ *
+ * @see mv_hand_landmark_create()
+ */
+int mv_hand_landmark_destroy(mv_hand_landmark_h handle);
+
+/**
+ * @internal
+ * @brief Configures the backend for the hand landmark inference.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the inference
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int mv_hand_landmark_configure(mv_hand_landmark_h handle);
+
+/**
+ * @internal
+ * @brief Prepares the hand landmark inference.
+ * @details Use this function to prepare the hand landmark inference based on
+ *          the configured network.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the inference.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_DATA Invalid model data
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Not supported format
+ */
+int mv_hand_landmark_prepare(mv_hand_landmark_h handle);
+
+/**
+ * @internal
+ * @brief Performs the hand landmark inference on the @a source.
+ *
+ * @since_tizen 9.0
+ * @remarks This function is synchronous and may take considerable time to run.
+ *
+ * @param[in] handle          The handle to the inference
+ * @param[in] source         The handle to the source of the media
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_hand_landmark_create()
+ * @pre Prepare an inference by calling mv_hand_landmark_configure()
+ * @pre Prepare an inference by calling mv_hand_landmark_prepare()
+ *
+ * @par Inference Example
+ * @snippet hand_landmark_sync.c FLD sync
+ */
+int mv_hand_landmark_inference(mv_hand_landmark_h handle, mv_source_h source);
+
+/**
+ * @internal
+ * @brief Performs asynchronously the hand landmark inference on the @a source.
+ *
+ * @since_tizen 9.0
+ * @remarks This function operates asynchronously, so it returns immediately upon invocation.
+ *          The inference results are inserted into the outgoing queue within the framework
+ *          in the order of processing, and the results can be obtained through mv_hand_landmark_get_position().
+ *
+ * @param[in] handle         The handle to the inference
+ * @param[in] source         The handle to the source of the media
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_hand_landmark_create()
+ * @pre Prepare an inference by calling mv_hand_landmark_configure()
+ * @pre Prepare an inference by calling mv_hand_landmark_prepare()
+ *
+ * @par Async Inference Example
+ * @snippet hand_landmark_async.c FLD async
+ */
+int mv_hand_landmark_inference_async(mv_hand_landmark_h handle, mv_source_h source);
+
+/**
+ * @internal
+ * @brief Gets the result count to objects.
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the inference
+ * @param[out] frame_number  A frame number inferenced.
+ * @param[out] result_cnt    A number of results.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_hand_landmark_create()
+ * @pre Prepare an inference by calling mv_hand_landmark_configure()
+ * @pre Prepare an inference by calling mv_hand_landmark_prepare()
+ * @pre Request an inference by calling mv_hand_landmark_inference()
+ */
+int mv_hand_landmark_get_result_count(mv_hand_landmark_h handle, unsigned long *frame_number, unsigned int *result_cnt);
+
+/**
+ * @internal
+ * @brief Gets the hand landmark position values to a given index.
+ *
+ * @since_tizen 9.0
+ * @remarks pos_x and pos_y arrays are allocated internally by the framework and will remain valid
+ *          until the handle is released.
+ *          Please do not deallocate them directly, and if you want to use them after the handle is released,
+ *          please copy them to user memory and use the copy.
+ *
+ *          This function operates differently depending on the inference request method.
+ *          - After mv_hand_landmark_inference() calls, this function returns hand landmark positions immediately.
+ *          - After mv_hand_landmark_inference_async() calls, this function can be blocked until the asynchronous inference request is completed
+ *            or the timeout occurs if no result within 3 seconds.
+ *
+ *          Additionally, after calling the mv_hand_landmark_inference_async() function, the function operates
+ *          in asynchronous mode until the handle is released.
+ *
+ * @param[in] handle               The handle to the inference
+ * @param[in] index                A result index.
+ * @param[out] pos_x               An array containing x-coordinate values.
+ * @param[out] pos_y               An array containing y-coordinate values.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INTERNAL          Internal error
+ *
+ * @pre Create a source handle by calling mv_create_source()
+ * @pre Create an inference handle by calling mv_hand_landmark_create()
+ * @pre Prepare an inference by calling mv_hand_landmark_configure()
+ * @pre Prepare an inference by calling mv_hand_landmark_prepare()
+ * @pre Prepare an inference by calling mv_hand_landmark_inference()
+ * @pre Get result count by calling mv_hand_landmark_get_result_count()
+ */
+int mv_hand_landmark_get_position(mv_hand_landmark_h handle, unsigned int index, unsigned int *pos_x,
+                                                                 unsigned int *pos_y);
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_MV_HAND_LANDMARK_H__ */
diff --git a/include/mv_hand_landmark_internal.h b/include/mv_hand_landmark_internal.h
new file mode 100644 (file)
index 0000000..e65b5a6
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2024 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 __TIZEN_MEDIAVISION_HAND_LANDMARK_INTERNAL_H__
+#define __TIZEN_MEDIAVISION_HAND_LANDMARK_INTERNAL_H__
+
+#include <mv_common.h>
+#include <mv_hand_landmark_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_hand_landmark_internal.h
+ * @internal
+ * @brief  This file contains the Inference based Media Vision API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_INFERENCE_MODULE
+ * @{
+ */
+
+/**
+ * @internal
+ * @brief Sets user-given model information.
+ * @details Use this function to change the model information instead of default one after calling @ref mv_hand_landmark_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle        The handle to the hand landmark object.
+ * @param[in] model_file    Model file name.
+ * @param[in] meta_file     Model meta file name.
+ * @param[in] label_file    Label file name.
+ * @param[in] model_name    Model name.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a hand landmark handle by calling @ref mv_hand_landmark_create()
+ */
+int mv_hand_landmark_set_model(mv_hand_landmark_h handle, const char *model_file, const char *meta_file,
+                                                          const char *label_file, const char *model_name);
+
+/**
+ * @internal
+ * @brief Sets user-given inference engine and device types for inference.
+ * @details Use this function to change the inference engine and device types for inference instead of default ones after calling @ref mv_hand_landmark_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle        The handle to the hand landmark object.
+ * @param[in] engine_type  A string of inference engine type.
+ * @param[in] device_type   A string of device type.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a hand landmark handle by calling @ref mv_hand_landmark_create()
+ */
+int mv_hand_landmark_set_engine(mv_hand_landmark_h handle, const char *engine_type, const char *device_type);
+
+/**
+ * @internal
+ * @brief Gets a number of inference engines available for hand landmark task API.
+ * @details Use this function to get how many inference engines are supported for hand landmark after calling @ref mv_hand_landmark_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the hand landmark object.
+ * @param[out] engine_count  A number of inference engines available for hand landmark API.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a hand landmark handle by calling @ref mv_hand_landmark_create()
+ */
+int mv_hand_landmark_get_engine_count(mv_hand_landmark_h handle, unsigned int *engine_count);
+
+/**
+ * @internal
+ * @brief Gets engine type to a given inference engine index.
+ * @details Use this function to get inference engine type with a given engine index after calling @ref mv_hand_landmark_get_engine_count().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle        The handle to the hand landmark object.
+ * @param[in] engine_index  A inference engine index for getting the inference engine type.
+ * @param[out] engine_type  A string to inference engine.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Get a number of inference engines available for hand landmark task API by calling @ref mv_hand_landmark_get_engine_count()
+ */
+int mv_hand_landmark_get_engine_type(mv_hand_landmark_h handle, const unsigned int engine_index, char **engine_type);
+
+/**
+ * @internal
+ * @brief Gets a number of device types available to a given inference engine.
+ * @details Use this function to get how many device types are supported for a given inference engine after calling @ref mv_hand_landmark_create().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the hand landmark object.
+ * @param[in] engine_type    A inference engine string.
+ * @param[out] device_count  A number of device types available for a given inference engine.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a hand landmark handle by calling @ref mv_hand_landmark_create()
+ */
+int mv_hand_landmark_get_device_count(mv_hand_landmark_h handle, const char *engine_type, unsigned int *device_count);
+
+/**
+ * @internal
+ * @brief Gets device type list available.
+ * @details Use this function to get what device types are supported for current inference engine type after calling @ref mv_hand_landmark_configure().
+ *
+ * @since_tizen 9.0
+ *
+ * @param[in] handle         The handle to the hand landmark object.
+ * @param[in] engine_type    A inference engine string.
+ * @param[in] device_index   A device index for getting the device type.
+ * @param[out] device_type   A string to device type.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ *
+ * @pre Create a hand landmark handle by calling @ref mv_hand_landmark_create()
+ * @pre Configure hand landmark task by calling @ref mv_hand_landmark_configure()
+ */
+int mv_hand_landmark_get_device_type(mv_hand_landmark_h handle, const char *engine_type,
+                                                                        const unsigned int device_index, char **device_type);
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_HAND_LANDMARK_INTERNAL_H__ */
diff --git a/include/mv_hand_landmark_type.h b/include/mv_hand_landmark_type.h
new file mode 100644 (file)
index 0000000..c97105d
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024 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 __TIZEN_MEDIAVISION_MV_HAND_LANDMARK_TYPE_H__
+#define __TIZEN_MEDIAVISION_MV_HAND_LANDMARK_TYPE_H__
+
+#include <mv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_hand_landmark_type.h
+ * @brief  This file contains the hand landmark handle for Mediavision.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_HAND_LANDMARK_MODULE
+ * @{
+ */
+
+/**
+ * @brief The hand landmark object handle.
+ *
+ * @since_tizen 9.0
+ */
+typedef void *mv_hand_landmark_h;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_MV_HAND_LANDMARK_TYPE_H__ */
index 75699838bb1c42eab7a70f54fbbbd3521756953b..0e356c82dd301344d3d3a019dcfd2235ad2ada25 100644 (file)
@@ -39,7 +39,7 @@ enum class BoxCoordinateType { RATIO, PIXEL };
 
 enum class BoxType { LEFTTOP, CENTER };
 
-enum class LandmarkType { SINGLE_2D, MULTI_2D };
+enum class LandmarkType { SINGLE_2D, SINGLE_3D, MULTI_2D };
 
 enum class BoxNmsMode { NONE = -1, STANDARD };
 
index 984acf53621129b61b1a83e17c74f6191f6efbe6..b7541ec38299870e9e890595b176d3ef2d170c90 100644 (file)
@@ -42,6 +42,7 @@ std::map<std::string, BoxDecodingType> gSupportedBoxDecodingTypes = { { "BYPASS"
 std::map<std::string, ScoreType> gSupportedScoreTypes = { { "NORMAL", ScoreType::NORMAL },
                                                                                                                  { "SIGMOID", ScoreType::SIGMOID } };
 std::map<std::string, LandmarkType> gSupportedLandmarkTypes = { { "2D_SINGLE", LandmarkType::SINGLE_2D },
+                                                                                                                               { "3D_SINGLE", LandmarkType::SINGLE_3D },
                                                                                                                                { "2D_MULTI", LandmarkType::MULTI_2D } };
 std::map<std::string, LandmarkCoordinateType> gSupportedLandmarkCoordinateTypes = {
        { "RATIO", LandmarkCoordinateType::RATIO },
index 43cf88e70b5fbd665f3cc6de9c07cbcae90becb8..eda67fcfee2d0b0b78f201489df7aabca8eadf47 100644 (file)
@@ -23,4 +23,7 @@ install(
        PATTERN "mv_pose_landmark_internal.h"
        PATTERN "mv_pose_landmark.h"
        PATTERN "mv_pose_landmark_type.h"
+       PATTERN "mv_hand_landmark_internal.h"
+       PATTERN "mv_hand_landmark.h"
+       PATTERN "mv_hand_landmark_type.h"
        )
diff --git a/mv_machine_learning/landmark_detection/include/HandLander.h b/mv_machine_learning/landmark_detection/include/HandLander.h
new file mode 100644 (file)
index 0000000..b698afe
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2024 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 __HLD_HAND_LANDER_H__
+#define __HLD_HAND_LANDER_H__
+
+#include <memory>
+#include <mv_common.h>
+
+#include "LandmarkDetection.h"
+#include <mv_inference_type.h>
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T> class HandLander : public LandmarkDetection<T>
+{
+       using LandmarkDetection<T>::_config;
+       using LandmarkDetection<T>::_preprocess;
+       using LandmarkDetection<T>::_inference;
+
+private:
+       LandmarkDetectionResult _result;
+
+public:
+       HandLander(LandmarkDetectionTaskType task_type, std::shared_ptr<Config> config);
+       ~HandLander();
+
+       LandmarkDetectionResult &result() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/include/HandLandmarkAdapter.h b/mv_machine_learning/landmark_detection/include/HandLandmarkAdapter.h
new file mode 100644 (file)
index 0000000..fa6907d
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2024 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 __HAND_LANDMARK_ADAPTER_H__
+#define __HAND_LANDMARK_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "ILandmarkDetection.h"
+#include "ITask.h"
+#include "MvMlConfig.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class HandLandmarkAdapter : public mediavision::common::ITask
+{
+private:
+       std::unique_ptr<ILandmarkDetection> _landmark_detection;
+       std::shared_ptr<Config> _config;
+       const std::string _config_file_name = "hand_landmark.json";
+
+       void create(const std::string &model_name);
+       template<typename U> void create(LandmarkDetectionTaskType task_type);
+       LandmarkDetectionTaskType convertToTaskType(std::string model_name);
+
+public:
+       HandLandmarkAdapter();
+       ~HandLandmarkAdapter();
+
+       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
index 23d3bf38fd2c6bee5b92c95986a89b818ba0f3e1..19685342431fef84d2d9fe51e79700ff8af4ed97 100644 (file)
@@ -40,7 +40,13 @@ struct LandmarkDetectionResult : public OutputBaseType {
        std::vector<std::string> labels;
 };
 
-enum class LandmarkDetectionTaskType { LANDMARK_DETECTION_TASK_NONE = 0, FLD_TWEAK_CNN, FLD_U2NET, PLD_CPM };
+enum class LandmarkDetectionTaskType {
+       LANDMARK_DETECTION_TASK_NONE = 0,
+       FLD_TWEAK_CNN,
+       FLD_U2NET,
+       PLD_CPM,
+       HAND_LANDER
+};
 
 }
 }
diff --git a/mv_machine_learning/landmark_detection/meta/hand_landmark.json b/mv_machine_learning/landmark_detection/meta/hand_landmark.json
new file mode 100644 (file)
index 0000000..4028e1b
--- /dev/null
@@ -0,0 +1,40 @@
+{
+    "attributes":
+    [
+        {
+            "name" : "MODEL_DEFAULT_PATH",
+            "type" : "string",
+            "value" : "/opt/usr/globalapps/mediavision.landmark.detection/models/tflite/"
+        },
+        {
+            "name"  : "MODEL_FILE_NAME",
+            "type"  : "string",
+            "value" : "hld_hand_lander_256_int8_quant.tflite"
+        },
+        {
+            "name"  : "DEFAULT_MODEL_NAME",
+            "type"  : "string",
+            "value" : "HAND_LANDER"
+        },
+        {
+            "name"  : "MODEL_META_FILE_NAME",
+            "type"  : "string",
+            "value" : "hld_hand_lander_256_int8_quant.json"
+        },
+        {
+            "name"  : "MODEL_LABEL_FILE_NAME",
+            "type"  : "string",
+            "value" : ""
+        },
+        {
+            "name"  : "BACKEND_TYPE",
+            "type"  : "integer",
+            "value" : 1
+        },
+        {
+            "name"  : "TARGET_DEVICE_TYPE",
+            "type"  : "integer",
+            "value" : 1
+        }
+    ]
+}
diff --git a/mv_machine_learning/landmark_detection/src/HandLander.cpp b/mv_machine_learning/landmark_detection/src/HandLander.cpp
new file mode 100644 (file)
index 0000000..422c0b9
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2024 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 <algorithm>
+#include <map>
+#include <string.h>
+
+#include "HandLander.h"
+#include "MvMlException.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>
+HandLander<T>::HandLander(LandmarkDetectionTaskType task_type, std::shared_ptr<Config> config)
+               : LandmarkDetection<T>(task_type, config), _result()
+{}
+
+template<typename T> HandLander<T>::~HandLander()
+{}
+
+template<typename T> LandmarkDetectionResult &HandLander<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);
+
+       vector<float> tensor1, tensor2;
+
+       LandmarkDetection<T>::getOutputTensor(names[0], tensor1);
+       LandmarkDetection<T>::getOutputTensor(names[1], tensor2);
+
+       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());
+
+       // Calculate the ratio[A] between the original image size and the input tensor size.
+       auto width_ratio = ori_src_width / input_tensor_width;
+       auto height_ratio = ori_src_height / input_tensor_height;
+
+       _result.number_of_landmarks = static_cast<unsigned int>(tensor1.size()) / 3;
+
+       for (size_t idx = 0; idx < tensor1.size(); idx += 3) {
+               _result.x_pos.push_back(tensor1[idx] * width_ratio);
+               _result.y_pos.push_back(tensor1[idx + 1] * height_ratio);
+       }
+
+       _result.scores.push_back(tensor2[0]);
+
+       for (auto &name : names)
+               LOGD("%s", name.c_str());
+
+       return _result;
+}
+
+template class HandLander<unsigned char>;
+template class HandLander<float>;
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/HandLandmarkAdapter.cpp b/mv_machine_learning/landmark_detection/src/HandLandmarkAdapter.cpp
new file mode 100644 (file)
index 0000000..ee33fcd
--- /dev/null
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2024 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 "HandLandmarkAdapter.h"
+#include "HandLander.h"
+#include "MvMlException.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
+{
+HandLandmarkAdapter::HandLandmarkAdapter()
+{
+       _config = make_shared<Config>();
+       _config->parseConfigFile(_config_file_name);
+
+       create(_config->getDefaultModelName());
+}
+
+HandLandmarkAdapter::~HandLandmarkAdapter()
+{
+       _landmark_detection->preDestroy();
+}
+
+template<typename U> void HandLandmarkAdapter::create(LandmarkDetectionTaskType task_type)
+{
+       switch (task_type) {
+       case LandmarkDetectionTaskType::HAND_LANDER:
+               _landmark_detection = make_unique<HandLander<U> >(task_type, _config);
+               break;
+       default:
+               throw InvalidOperation("Invalid landmark detection task type.");
+       }
+}
+
+void HandLandmarkAdapter::create(const string &model_name)
+{
+       auto task_type = convertToTaskType(model_name.empty() ? _config->getDefaultModelName() : 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 HandLandmarkAdapter::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 == "HAND_LANDER")
+               return LandmarkDetectionTaskType::HAND_LANDER;
+       // TODO.
+
+       throw InvalidParameter("Invalid hand detection model name.");
+}
+
+void HandLandmarkAdapter::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 HandLandmarkAdapter::setEngineInfo(const string &engine_type, const string &device_type)
+{
+       _landmark_detection->setEngineInfo(string(engine_type), string(device_type));
+}
+
+void HandLandmarkAdapter::configure()
+{
+       _landmark_detection->configure();
+}
+
+unsigned int HandLandmarkAdapter::getNumberOfEngines()
+{
+       return _landmark_detection->getNumberOfEngines();
+}
+
+const string &HandLandmarkAdapter::getEngineType(unsigned int engine_index)
+{
+       return _landmark_detection->getEngineType(engine_index);
+}
+
+unsigned int HandLandmarkAdapter::getNumberOfDevices(const string &engine_type)
+{
+       return _landmark_detection->getNumberOfDevices(engine_type);
+}
+
+const string &HandLandmarkAdapter::getDeviceType(const string &engine_type, unsigned int device_index)
+{
+       return _landmark_detection->getDeviceType(engine_type, device_index);
+}
+
+void HandLandmarkAdapter::prepare()
+{
+       _landmark_detection->prepare();
+}
+
+void HandLandmarkAdapter::perform(InputBaseType &input)
+{
+       _landmark_detection->perform(input.inference_src);
+}
+
+void HandLandmarkAdapter::performAsync(InputBaseType &input)
+{
+       _landmark_detection->performAsync(static_cast<LandmarkDetectionInput &>(input));
+}
+
+OutputBaseType &HandLandmarkAdapter::getOutput()
+{
+       return _landmark_detection->getOutput();
+}
+
+OutputBaseType &HandLandmarkAdapter::getOutputCache()
+{
+       return _landmark_detection->getOutputCache();
+}
+
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/landmark_detection/src/mv_hand_landmark.cpp b/mv_machine_learning/landmark_detection/src/mv_hand_landmark.cpp
new file mode 100644 (file)
index 0000000..9346726
--- /dev/null
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2024 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_hand_landmark.h"
+#include "Context.h"
+#include "HandLandmarkAdapter.h"
+#include "ITask.h"
+#include "MvMlException.h"
+#include "landmark_detection_type.h"
+#include "mv_feature_key.h"
+#include "mv_hand_landmark_internal.h"
+#include "mv_private.h"
+#include "native_capi.h"
+
+#include <algorithm>
+#include <exception>
+#include <new>
+#include <string>
+#include <unistd.h>
+
+#define TASK_NAME "hand_landmark"
+
+using namespace std;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning::exception;
+
+static const char *feature_keys[] = { "http://tizen.org/feature/vision.inference",
+                                                                         "http://tizen.org/feature/vision.inference.face" };
+static const size_t num_keys = sizeof(feature_keys) / sizeof(char *);
+
+int mv_hand_landmark_create(mv_hand_landmark_h *handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_NULL_ARG_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       mv_hand_landmark_h ctx = nullptr;
+
+       try {
+               ctx = machine_learning_native_create();
+               machine_learning_native_add(ctx, TASK_NAME, new HandLandmarkAdapter());
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       } catch (const std::exception &e) {
+               LOGE("%s", e.what());
+               return MEDIA_VISION_ERROR_INTERNAL;
+       }
+
+       *handle = ctx;
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_destroy(mv_hand_landmark_h handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       machine_learning_native_destroy(handle);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_set_model(mv_hand_landmark_h handle, const char *model_file, const char *meta_file,
+                                                          const char *label_file, const char *model_name)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(model_file);
+       MEDIA_VISION_NULL_ARG_CHECK(meta_file);
+       MEDIA_VISION_NULL_ARG_CHECK(label_file);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_set_model(handle, TASK_NAME, model_file, meta_file, label_file, model_name);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_set_engine(mv_hand_landmark_h handle, const char *backend_type, const char *device_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(backend_type);
+       MEDIA_VISION_NULL_ARG_CHECK(device_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_set_engine(handle, TASK_NAME, backend_type, device_type);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_get_engine_count(mv_hand_landmark_h handle, unsigned int *engine_count)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_count);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_engine_count(handle, TASK_NAME, engine_count);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_get_engine_type(mv_hand_landmark_h handle, const unsigned int engine_index, char **engine_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_engine_type(handle, TASK_NAME, engine_index, engine_type);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_get_device_count(mv_hand_landmark_h handle, const char *engine_type, unsigned int *device_count)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(device_count);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_device_count(handle, TASK_NAME, engine_type, device_count);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_get_device_type(mv_hand_landmark_h handle, const char *engine_type,
+                                                                        const unsigned int device_index, char **device_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_type);
+       MEDIA_VISION_NULL_ARG_CHECK(device_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_get_device_type(handle, TASK_NAME, engine_type, device_index, device_type);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_configure(mv_hand_landmark_h handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_configure(handle, TASK_NAME);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_prepare(mv_hand_landmark_h handle)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               machine_learning_native_prepare(handle, TASK_NAME);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_inference(mv_hand_landmark_h handle, mv_source_h source)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(source);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               LandmarkDetectionInput input(source);
+
+               machine_learning_native_inference(handle, TASK_NAME, input);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_inference_async(mv_hand_landmark_h handle, mv_source_h source)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(source);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               LandmarkDetectionInput input(source);
+
+               machine_learning_native_inference_async(handle, TASK_NAME, input);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_get_result_count(mv_hand_landmark_h handle, unsigned long *frame_number, unsigned int *result_cnt)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(frame_number);
+       MEDIA_VISION_INSTANCE_CHECK(result_cnt);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               auto &result = static_cast<LandmarkDetectionResult &>(machine_learning_native_get_result(handle, TASK_NAME));
+
+               *frame_number = result.frame_number;
+               *result_cnt = result.number_of_landmarks;
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_hand_landmark_get_position(mv_hand_landmark_h handle, unsigned int index, unsigned int *pos_x,
+                                                                 unsigned int *pos_y)
+{
+       MEDIA_VISION_SUPPORT_CHECK(mv_check_feature_key(feature_keys, num_keys, true));
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(pos_x);
+       MEDIA_VISION_INSTANCE_CHECK(pos_y);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       try {
+               auto &result =
+                               static_cast<LandmarkDetectionResult &>(machine_learning_native_get_result_cache(handle, TASK_NAME));
+               if (index >= result.number_of_landmarks) {
+                       LOGE("Invalid index(index = %u, result count = %u).", index, result.number_of_landmarks);
+                       return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+               }
+
+               *pos_x = result.x_pos[index];
+               *pos_y = result.y_pos[index];
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return MEDIA_VISION_ERROR_NONE;
+}
\ No newline at end of file
index f68dc5c7a56bc20129ccbc11055d23025f00cbc2..c309a64709506340921160b39bbf364b1cdaf4a5 100644 (file)
@@ -401,6 +401,7 @@ find . -name '*.gcno' -not -path "./test/*" -not -path "./mv_machine_learning/*"
 %if "%{enable_ml_landmark_detection}" == "1"
 %{_datadir}/%{name}/facial_landmark.json
 %{_datadir}/%{name}/pose_landmark.json
+%{_datadir}/%{name}/hand_landmark.json
 %{_libdir}/libmv_landmark_detection.so
 %endif
 %if "%{enable_ml_image_segmentation}" == "1"
@@ -450,6 +451,9 @@ find . -name '*.gcno' -not -path "./test/*" -not -path "./mv_machine_learning/*"
 %{_includedir}/media/mv_pose_landmark_internal.h
 %{_includedir}/media/mv_pose_landmark.h
 %{_includedir}/media/mv_pose_landmark_type.h
+%{_includedir}/media/mv_hand_landmark_internal.h
+%{_includedir}/media/mv_hand_landmark.h
+%{_includedir}/media/mv_hand_landmark_type.h
 %{_libdir}/pkgconfig/*landmark-detection.pc
 %endif
 %if "%{enable_ml_image_segmentation}" == "1"