mv_machine_learning: add face detection api support
authorInki Dae <inki.dae@samsung.com>
Thu, 30 Mar 2023 08:14:42 +0000 (17:14 +0900)
committerKwanghoon Son <k.son@samsung.com>
Fri, 7 Apr 2023 08:53:23 +0000 (17:53 +0900)
[Issue type] : new feature

Added face detection api support to object detection task group.

Models for face detection same as the ones for object detection.
Only difference between them is label data - face detection model
has a fixed label as "face" so this patch adds face detection API
implementation and its adapter class to object detection task group,
and it makes face detection adapter to share object detection class
and its child classes.

Change-Id: I32eb823e75deac84446316308ccd36ec396b1d7c
Signed-off-by: Inki Dae <inki.dae@samsung.com>
20 files changed:
CMakeLists.txt
include/mv_face_detection_internal.h [new file with mode: 0644]
include/mv_face_detection_type.h [new file with mode: 0644]
include/mv_object_detection_internal.h
include/mv_object_detection_type.h
mv_machine_learning/object_detection/include/face_detection_adapter.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/mv_face_detection_open.h [new file with mode: 0644]
mv_machine_learning/object_detection/include/mv_object_detection_config.h
mv_machine_learning/object_detection/include/object_detection.h
mv_machine_learning/object_detection/include/object_detection_type.h
mv_machine_learning/object_detection/meta/face_detection.json [new file with mode: 0644]
mv_machine_learning/object_detection/src/face_detection_adapter.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/mv_face_detection.c [new file with mode: 0644]
mv_machine_learning/object_detection/src/mv_face_detection_open.cpp [new file with mode: 0644]
mv_machine_learning/object_detection/src/mv_object_detection.c
mv_machine_learning/object_detection/src/mv_object_detection_open.cpp
mv_machine_learning/object_detection/src/object_detection.cpp
mv_machine_learning/object_detection/src/object_detection_adapter.cpp
packaging/capi-media-vision.spec
test/testsuites/machine_learning/object_detection/test_object_detection.cpp

index bcad937..4e0e997 100644 (file)
@@ -203,6 +203,7 @@ if (${ENABLE_ML_OBJECT_DETECTION})
     )
     install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}-object-detection.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
     install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/object_detection/meta/object_detection.json DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
+    install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/object_detection/meta/face_detection.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_face_detection_internal.h b/include/mv_face_detection_internal.h
new file mode 100644 (file)
index 0000000..c69aa36
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * 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 __TIZEN_MEDIAVISION_FACE_DETECT_INTERNAL_H__
+#define __TIZEN_MEDIAVISION_FACE_DETECT_INTERNAL_H__
+
+#include <mv_common.h>
+#include <mv_face_detection_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_face_detection.h
+ * @internal
+ * @brief  This file contains the Inference based Media Vision API.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_INFERENCE_MODULE
+ * @{
+ */
+
+/**
+ * @internal
+ * @brief Creates a inference handle for object detection object.
+ * @details Use this function to create a inference handle. After the creation
+ *          the object detection 3d task has to be prepared with
+ *          mv_face_detection_prepare() function to prepare a network
+ *          for the inference.
+ *
+ * @since_tizen 7.5
+ *
+ * @remarks The @a infer should be released using mv_face_detection_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
+ *
+ * @see mv_face_detection_destroy()
+ * @see mv_face_detection_prepare()
+ */
+int mv_face_detection_create(mv_face_detection_h *handle);
+
+/**
+ * @internal
+ * @brief Destroys inference handle and releases all its resources.
+ *
+ * @since_tizen 7.5
+ *
+ * @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_face_detection_create()
+ *
+ * @see mv_face_detection_create()
+ */
+int mv_face_detection_destroy(mv_face_detection_h handle);
+
+/**
+ * @internal
+ * @brief Sets user-given model information.
+ * @details Use this function to change the model information instead of default one after calling @ref mv_face_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the object detection object.
+ * @param[in] model_name    Model name.
+ * @param[in] model_file    Model file name.
+ * @param[in] meta_file     Model meta file name.
+ * @param[in] label_file    Label file 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 object detection handle by calling @ref mv_face_detection_create()
+ */
+int mv_face_detection_set_model(mv_face_detection_h handle, const char *model_name, const char *model_file,
+                                                               const char *meta_file, const char *label_file);
+
+/**
+ * @internal
+ * @brief Configures the backend for the object detection inference.
+ *
+ * @since_tizen 7.5
+ *
+ * @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_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_INVALID_OPERATION Invalid operation
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ */
+int mv_face_detection_configure(mv_face_detection_h handle);
+
+/**
+ * @internal
+ * @brief Prepares the object detection inference
+ * @details Use this function to prepare the object detection inference based on
+ *          the configured network.
+ *
+ * @since_tizen 7.5
+ *
+ * @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_PERMISSION_DENIED Permission denied
+ * @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_face_detection_prepare(mv_face_detection_h handle);
+
+/**
+ * @internal
+ * @brief Performs the object detection inference on the @a source.
+ *
+ * @since_tizen 7.5
+ * @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_object_detect_create()
+ * @pre Prepare an inference by calling mv_object_detect_configure()
+ * @pre Prepare an inference by calling mv_object_detect_prepare()
+ */
+int mv_face_detection_inference(mv_face_detection_h handle, mv_source_h source);
+
+/**
+ * @internal
+ * @brief Gets the object detection inference result on the @a source.
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle               The handle to the inference
+ * @param[out] number_of_objects  A number of objects detected.
+ * @param[out] indices            Label indices to detected objects.
+ * @param[out] confidences        Probability to detected objects.
+ * @param[out] left               An left position array to bound boxes.
+ * @param[out] top                An top position array to bound boxes.
+ * @param[out] right              An right position array to bound boxes.
+ * @param[out] bottom             An bottom position array to bound boxes.
+ *
+ * @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_object_detect_create()
+ * @pre Prepare an inference by calling mv_object_detect_configure()
+ * @pre Prepare an inference by calling mv_object_detect_prepare()
+ * @pre Prepare an inference by calling mv_object_detect_inference()
+ */
+int mv_face_detection_get_result(mv_face_detection_h handle, unsigned int *number_of_objects,
+                                                                const unsigned int **indices, const float **confidences, const int **left,
+                                                                const int **top, const int **right, const int **bottom);
+
+/**
+ * @internal
+ * @brief Gets the label string to a given index.
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle       The handle to the inference
+ * @param[in] index       Label index to get the label string.
+ * @param[out] label  Label string to a given index.
+ *
+ * @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_object_detect_create()
+ * @pre Prepare an inference by calling mv_object_detect_configure()
+ * @pre Prepare an inference by calling mv_object_detect_prepare()
+ * @pre Prepare an inference by calling mv_object_detect_inference()
+ */
+int mv_face_detection_get_label(mv_face_detection_h handle, const unsigned int index, const char **label);
+
+/**
+ * @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_face_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the object detection 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 object detection handle by calling @ref mv_face_detection_create()
+ */
+int mv_face_detection_set_engine(mv_face_detection_h handle, const char *engine_type, const char *device_type);
+
+/**
+ * @internal
+ * @brief Gets a number of inference engines available for object detection task API.
+ * @details Use this function to get how many inference engines are supported for object detection after calling @ref mv_face_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the object detection object.
+ * @param[out] engine_count  A number of inference engines available for object detection 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 object detection handle by calling @ref mv_face_detection_create()
+ */
+int mv_face_detection_get_engine_count(mv_face_detection_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_face_detection_get_engine_count().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the object detection 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 object detection task API by calling @ref mv_face_detection_get_engine_count()
+ */
+int mv_face_detection_get_engine_type(mv_face_detection_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_face_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the object detection 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 object detection handle by calling @ref mv_face_detection_create()
+ */
+int mv_face_detection_get_device_count(mv_face_detection_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_face_detection_configure().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the object detection 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 object detection handle by calling @ref mv_face_detection_create()
+ * @pre Configure object detection task by calling @ref mv_face_detection_configure()
+ */
+int mv_face_detection_get_device_type(mv_face_detection_h handle, const char *engine_type,
+                                                                         const unsigned int device_index, char **device_type);
+/**
+ * @}
+ */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_DETECT_INTERNAL_H__ */
diff --git a/include/mv_face_detection_type.h b/include/mv_face_detection_type.h
new file mode 100644 (file)
index 0000000..dc7eced
--- /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 __TIZEN_MEDIAVISION_MV_FACE_DETECTION_TYPE_H__
+#define __TIZEN_MEDIAVISION_MV_FACE_DETECTION_TYPE_H__
+
+#include <mv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @file   mv_face_detection_type.h
+ * @brief  This file contains the face recognition handle for Mediavision.
+ */
+
+/**
+ * @addtogroup CAPI_MEDIA_VISION_FACE_DETECT_MODULE
+ * @{
+ */
+
+/**
+ * @brief The face detection object handle.
+ *
+ * @since_tizen 7.5
+ */
+typedef void *mv_face_detection_h;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_MV_FACE_DETECTION_TYPE_H__ */
index ff20353..d11dd0f 100644 (file)
@@ -26,6 +26,7 @@ extern "C" {
 
 /**
  * @file   mv_object_detection.h
+ * @internal
  * @brief  This file contains the Inference based Media Vision API.
  */
 
@@ -35,6 +36,7 @@ extern "C" {
  */
 
 /**
+ * @internal
  * @brief Creates a inference handle for object detection object.
  * @details Use this function to create a inference handle. After the creation
  *          the object detection 3d task has to be prepared with
@@ -59,6 +61,7 @@ extern "C" {
 int mv_object_detection_create(mv_object_detection_h *infer);
 
 /**
+ * @internal
  * @brief Destroys inference handle and releases all its resources.
  *
  * @since_tizen 7.5
@@ -77,28 +80,30 @@ int mv_object_detection_create(mv_object_detection_h *infer);
 int mv_object_detection_destroy(mv_object_detection_h infer);
 
 /**
-        * @brief Set user-given model information.
-        * @details Use this function to change the model information instead of default one after calling @ref mv_object_detection_create().
-        *
-        * @since_tizen 7.5
-        *
-        * @param[in] handle        The handle to the object detection object.
-        * @param[in] model_name    Model name.
-        * @param[in] model_file    Model file name.
-        * @param[in] meta_file     Model meta file name.
-        * @param[in] label_file    Label file 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 object detection handle by calling @ref mv_object_detection_create()
-        */
+ * @internal
+ * @brief Set user-given model information.
+ * @details Use this function to change the model information instead of default one after calling @ref mv_object_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the object detection object.
+ * @param[in] model_name    Model name.
+ * @param[in] model_file    Model file name.
+ * @param[in] meta_file     Model meta file name.
+ * @param[in] label_file    Label file 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 object detection handle by calling @ref mv_object_detection_create()
+ */
 int mv_object_detection_set_model(mv_object_detection_h handle, const char *model_name, const char *model_file,
                                                                  const char *meta_file, const char *label_file);
 
 /**
+ * @internal
  * @brief Configures the backend for the object detection inference.
  *
  * @since_tizen 7.5
@@ -114,6 +119,7 @@ int mv_object_detection_set_model(mv_object_detection_h handle, const char *mode
 int mv_object_detection_configure(mv_object_detection_h infer);
 
 /**
+ * @internal
  * @brief Prepares the object detection inference
  * @details Use this function to prepare the object detection inference based on
  *          the configured network.
@@ -135,6 +141,7 @@ int mv_object_detection_configure(mv_object_detection_h infer);
 int mv_object_detection_prepare(mv_object_detection_h infer);
 
 /**
+ * @internal
  * @brief Performs the object detection inference on the @a source.
  *
  * @since_tizen 7.5
@@ -159,6 +166,7 @@ int mv_object_detection_prepare(mv_object_detection_h infer);
 int mv_object_detection_inference(mv_object_detection_h infer, mv_source_h source);
 
 /**
+ * @internal
  * @brief Gets the object detection inference result on the @a source.
  *
  * @since_tizen 7.5
@@ -189,6 +197,7 @@ int mv_object_detection_get_result(mv_object_detection_h infer, unsigned int *nu
                                                                   const int **top, const int **right, const int **bottom);
 
 /**
+ * @internal
  * @brief Gets the label string to a given index.
  *
  * @since_tizen 7.5
@@ -212,101 +221,106 @@ int mv_object_detection_get_result(mv_object_detection_h infer, unsigned int *nu
 int mv_object_detection_get_label(mv_object_detection_h infer, const unsigned int index, const char **out_label);
 
 /**
-        * @brief Set 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_object_detection_create().
-        *
-        * @since_tizen 7.5
-        *
-        * @param[in] handle        The handle to the object detection 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 object detection handle by calling @ref mv_object_detection_create()
-        */
+ * @internal
+ * @brief Set 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_object_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the object detection 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 object detection handle by calling @ref mv_object_detection_create()
+ */
 int mv_object_detection_set_engine(mv_object_detection_h handle, const char *engine_type, const char *device_type);
 
 /**
-        * @brief Get a number of inference engines available for object detection task API.
-        * @details Use this function to get how many inference engines are supported for object detection after calling @ref mv_object_detection_create().
-        *
-        * @since_tizen 7.5
-        *
-        * @param[in] handle         The handle to the object detection object.
-        * @param[out] engine_count  A number of inference engines available for object detection 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 object detection handle by calling @ref mv_object_detection_create()
-        */
+ * @internal
+ * @brief Get a number of inference engines available for object detection task API.
+ * @details Use this function to get how many inference engines are supported for object detection after calling @ref mv_object_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the object detection object.
+ * @param[out] engine_count  A number of inference engines available for object detection 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 object detection handle by calling @ref mv_object_detection_create()
+ */
 int mv_object_detection_get_engine_count(mv_object_detection_h handle, unsigned int *engine_count);
 
 /**
-        * @brief Get 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_object_detection_get_engine_count().
-        *
-        * @since_tizen 7.5
-        *
-        * @param[in] handle        The handle to the object detection 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 object detection task API by calling @ref mv_object_detection_get_engine_count()
-        */
+ * @internal
+ * @brief Get 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_object_detection_get_engine_count().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the object detection 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 object detection task API by calling @ref mv_object_detection_get_engine_count()
+ */
 int mv_object_detection_get_engine_type(mv_object_detection_h handle, const unsigned int engine_index,
                                                                                char **engine_type);
 
 /**
-        * @brief Get 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_object_detection_create().
-        *
-        * @since_tizen 7.5
-        *
-        * @param[in] handle         The handle to the object detection 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 object detection handle by calling @ref mv_object_detection_create()
-        */
+ * @internal
+ * @brief Get 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_object_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the object detection 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 object detection handle by calling @ref mv_object_detection_create()
+ */
 int mv_object_detection_get_device_count(mv_object_detection_h handle, const char *engine_type,
                                                                                 unsigned int *device_count);
 
 /**
-        * @brief Get device type list available.
-        * @details Use this function to get what device types are supported for current inference engine type after calling @ref mv_object_detection_configure().
-        *
-        * @since_tizen 7.5
-        *
-        * @param[in] handle         The handle to the object detection 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 object detection handle by calling @ref mv_object_detection_create()
-        * @pre Configure object detection task by calling @ref mv_object_detection_configure()
-        */
+ * @internal
+ * @brief Get device type list available.
+ * @details Use this function to get what device types are supported for current inference engine type after calling @ref mv_object_detection_configure().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the object detection 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 object detection handle by calling @ref mv_object_detection_create()
+ * @pre Configure object detection task by calling @ref mv_object_detection_configure()
+ */
 int mv_object_detection_get_device_type(mv_object_detection_h handle, const char *engine_type,
                                                                                const unsigned int device_index, char **device_type);
 /**
@@ -316,4 +330,4 @@ int mv_object_detection_get_device_type(mv_object_detection_h handle, const char
 }
 #endif /* __cplusplus */
 
-#endif /* __TIZEN_MEDIAVISION_OBJECT_DETECT_3D_INTERNAL_H__ */
+#endif /* __TIZEN_MEDIAVISION_OBJECT_DETECT_INTERNAL_H__ */
index 909392e..c5d4f50 100644 (file)
@@ -36,7 +36,7 @@ extern "C" {
 /**
  * @brief The object detection object handle.
  *
- * @since_tizen 7.0
+ * @since_tizen 7.5
  */
 typedef void *mv_object_detection_h;
 
@@ -48,4 +48,4 @@ typedef void *mv_object_detection_h;
 }
 #endif /* __cplusplus */
 
-#endif /* __TIZEN_MEDIAVISION_MV_OBJECT_DETECTION_3D_TYPE_H__ */
+#endif /* __TIZEN_MEDIAVISION_MV_OBJECT_DETECTION_TYPE_H__ */
diff --git a/mv_machine_learning/object_detection/include/face_detection_adapter.h b/mv_machine_learning/object_detection/include/face_detection_adapter.h
new file mode 100644 (file)
index 0000000..f763380
--- /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 __FACE_DETECTION_ADAPTER_H__
+#define __FACE_DETECTION_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "itask.h"
+#include "mobilenet_v1_ssd.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T, typename V> class FaceDetectionAdapter : public mediavision::common::ITask<T, V>
+{
+private:
+       std::unique_ptr<ObjectDetection> _object_detection;
+       T _source;
+       std::string _model_name;
+       std::string _model_file;
+       std::string _meta_file;
+       std::string _label_file;
+
+public:
+       FaceDetectionAdapter();
+       ~FaceDetectionAdapter();
+
+       void create(int type) override;
+
+       void setModelInfo(const char *model_file, const char *meta_file, const char *label_file,
+                                         const char *model_name) override;
+       void setEngineInfo(const char *engine_type, const char *device_type) override;
+       void configure() override;
+       void getNumberOfEngines(unsigned int *number_of_engines) override;
+       void getEngineType(unsigned int engine_index, char **engine_type) override;
+       void getNumberOfDevices(const char *engine_type, unsigned int *number_of_devices) override;
+       void getDeviceType(const char *engine_type, unsigned int device_index, char **device_type) override;
+       void prepare() override;
+       void setInput(T &t) override;
+       void perform() override;
+       V &getOutput() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/include/mv_face_detection_open.h b/mv_machine_learning/object_detection/include/mv_face_detection_open.h
new file mode 100644 (file)
index 0000000..9203f79
--- /dev/null
@@ -0,0 +1,302 @@
+/**
+ * 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 __MEDIA_VISION_FACE_DETECTION_OPEN_H__
+#define __MEDIA_VISION_FACE_DETECTION_OPEN_H__
+
+#include <mv_common.h>
+#include <mv_private.h>
+#include <mv_face_detection_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @brief Create face detection object handle.
+ * @details Use this function to create an face detection object handle.
+ *          After creation the handle has to be prepared with
+ *          @ref mv_face_detection_prepare_open() function to prepare
+ *               an face detection object.
+ *
+ * @since_tizen 7.5
+ *
+ * @param[out] handle    The handle to the face detection object to be created
+ *
+ * @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_OUT_OF_MEMORY Out of memory
+ *
+ * @post Release @a handle by using
+ *       @ref mv_face_detection_destroy_open() function when it is not needed
+ *       anymore
+ *
+ * @see mv_face_detection_destroy_open()
+ */
+int mv_face_detection_create_open(mv_face_detection_h *handle);
+
+/**
+ * @brief Destroy face detection handle and releases all its resources.
+ *
+ * @since_tizen 7.0
+ *
+ * @param[in] handle    The handle to the face detection object to be destroyed.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIA_VISION_ERROR_NONE Successful
+ * @retval #MEDIA_VISION_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @pre Create an face detection handle by using @ref mv_face_detection_create_open()
+ *
+ * @see mv_face_detection_create_open()
+ */
+int mv_face_detection_destroy_open(mv_face_detection_h handle);
+
+/**
+ * @brief Set user-given model information.
+ * @details Use this function to change the model information instead of default one after calling @ref mv_face_detection_create().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the face detection object.
+ * @param[in] model_name    Model name.
+ * @param[in] model_file    Model file name.
+ * @param[in] meta_type     Model meta file name.
+ * @param[in] label_file    Label file 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 face detection handle by calling @ref mv_face_detection_create()
+ */
+int mv_face_detection_set_model_open(mv_face_detection_h handle, const char *model_name, const char *model_file,
+                                                                        const char *meta_file, const char *label_file);
+
+/**
+ * @brief Configure the backend to the inference handle
+ *
+ * @since_tizen 7.5
+ *
+ * @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_OUT_OF_MEMORY Out of memory
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED Not supported
+ */
+int mv_face_detection_configure_open(mv_face_detection_h handle);
+
+/**
+ * @brief Prepare inference.
+ * @details Use this function to prepare inference based on
+ *          the configured network.
+ *
+ * @since_tizen 7.5
+ *
+ * @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_INVALID_DATA Invalid model data
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int mv_face_detection_prepare_open(mv_face_detection_h handle);
+
+/**
+ *
+ * @brief Inference with a given face on the @a source
+ * @details Use this function to inference with a given source.
+ *
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the face detection object.
+ * @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_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIA_VISION_ERROR_NOT_SUPPORTED_FORMAT Source colorspace
+ *                                                  isn't supported
+ * @retval #MEDIA_VISION_ERROR_OUT_OF_MEMORY Out of memory
+ *
+ * @pre Create a source handle by calling @ref mv_create_source()
+ * @pre Create an face detection handle by calling @ref mv_face_detection_create_open()
+ * @pre Prepare an inference by calling mv_object_detect_configure_open()
+ * @pre Prepare an face detection by calling @ref mv_face_detection_prepare_open()
+ */
+int mv_face_detection_inference_open(mv_face_detection_h handle, mv_source_h source);
+
+/**
+ * @brief Gets the face detection inference result on the @a source.
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle              The handle to the inference
+ * @param[out] number_of_objects  A number of objects detected.
+ * @param[out] indices            Label indices to detected objects.
+ * @param[out] confidences        Probability to detected objects.
+ * @param[out] left               An left position array to bound boxs.
+ * @param[out] top                An top position array to bound boxs.
+ * @param[out] right              An right position array to bound boxs.
+ * @param[out] bottom             An bottom position array to bound boxs.
+ *
+ * @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_object_detect_create_open()
+ * @pre Prepare an inference by calling mv_object_detect_configure_open()
+ * @pre Prepare an inference by calling mv_object_detect_prepare_open()
+ * @pre Prepare an inference by calling mv_object_detect_inference_open()
+ */
+int mv_face_detection_get_result_open(mv_face_detection_h handle, unsigned int *number_of_objects,
+                                                                         const unsigned int **indices, const float **confidences, const int **left,
+                                                                         const int **top, const int **right, const int **bottom);
+
+/**
+ * @brief Gets the label string to a given index.
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle       The handle to the inference
+ * @param[in] index       Label index to get the label string.
+ * @param[out] label  Label string to a given index.
+ *
+ * @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_object_detect_create()
+ * @pre Prepare an inference by calling mv_object_detect_configure()
+ * @pre Prepare an inference by calling mv_object_detect_prepare()
+ * @pre Prepare an inference by calling mv_object_detect_inference()
+ */
+int mv_face_detection_get_label_open(mv_face_detection_h handle, const unsigned int index, const char **label);
+
+/**
+ * @brief Sets user-given backend and device types for inference.
+ * @details Use this function to change the backend and device types for inference instead of default ones after calling @ref mv_face_detection_create_open().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the image classification object.
+ * @param[in] backend_type  A string of backend 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 image classification handle by calling @ref mv_face_detection_create_open()
+ */
+int mv_face_detection_set_engine_open(mv_face_detection_h handle, const char *backend_type, const char *device_type);
+
+/**
+ * @brief Gets a number of inference engines available for image classification task API.
+ * @details Use this function to get how many inference engines are supported for image classification after calling @ref mv_face_detection_create_open().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the image classification object.
+ * @param[out] engine_count  A number of inference engines available for image classification 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 image classification handle by calling @ref mv_face_detection_create_open()
+ */
+int mv_face_detection_get_engine_count_open(mv_face_detection_h handle, unsigned int *engine_count);
+
+/**
+ * @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_face_detection_get_engine_count().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle        The handle to the image classification 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 image classification task API by calling @ref mv_face_detection_get_engine_count()
+ */
+int mv_face_detection_get_engine_type_open(mv_face_detection_h handle, const unsigned int engine_index,
+                                                                                  char **engine_type);
+
+/**
+ * @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_face_detection_create_open().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the image classification 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 image classification handle by calling @ref mv_face_detection_create_open()
+ */
+int mv_face_detection_get_device_count_open(mv_face_detection_h handle, const char *engine_type,
+                                                                                       unsigned int *device_count);
+
+/**
+ * @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_face_detection_configure().
+ *
+ * @since_tizen 7.5
+ *
+ * @param[in] handle         The handle to the image classification 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 image classification handle by calling @ref mv_face_detection_create_open()
+ * @pre Configure image classification task by calling @ref mv_face_detection_configure_open()
+ */
+int mv_face_detection_get_device_type_open(mv_face_detection_h handle, const char *engine_type,
+                                                                                  const unsigned int device_index, char **device_type);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MEDIA_VISION_INFERENCE_OPEN_H__ */
index ffa62cb..55514cf 100644 (file)
@@ -29,7 +29,7 @@
  * @brief Defines #MV_OBJECT_DETECTION_MODEL_FILE_PATH
  *        to set the object detection model file path.
  *
- * @since_tizen 7.0
+ * @since_tizen 7.5
  */
 #define MV_OBJECT_DETECTION_MODEL_FILE_PATH "MODEL_FILE_NAME"
 
@@ -40,7 +40,7 @@
  *          node names, input tensor's width and height,
  *          mean and standard deviation values for pre-processing.
  *
- * @since_tizen 7.0
+ * @since_tizen 7.5
  */
 #define MV_OBJECT_DETECTION_MODEL_META_FILE_PATH "META_FILE_NAME"
 
@@ -50,7 +50,7 @@
  * @brief Defines #MV_OBJECT_DETECT_BACKEND_TYPE
  *        to set inference backend engine type. In default, tensorflow lite is used.
  *
- * @since_tizen 7.0
+ * @since_tizen 7.5
  */
 #define MV_OBJECT_DETECTION_BACKEND_TYPE "BACKEND_TYPE"
 
  * @brief Defines #MV_OBJECT_DETECT_TARGET_DEVICE_TYPE
  *        to set inference target device type. In default, CPU device is used.
  *
- * @since_tizen 7.0
+ * @since_tizen 7.5
  */
 #define MV_OBJECT_DETECTION_TARGET_DEVICE_TYPE "TARGET_DEVICE_TYPE"
 
-#define MV_OBJECT_DETECTION_META_FILE_NAME "object_detection.json"
-
-#endif /* __MEDIA_VISION_INFERENCE_OPEN_H__ */
+#endif /* __MEDIA_VISION_OBJECT_DETECTION_CONFIG_H__ */
index 4ade7f0..8714c4f 100644 (file)
@@ -69,7 +69,7 @@ public:
        void getEngineType(unsigned int engine_index, char **engine_type);
        void getNumberOfDevices(const char *engine_type, unsigned int *number_of_devices);
        void getDeviceType(const char *engine_type, const unsigned int device_index, char **device_type);
-       void parseMetaFile();
+       void parseMetaFile(const char *meta_file_name);
        void configure();
        void prepare();
        void preprocess(mv_source_h &mv_src);
index 96bac8e..abf5873 100644 (file)
@@ -47,7 +47,8 @@ struct ObjectDetectionResult {
 enum class ObjectDetectionTaskType {
        OBJECT_DETECTION_TASK_NONE = 0,
        MOBILENET_V1_SSD,
-       MOBILENET_V2_SSD
+       MOBILENET_V2_SSD,
+       FD_MOBILENET_V1_SSD
        // TODO
 };
 
diff --git a/mv_machine_learning/object_detection/meta/face_detection.json b/mv_machine_learning/object_detection/meta/face_detection.json
new file mode 100644 (file)
index 0000000..ffab5c2
--- /dev/null
@@ -0,0 +1,35 @@
+{
+    "attributes":
+    [
+        {
+            "name" : "MODEL_DEFAULT_PATH",
+            "type" : "string",
+            "value" : "/usr/share/capi-media-vision/models/FD/tflite/"
+        },
+               {
+            "name"  : "MODEL_FILE_NAME",
+            "type"  : "string",
+            "value" : "fd_mobilenet_v1_ssd_postop_300x300.tflite"
+        },
+        {
+            "name"  : "META_FILE_NAME",
+            "type"  : "string",
+            "value" : "fd_mobilenet_v1_ssd_postop_300x300.json"
+        },
+        {
+            "name"  : "LABEL_FILE_NAME",
+            "type"  : "string",
+            "value" : "fd_mobilenet_v1_ssd_postop_label.txt"
+        },
+        {
+            "name"  : "BACKEND_TYPE",
+            "type"  : "integer",
+            "value" : 1
+        },
+        {
+            "name"  : "TARGET_DEVICE_TYPE",
+            "type"  : "integer",
+            "value" : 1
+        }
+    ]
+}
diff --git a/mv_machine_learning/object_detection/src/face_detection_adapter.cpp b/mv_machine_learning/object_detection/src/face_detection_adapter.cpp
new file mode 100644 (file)
index 0000000..ad5356e
--- /dev/null
@@ -0,0 +1,143 @@
+/**
+ * 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"
+
+using namespace std;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+template<typename T, typename V> FaceDetectionAdapter<T, V>::FaceDetectionAdapter() : _source()
+{
+       // In default, FD Mobilenet v1 ssd model will be used.
+       // If other model is set by user then strategy pattern will be used
+       // to create its corresponding concerte class by calling create().
+       _object_detection = make_unique<MobilenetV1Ssd>(ObjectDetectionTaskType::FD_MOBILENET_V1_SSD);
+}
+
+template<typename T, typename V> FaceDetectionAdapter<T, V>::~FaceDetectionAdapter()
+{}
+
+template<typename T, typename V> void FaceDetectionAdapter<T, V>::create(int type)
+{
+       ObjectDetectionTaskType task_type = static_cast<ObjectDetectionTaskType>(type);
+
+       // If default task type is same as a given one then skip.
+       if (_object_detection->getTaskType() == task_type)
+               return;
+
+       _object_detection.reset();
+
+       if (task_type == ObjectDetectionTaskType::FD_MOBILENET_V1_SSD)
+               _object_detection = make_unique<MobilenetV1Ssd>(task_type);
+       // TODO.
+}
+
+template<typename T, typename V>
+void FaceDetectionAdapter<T, V>::setModelInfo(const char *model_file, const char *meta_file, const char *label_file,
+                                                                                         const char *model_name)
+{
+       string model_name_str(model_name);
+
+       if (!model_name_str.empty()) {
+               transform(model_name_str.begin(), model_name_str.end(), model_name_str.begin(), ::toupper);
+
+               int model_type = 0;
+
+               if (model_name_str == string("FD_MOBILENET_V1_SSD"))
+                       model_type = static_cast<int>(ObjectDetectionTaskType::FD_MOBILENET_V1_SSD);
+               // TODO.
+               else
+                       throw InvalidParameter("Invalid face detection model name.");
+
+               create(static_cast<int>(model_type));
+       }
+
+       _model_file = string(model_file);
+       _meta_file = string(meta_file);
+       _label_file = string(label_file);
+
+       if (_model_file.empty() && _meta_file.empty() && _label_file.empty())
+               return;
+
+       _object_detection->setUserModel(_model_file, _meta_file, _label_file);
+}
+
+template<typename T, typename V>
+void FaceDetectionAdapter<T, V>::setEngineInfo(const char *engine_type, const char *device_type)
+{
+       _object_detection->setEngineInfo(string(engine_type), string(device_type));
+}
+
+template<typename T, typename V> void FaceDetectionAdapter<T, V>::configure()
+{
+       _object_detection->parseMetaFile("face_detection.json");
+       _object_detection->configure();
+}
+
+template<typename T, typename V> void FaceDetectionAdapter<T, V>::getNumberOfEngines(unsigned int *number_of_engines)
+{
+       _object_detection->getNumberOfEngines(number_of_engines);
+}
+
+template<typename T, typename V>
+void FaceDetectionAdapter<T, V>::getEngineType(unsigned int engine_index, char **engine_type)
+{
+       _object_detection->getEngineType(engine_index, engine_type);
+}
+
+template<typename T, typename V>
+void FaceDetectionAdapter<T, V>::getNumberOfDevices(const char *engine_type, unsigned int *number_of_devices)
+{
+       _object_detection->getNumberOfDevices(engine_type, number_of_devices);
+}
+
+template<typename T, typename V>
+void FaceDetectionAdapter<T, V>::getDeviceType(const char *engine_type, unsigned int device_index, char **device_type)
+{
+       _object_detection->getDeviceType(engine_type, device_index, device_type);
+}
+
+template<typename T, typename V> void FaceDetectionAdapter<T, V>::prepare()
+{
+       _object_detection->prepare();
+}
+
+template<typename T, typename V> void FaceDetectionAdapter<T, V>::setInput(T &t)
+{
+       _source = t;
+}
+
+template<typename T, typename V> void FaceDetectionAdapter<T, V>::perform()
+{
+       _object_detection->preprocess(_source.inference_src);
+       _object_detection->inference(_source.inference_src);
+}
+
+template<typename T, typename V> V &FaceDetectionAdapter<T, V>::getOutput()
+{
+       return _object_detection->result();
+}
+
+template class FaceDetectionAdapter<ObjectDetectionInput, ObjectDetectionResult>;
+}
+}
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/src/mv_face_detection.c b/mv_machine_learning/object_detection/src/mv_face_detection.c
new file mode 100644 (file)
index 0000000..99fe517
--- /dev/null
@@ -0,0 +1,233 @@
+/**
+ * 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 "mv_face_detection_internal.h"
+#include "mv_face_detection_open.h"
+
+/**
+ * @file  mv_face_detection.c
+ * @brief This file contains Media Vision inference module.
+ */
+
+int mv_face_detection_create(mv_face_detection_h *infer)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
+       MEDIA_VISION_NULL_ARG_CHECK(infer);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_create_open(infer);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+       return ret;
+}
+
+int mv_face_detection_destroy(mv_face_detection_h infer)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(infer);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_destroy_open(infer);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+       return ret;
+}
+
+int mv_face_detection_set_model(mv_face_detection_h handle, const char *model_name, const char *model_file,
+                                                               const char *meta_file, const char *label_file)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_face_check_system_info_feature_supported());
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(model_name);
+       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();
+
+       int ret = mv_face_detection_set_model_open(handle, model_name, model_file, meta_file, label_file);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_set_engine(mv_face_detection_h handle, const char *backend_type, const char *device_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_face_check_system_info_feature_supported());
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(backend_type);
+       MEDIA_VISION_NULL_ARG_CHECK(device_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_set_engine_open(handle, backend_type, device_type);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_get_engine_count(mv_face_detection_h handle, unsigned int *engine_count)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_face_check_system_info_feature_supported());
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_count);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_get_engine_count_open(handle, engine_count);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_get_engine_type(mv_face_detection_h handle, const unsigned int engine_index, char **engine_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_face_check_system_info_feature_supported());
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_get_engine_type_open(handle, engine_index, engine_type);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_get_device_count(mv_face_detection_h handle, const char *engine_type, unsigned int *device_count)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_face_check_system_info_feature_supported());
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(device_count);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_get_device_count_open(handle, engine_type, device_count);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_get_device_type(mv_face_detection_h handle, const char *engine_type,
+                                                                         const unsigned int device_index, char **device_type)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_face_check_system_info_feature_supported());
+
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_NULL_ARG_CHECK(engine_type);
+       MEDIA_VISION_NULL_ARG_CHECK(device_type);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_get_device_type_open(handle, engine_type, device_index, device_type);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_configure(mv_face_detection_h infer)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(infer);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_configure_open(infer);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+       return ret;
+}
+
+int mv_face_detection_prepare(mv_face_detection_h infer)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(infer);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_prepare_open(infer);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+       return ret;
+}
+
+int mv_face_detection_inference(mv_face_detection_h infer, mv_source_h source)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_image_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(source);
+       MEDIA_VISION_INSTANCE_CHECK(infer);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_inference_open(infer, source);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_get_result(mv_face_detection_h infer, unsigned int *number_of_objects,
+                                                                const unsigned int **indices, const float **confidences, const int **left,
+                                                                const int **top, const int **right, const int **bottom)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_image_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(infer);
+       MEDIA_VISION_INSTANCE_CHECK(number_of_objects);
+       MEDIA_VISION_INSTANCE_CHECK(indices);
+       MEDIA_VISION_INSTANCE_CHECK(confidences);
+       MEDIA_VISION_INSTANCE_CHECK(left);
+       MEDIA_VISION_INSTANCE_CHECK(top);
+       MEDIA_VISION_INSTANCE_CHECK(right);
+       MEDIA_VISION_INSTANCE_CHECK(bottom);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret =
+                       mv_face_detection_get_result_open(infer, number_of_objects, indices, confidences, left, top, right, bottom);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
+
+int mv_face_detection_get_label(mv_face_detection_h infer, const unsigned int index, const char **out_label)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_image_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(infer);
+       MEDIA_VISION_INSTANCE_CHECK(out_label);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = mv_face_detection_get_label_open(infer, index, out_label);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
+       return ret;
+}
\ No newline at end of file
diff --git a/mv_machine_learning/object_detection/src/mv_face_detection_open.cpp b/mv_machine_learning/object_detection/src/mv_face_detection_open.cpp
new file mode 100644 (file)
index 0000000..aedf1e7
--- /dev/null
@@ -0,0 +1,386 @@
+/**
+ * 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 "itask.h"
+#include "mv_face_detection_open.h"
+#include "face_detection_adapter.h"
+#include "machine_learning_exception.h"
+#include "object_detection_type.h"
+#include "context.h"
+
+#include <new>
+#include <unistd.h>
+#include <string>
+#include <algorithm>
+#include <mutex>
+#include <iostream>
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::common;
+using namespace mediavision::machine_learning;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning::exception;
+using FaceDetectionTask = ITask<ObjectDetectionInput, ObjectDetectionResult>;
+
+static mutex g_face_detection_mutex;
+
+int mv_face_detection_create_open(mv_face_detection_h *out_handle)
+{
+       if (!out_handle) {
+               LOGE("Handle can't be created because handle pointer is NULL");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       Context *context = nullptr;
+       FaceDetectionTask *task = nullptr;
+
+       try {
+               context = new Context();
+               task = new FaceDetectionAdapter<ObjectDetectionInput, ObjectDetectionResult>();
+               context->__tasks.insert(make_pair("face_detection", task));
+               *out_handle = static_cast<mv_face_detection_h>(context);
+       } catch (const BaseException &e) {
+               delete task;
+               delete context;
+               return e.getError();
+       }
+
+       LOGD("face detection handle [%p] has been created", *out_handle);
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_destroy_open(mv_face_detection_h handle)
+{
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       auto context = static_cast<Context *>(handle);
+
+       for (auto &m : context->__tasks)
+               delete static_cast<FaceDetectionTask *>(m.second);
+
+       delete context;
+
+       LOGD("Object detection handle has been destroyed.");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_set_model_open(mv_face_detection_h handle, const char *model_name, const char *model_file,
+                                                                        const char *meta_file, const char *label_file)
+{
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->setModelInfo(model_file, meta_file, label_file, model_name);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_set_engine_open(mv_face_detection_h handle, const char *backend_type, const char *device_type)
+{
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->setEngineInfo(backend_type, device_type);
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_get_engine_count_open(mv_face_detection_h handle, unsigned int *engine_count)
+{
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->getNumberOfEngines(engine_count);
+               // TODO.
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_get_engine_type_open(mv_face_detection_h handle, const unsigned int engine_index,
+                                                                                  char **engine_type)
+{
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->getEngineType(engine_index, engine_type);
+               // TODO.
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_get_device_count_open(mv_face_detection_h handle, const char *engine_type,
+                                                                                       unsigned int *device_count)
+{
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->getNumberOfDevices(engine_type, device_count);
+               // TODO.
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_get_device_type_open(mv_face_detection_h handle, const char *engine_type,
+                                                                                  const unsigned int device_index, char **device_type)
+{
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->getDeviceType(engine_type, device_index, device_type);
+               // TODO.
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_configure_open(mv_face_detection_h handle)
+{
+       LOGD("ENTER");
+
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->configure();
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_prepare_open(mv_face_detection_h handle)
+{
+       LOGD("ENTER");
+
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               task->prepare();
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_inference_open(mv_face_detection_h handle, mv_source_h source)
+{
+       LOGD("ENTER");
+
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               ObjectDetectionInput input = { source };
+
+               task->setInput(input);
+               task->perform();
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_get_result_open(mv_face_detection_h handle, unsigned int *number_of_objects,
+                                                                         const unsigned int **indices, const float **confidences, const int **left,
+                                                                         const int **top, const int **right, const int **bottom)
+{
+       LOGD("ENTER");
+
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               ObjectDetectionResult &result = task->getOutput();
+               *number_of_objects = result.number_of_objects;
+               *indices = result.indices.data();
+               *confidences = result.confidences.data();
+               *left = result.left.data();
+               *top = result.top.data();
+               *right = result.right.data();
+               *bottom = result.bottom.data();
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_detection_get_label_open(mv_face_detection_h handle, const unsigned int index, const char **out_label)
+{
+       LOGD("ENTER");
+
+       lock_guard<mutex> lock(g_face_detection_mutex);
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto task = static_cast<FaceDetectionTask *>(context->__tasks.at("face_detection"));
+
+               ObjectDetectionResult &result = task->getOutput();
+
+               if (result.number_of_objects <= index)
+                       throw InvalidParameter("Invalid index range.");
+
+               *out_label = result.names[index].c_str();
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
\ No newline at end of file
index cda77a6..9098a77 100644 (file)
  * @brief This file contains Media Vision inference module.
  */
 
-int mv_object_detection_create(mv_object_detection_h *infer)
+int mv_object_detection_create(mv_object_detection_h *handle)
 {
        MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
-       MEDIA_VISION_NULL_ARG_CHECK(infer);
+       MEDIA_VISION_NULL_ARG_CHECK(handle);
 
        MEDIA_VISION_FUNCTION_ENTER();
 
-       int ret = mv_object_detection_create_open(infer);
+       int ret = mv_object_detection_create_open(handle);
 
        MEDIA_VISION_FUNCTION_LEAVE();
        return ret;
 }
 
-int mv_object_detection_destroy(mv_object_detection_h infer)
+int mv_object_detection_destroy(mv_object_detection_h handle)
 {
        MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
-       MEDIA_VISION_INSTANCE_CHECK(infer);
+       MEDIA_VISION_INSTANCE_CHECK(handle);
 
        MEDIA_VISION_FUNCTION_ENTER();
 
-       int ret = mv_object_detection_destroy_open(infer);
+       int ret = mv_object_detection_destroy_open(handle);
 
        MEDIA_VISION_FUNCTION_LEAVE();
        return ret;
@@ -154,53 +154,53 @@ int mv_object_detection_get_device_type(mv_object_detection_h handle, const char
        return ret;
 }
 
-int mv_object_detection_configure(mv_object_detection_h infer)
+int mv_object_detection_configure(mv_object_detection_h handle)
 {
        MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
-       MEDIA_VISION_INSTANCE_CHECK(infer);
+       MEDIA_VISION_INSTANCE_CHECK(handle);
 
        MEDIA_VISION_FUNCTION_ENTER();
 
-       int ret = mv_object_detection_configure_open(infer);
+       int ret = mv_object_detection_configure_open(handle);
 
        MEDIA_VISION_FUNCTION_LEAVE();
        return ret;
 }
 
-int mv_object_detection_prepare(mv_object_detection_h infer)
+int mv_object_detection_prepare(mv_object_detection_h handle)
 {
        MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
-       MEDIA_VISION_INSTANCE_CHECK(infer);
+       MEDIA_VISION_INSTANCE_CHECK(handle);
 
        MEDIA_VISION_FUNCTION_ENTER();
 
-       int ret = mv_object_detection_prepare_open(infer);
+       int ret = mv_object_detection_prepare_open(handle);
 
        MEDIA_VISION_FUNCTION_LEAVE();
        return ret;
 }
 
-int mv_object_detection_inference(mv_object_detection_h infer, mv_source_h source)
+int mv_object_detection_inference(mv_object_detection_h handle, mv_source_h source)
 {
        MEDIA_VISION_SUPPORT_CHECK(_mv_inference_image_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(handle);
        MEDIA_VISION_INSTANCE_CHECK(source);
-       MEDIA_VISION_INSTANCE_CHECK(infer);
 
        MEDIA_VISION_FUNCTION_ENTER();
 
-       int ret = mv_object_detection_inference_open(infer, source);
+       int ret = mv_object_detection_inference_open(handle, source);
 
        MEDIA_VISION_FUNCTION_LEAVE();
 
        return ret;
 }
 
-int mv_object_detection_get_result(mv_object_detection_h infer, unsigned int *number_of_objects,
+int mv_object_detection_get_result(mv_object_detection_h handle, unsigned int *number_of_objects,
                                                                   const unsigned int **indices, const float **confidences, const int **left,
                                                                   const int **top, const int **right, const int **bottom)
 {
        MEDIA_VISION_SUPPORT_CHECK(_mv_inference_image_check_system_info_feature_supported());
-       MEDIA_VISION_INSTANCE_CHECK(infer);
+       MEDIA_VISION_INSTANCE_CHECK(handle);
        MEDIA_VISION_INSTANCE_CHECK(number_of_objects);
        MEDIA_VISION_INSTANCE_CHECK(indices);
        MEDIA_VISION_INSTANCE_CHECK(confidences);
@@ -211,7 +211,7 @@ int mv_object_detection_get_result(mv_object_detection_h infer, unsigned int *nu
 
        MEDIA_VISION_FUNCTION_ENTER();
 
-       int ret = mv_object_detection_get_result_open(infer, number_of_objects, indices, confidences, left, top, right,
+       int ret = mv_object_detection_get_result_open(handle, number_of_objects, indices, confidences, left, top, right,
                                                                                                  bottom);
 
        MEDIA_VISION_FUNCTION_LEAVE();
@@ -219,15 +219,15 @@ int mv_object_detection_get_result(mv_object_detection_h infer, unsigned int *nu
        return ret;
 }
 
-int mv_object_detection_get_label(mv_object_detection_h infer, const unsigned int index, const char **out_label)
+int mv_object_detection_get_label(mv_object_detection_h handle, const unsigned int index, const char **label)
 {
        MEDIA_VISION_SUPPORT_CHECK(_mv_inference_image_check_system_info_feature_supported());
-       MEDIA_VISION_INSTANCE_CHECK(infer);
-       MEDIA_VISION_INSTANCE_CHECK(out_label);
+       MEDIA_VISION_INSTANCE_CHECK(handle);
+       MEDIA_VISION_INSTANCE_CHECK(label);
 
        MEDIA_VISION_FUNCTION_ENTER();
 
-       int ret = mv_object_detection_get_label_open(infer, index, out_label);
+       int ret = mv_object_detection_get_label_open(handle, index, label);
 
        MEDIA_VISION_FUNCTION_LEAVE();
 
index 5301b1c..ce3633c 100644 (file)
@@ -39,9 +39,9 @@ using ObjectDetectionTask = ITask<ObjectDetectionInput, ObjectDetectionResult>;
 
 static mutex g_object_detection_mutex;
 
-int mv_object_detection_create_open(mv_object_detection_h *out_handle)
+int mv_object_detection_create_open(mv_object_detection_h *handle)
 {
-       if (!out_handle) {
+       if (!handle) {
                LOGE("Handle can't be created because handle pointer is NULL");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
        }
@@ -53,14 +53,14 @@ int mv_object_detection_create_open(mv_object_detection_h *out_handle)
                context = new Context();
                task = new ObjectDetectionAdapter<ObjectDetectionInput, ObjectDetectionResult>();
                context->__tasks.insert(make_pair("object_detection", task));
-               *out_handle = static_cast<mv_object_detection_h>(context);
+               *handle = static_cast<mv_object_detection_h>(context);
        } catch (const BaseException &e) {
                delete task;
                delete context;
                return e.getError();
        }
 
-       LOGD("object detection handle [%p] has been created", *out_handle);
+       LOGD("object detection handle [%p] has been created", *handle);
 
        return MEDIA_VISION_ERROR_NONE;
 }
@@ -354,7 +354,7 @@ int mv_object_detection_get_result_open(mv_object_detection_h handle, unsigned i
        return MEDIA_VISION_ERROR_NONE;
 }
 
-int mv_object_detection_get_label_open(mv_object_detection_h handle, const unsigned int index, const char **out_label)
+int mv_object_detection_get_label_open(mv_object_detection_h handle, const unsigned int index, const char **label)
 {
        LOGD("ENTER");
 
@@ -374,7 +374,7 @@ int mv_object_detection_get_label_open(mv_object_detection_h handle, const unsig
                if (result.number_of_objects <= index)
                        throw InvalidParameter("Invalid index range.");
 
-               *out_label = result.names[index].c_str();
+               *label = result.names[index].c_str();
        } catch (const BaseException &e) {
                LOGE("%s", e.what());
                return e.getError();
index 97972c3..752439b 100644 (file)
@@ -174,9 +174,9 @@ void ObjectDetection::loadLabel()
        readFile.close();
 }
 
-void ObjectDetection::parseMetaFile()
+void ObjectDetection::parseMetaFile(const char *meta_file_name)
 {
-       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(MV_OBJECT_DETECTION_META_FILE_NAME));
+       _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(meta_file_name));
 
        int ret = _config->getIntegerAttribute(string(MV_OBJECT_DETECTION_BACKEND_TYPE), &_backendType);
        if (ret != MEDIA_VISION_ERROR_NONE)
index 44a7c68..adec879 100644 (file)
@@ -51,7 +51,6 @@ template<typename T, typename V> void ObjectDetectionAdapter<T, V>::create(int t
                _object_detection = make_unique<MobilenetV1Ssd>(task_type);
        else if (task_type == ObjectDetectionTaskType::MOBILENET_V2_SSD)
                _object_detection = make_unique<MobilenetV2Ssd>(task_type);
-
        // TODO.
 }
 
@@ -81,8 +80,10 @@ void ObjectDetectionAdapter<T, V>::setModelInfo(const char *model_file, const ch
        _meta_file = string(meta_file);
        _label_file = string(label_file);
 
-       if (_model_file.empty() && _meta_file.empty() && _label_file.empty())
-               throw InvalidParameter("Model info not invalid.");
+       if (_model_file.empty() && _meta_file.empty() && _label_file.empty()) {
+               LOGW("Given model info is invalid so default model info will be used instead.");
+               return;
+       }
 
        _object_detection->setUserModel(_model_file, _meta_file, _label_file);
 }
@@ -95,7 +96,7 @@ void ObjectDetectionAdapter<T, V>::setEngineInfo(const char *engine_type, const
 
 template<typename T, typename V> void ObjectDetectionAdapter<T, V>::configure()
 {
-       _object_detection->parseMetaFile();
+       _object_detection->parseMetaFile("object_detection.json");
        _object_detection->configure();
 }
 
index b1ef58c..1703ea0 100644 (file)
@@ -434,6 +434,7 @@ find . -name '*.gcno' -not -path "./test/*" -exec cp --parents '{}' "$gcno_obj_d
 %endif
 %if "%{enable_ml_object_detection}" == "1"
 %{_datadir}/%{name}/object_detection.json
+%{_datadir}/%{name}/face_detection.json
 %{_libdir}/libmv_object_detection.so
 %endif
 %if "%{enable_ml_object_detection_3d}" == "1"
index 6607883..9fb0b14 100644 (file)
 
 #include "ImageHelper.h"
 #include "mv_object_detection_internal.h"
+#include "mv_face_detection_internal.h"
 
-#define IMAGE_PATH MV_CONFIG_PATH "res/inference/images/dog2.jpg"
+#define IMG_DOG MV_CONFIG_PATH "res/inference/images/dog2.jpg"
+#define IMG_FACE MV_CONFIG_PATH "res/inference/images/faceDetection.jpg"
 
 using namespace testing;
 using namespace std;
@@ -35,6 +37,7 @@ struct model_info {
        string model_file;
        string meta_file;
        string label_file;
+       string anster;
 };
 
 TEST(ObjectDetectionTest, GettingAvailableInferenceEnginesInfoShouldBeOk)
@@ -83,25 +86,69 @@ TEST(ObjectDetectionTest, GettingAvailableInferenceEnginesInfoShouldBeOk)
        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 }
 
+TEST(FaceDetectionTest, GettingAvailableInferenceEnginesInfoShouldBeOk)
+{
+       mv_object_detection_h handle;
+
+       int ret = mv_face_detection_create(&handle);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+       unsigned int engine_count = 0;
+
+       ret = mv_face_detection_get_engine_count(handle, &engine_count);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+       cout << "Engine count = " << engine_count << endl;
+       ASSERT_GE(engine_count, 1);
+
+       for (unsigned int engine_idx = 0; engine_idx < engine_count; ++engine_idx) {
+               char *engine_type = nullptr;
+
+               ret = mv_face_detection_get_engine_type(handle, engine_idx, &engine_type);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               cout << "Engine type : " << engine_type << endl;
+
+               unsigned int device_count = 0;
+
+               ret = mv_face_detection_get_device_count(handle, engine_type, &device_count);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               cout << "Device count = " << device_count << endl;
+
+               ASSERT_GE(engine_count, 1);
+
+               for (unsigned int device_idx = 0; device_idx < device_count; ++device_idx) {
+                       char *device_type = nullptr;
+
+                       ret = mv_face_detection_get_device_type(handle, engine_type, device_idx, &device_type);
+                       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+                       cout << "Device type : " << device_type << endl;
+               }
+       }
+
+       ret = mv_face_detection_destroy(handle);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+}
+
 TEST(ObjectDetectionTest, InferenceShouldBeOk)
 {
        mv_object_detection_h handle;
        vector<model_info> test_models {
-               { "", "", "", "" }, // If empty then default model will be used.
+               { "", "", "", "", "DOG" }, // If empty then default model will be used.
                { "mobilenet_v1_ssd", "od_mobilenet_v1_ssd_postop_300x300.tflite", "od_mobilenet_v1_ssd_postop_300x300.json",
-                 "od_mobilenet_v1_ssd_postop_label.txt" },
+                 "od_mobilenet_v1_ssd_postop_label.txt", "DOG" },
                { "mobilenet_v2_ssd", "od_mobilenet_v2_ssd_320x320.tflite", "od_mobilenet_v2_ssd_320x320.json",
-                 "od_mobilenet_v2_ssd_label.txt" }
+                 "od_mobilenet_v2_ssd_label.txt", "DOG" }
                // TODO.
        };
 
-       const string image_path = IMAGE_PATH;
        mv_source_h mv_source = NULL;
-
        int ret = mv_create_source(&mv_source);
        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
-       ret = ImageHelper::loadImageToSource(image_path.c_str(), mv_source);
+       ret = ImageHelper::loadImageToSource(IMG_DOG, mv_source);
        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 
        for (auto model : test_models) {
@@ -148,7 +195,7 @@ TEST(ObjectDetectionTest, InferenceShouldBeOk)
 
                        transform(label_str.begin(), label_str.end(), label_str.begin(), ::toupper);
 
-                       ASSERT_TRUE(label_str == string("DOG"));
+                       ASSERT_TRUE(label_str == model.anster);
                }
 
                ret = mv_object_detection_destroy(handle);
@@ -158,3 +205,75 @@ TEST(ObjectDetectionTest, InferenceShouldBeOk)
        ret = mv_destroy_source(mv_source);
        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
 }
+
+TEST(FaceDetectionTest, InferenceShouldBeOk)
+{
+       mv_object_detection_h handle;
+       vector<model_info> test_models {
+               { "", "", "", "", "FACE" }, // If empty then default model will be used.
+               { "fd_mobilenet_v1_ssd", "fd_mobilenet_v1_ssd_postop_300x300.tflite", "fd_mobilenet_v1_ssd_postop_300x300.json",
+                 "fd_mobilenet_v1_ssd_postop_label.txt", "FACE" }
+               // TODO.
+       };
+
+       mv_source_h mv_source = NULL;
+       int ret = mv_create_source(&mv_source);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+       ret = ImageHelper::loadImageToSource(IMG_FACE, mv_source);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+       for (auto model : test_models) {
+               cout << "model name : " << model.model_file << endl;
+
+               ret = mv_face_detection_create(&handle);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               mv_face_detection_set_model(handle, model.model_name.c_str(), model.model_file.c_str(), model.meta_file.c_str(),
+                                                                       model.label_file.c_str());
+               mv_face_detection_set_engine(handle, "tflite", "cpu");
+
+               ret = mv_face_detection_configure(handle);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               ret = mv_face_detection_prepare(handle);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+               ret = mv_face_detection_inference(handle, mv_source);
+               ASSERT_EQ(ret, 0);
+
+               unsigned int number_of_objects;
+               const int *left, *top, *right, *bottom;
+               const unsigned int *indices;
+               const float *confidences;
+
+               ret = mv_face_detection_get_result(handle, &number_of_objects, &indices, &confidences, &left, &top, &right,
+                                                                                  &bottom);
+               ASSERT_EQ(ret, 0);
+
+               for (unsigned int idx = 0; idx < number_of_objects; ++idx) {
+                       cout << "index = " << indices[idx] << " probability = " << confidences[idx] << " " << left[idx] << " x "
+                                << top[idx] << " ~ " << right[idx] << " x " << bottom[idx] << endl;
+               }
+
+               for (unsigned int idx = 0; idx < number_of_objects; ++idx) {
+                       const char *label;
+
+                       ret = mv_face_detection_get_label(handle, indices[idx], &label);
+                       ASSERT_EQ(ret, 0);
+                       cout << "index = " << indices[idx] << " label = " << label << endl;
+
+                       string label_str(label);
+
+                       transform(label_str.begin(), label_str.end(), label_str.begin(), ::toupper);
+
+                       ASSERT_TRUE(label_str == model.anster);
+               }
+
+               ret = mv_face_detection_destroy(handle);
+               ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+       }
+
+       ret = mv_destroy_source(mv_source);
+       ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+}