"Name of the library will be built for tracker module (without extension).")
set(MV_OBJECT_DETECTION_LIB_NAME "mv_object_detection" CACHE STRING
"Name of the library will be built for object detection module (without extension).")
+set(MV_FACE_IRIS_LIB_NAME "mv_face_iris" CACHE STRING
+ "Name of the library will be built for face iris detection module (without extension).")
include(FindPkgConfig)
include(GNUInstallDirs)
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_3d.json DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
+set(PC_NAME ${fw_name}-face-iris)
+set(PC_LDFLAGS "-l${MV_FACE_IRIS_LIB_NAME} -l${MV_COMMON_LIB_NAME}")
+configure_file(
+ ${fw_name}.pc.in
+ ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}-face-iris.pc
+ @ONLY
+)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}-face-iris.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mv_machine_learning/face_iris/meta/face_iris.json DESTINATION ${CMAKE_INSTALL_DATADIR}/${fw_name})
+
if (${ENABLE_ML_FACE_RECOGNITION})
set(PC_NAME ${fw_name}-training)
set(PC_LDFLAGS "-l${MV_TRAINING_LIB_NAME} -l${MV_COMMON_LIB_NAME}")
--- /dev/null
+/*
+ * 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_FACE_IRIS_INTERNAL_H__
+#define __TIZEN_MEDIAVISION_FACE_IRIS_INTERNAL_H__
+
+#include <mv_common.h>
+#include <mv_face_iris_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int mv_face_iris_create(mv_face_iris_h *infer);
+
+int mv_face_iris_destroy(mv_face_iris_h infer);
+
+int mv_face_iris_configure(mv_face_iris_h infer);
+
+int mv_face_iris_prepare(mv_face_iris_h infer);
+
+int mv_face_iris_inference(mv_face_iris_h infer, mv_source_h source);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_IRIS_INTERNAL_H__ */
--- /dev/null
+/*
+ * 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_FACE_IRIS_TYPE_H__
+#define __TIZEN_MEDIAVISION_FACE_IRIS_TYPE_H__
+
+#include <mv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef void *mv_face_iris_h;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_IRIS_TYPE_H__ */
add_subdirectory(inference)
add_subdirectory(object_detection)
+add_subdirectory(face_iris)
if (${ENABLE_ML_FACE_RECOGNITION})
message("Enabled machine learning face recognition feature.")
--- /dev/null
+project(${MV_FACE_IRIS_LIB_NAME})
+cmake_minimum_required(VERSION 2.6...3.13)
+
+pkg_check_modules(${PROJECT_NAME}_DEP REQUIRED inference-engine-interface-common iniparser json-glib-1.0)
+file(GLOB MV_FACE_IRIS_SOURCE_LIST "${PROJECT_SOURCE_DIR}/src/*.c" "${PROJECT_SOURCE_DIR}/src/*.cpp" "${PROJECT_SOURCE_DIR}/../meta/src/*.cpp")
+
+find_package(OpenCV REQUIRED dnn imgproc)
+if(NOT OpenCV_FOUND)
+ message(SEND_ERROR "OpenCV NOT FOUND")
+ return()
+endif()
+
+if(FORCED_STATIC_BUILD)
+ add_library(${PROJECT_NAME} STATIC ${MV_FACE_IRIS_SOURCE_LIST})
+else()
+ add_library(${PROJECT_NAME} SHARED ${MV_FACE_IRIS_SOURCE_LIST})
+endif()
+
+target_link_libraries(${PROJECT_NAME} ${MV_COMMON_LIB_NAME} ${OpenCV_LIBS} ${${PROJECT_NAME}_DEP_LIBRARIES} mv_inference)
+target_include_directories(${PROJECT_NAME} PRIVATE include ../inference/include ../common/include ../meta/include)
+install(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACE_DETECTION_FRONT_H__
+#define __FACE_DETECTION_FRONT_H__
+
+#include <memory>
+#include <list>
+#include <mv_common.h>
+#include "mv_private.h"
+
+#include "face_iris.h"
+#include <mv_inference_type.h>
+#include "EngineConfig.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FaceDetectionFront : public FaceIris
+{
+private:
+ face_detection_result_s _result;
+ std::vector<fvec2> _anchors;
+ inference_engine_tensor_buffer *_bboxes_tensor;
+ inference_engine_tensor_buffer *_scores_tensor;
+
+ float *GetBboxPtr(unsigned int anchor_idx);
+ unsigned int CreateBlazefaceAnchors(unsigned int input_w, unsigned int input_h);
+
+ void RotVec(fvec2 &vec, float rotation);
+ void ComputeFaceRect(face_t &face);
+ float NormalizeRadians(float angle);
+ void ComputeRotation(face_t &face);
+ void PackFaceResult(face_detection_result_s *facedet_result, std::list<face_t> &face_list);
+ float CalcIntersectionOverUnion(face_t &face0, face_t &face1);
+ void NonMaxSuppression(std::list<face_t> &face_list, std::list<face_t> &face_sel_list,
+ float iou_thresh);
+ void DecodeBoundingBox(std::list<face_t> &face_list, float score_thresh,
+ unsigned int input_img_w, unsigned int input_img_h, const float *scores_ptr);
+
+public:
+ FaceDetectionFront();
+ ~FaceDetectionFront();
+ void parseMetaFile() override;
+ virtual void after_prepare() override;
+ face_detection_result_s &getResult() override;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACE_DETECTION_FRONT_ADAPTER_H__
+#define __FACE_DETECTION_FRONT_ADAPTER_H__
+
+#include <dlog.h>
+
+#include "EngineConfig.h"
+#include "itask.h"
+#include "face_detection_front.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+
+template<typename T, typename V> class FaceDetectionFrontAdapter : public mediavision::common::ITask<T, V>
+{
+private:
+ std::unique_ptr<FaceIris> _face_detection;
+ T _source;
+
+public:
+ FaceDetectionFrontAdapter();
+ ~FaceDetectionFrontAdapter();
+
+ void create(int type) override;
+
+ void configure() 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
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACE_IRIS_PARSER_H__
+#define __FACE_IRIS_PARSER_H__
+
+#include "MetaParser.h"
+#include "PostprocessParser.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FaceDetectionParser : public MetaParser
+{
+private:
+ PostprocessParser _postprocessParser;
+
+protected:
+ void parsePostprocess(std::shared_ptr<MetaInfo> meta_info, JsonObject *in_obj) override;
+
+public:
+ FaceDetectionParser();
+ ~FaceDetectionParser();
+};
+
+}
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __OBJECT_DETECTION_H__
+#define __OBJECT_DETECTION_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+#include "mv_private.h"
+
+#include "EngineConfig.h"
+#include "inference_engine_common_impl.h"
+#include "Inference.h"
+#include "face_iris_type.h"
+#include "face_detection_parser.h"
+#include "Preprocess.h"
+
+namespace mediavision
+{
+namespace machine_learning
+{
+class FaceIris
+{
+protected:
+ std::unique_ptr<mediavision::inference::Inference> _inference;
+
+ std::unique_ptr<MediaVision::Common::EngineConfig> _config;
+ std::unique_ptr<MetaParser> _parser;
+ Preprocess _preprocess;
+ std::string _modelFilePath;
+ std::string _modelMetaFilePath;
+ int _backendType;
+ int _targetDeviceType;
+
+public:
+ FaceIris();
+ virtual ~FaceIris() = default;
+ virtual void parseMetaFile() = 0;
+ void configure();
+ void prepare();
+ virtual void after_prepare() { }
+ void preprocess(mv_source_h &mv_src);
+ void inference(mv_source_h source);
+ virtual face_detection_result_s &getResult() = 0;
+};
+
+} // machine_learning
+} // mediavision
+
+#endif
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FACE_IRIS_TYPE_H__
+#define __FACE_IRIS_TYPE_H__
+
+#include <mv_common.h>
+#include <mv_inference_type.h>
+
+#define MAX_FACE_NUM 10
+#define FACE_KEY_NUM 468
+
+namespace mediavision
+{
+namespace machine_learning
+{
+
+struct face_detection_input_s {
+ mv_source_h inference_src;
+};
+
+struct face_landmark_input_s {
+};
+
+struct face_iris_input_s {
+};
+
+enum class face_iris_task_type_e {
+ FACE_DETECTION_TASK = 1,
+ FACE_LANDMARK_DETECTION_TASK,
+ FACE_IRIS_DETECTION_TASK
+ // TODO
+};
+
+enum face_key_id {
+ kRightEye = 0, // 0
+ kLeftEye, // 1
+ kNose, // 2
+ kMouth, // 3
+ kRightEar, // 4
+ kLeftEar, // 5
+ kFaceKeyNum
+};
+
+struct fvec2 {
+ float x, y;
+};
+
+struct fvec3 {
+ float x, y, z;
+};
+
+struct face_t {
+ float score;
+ fvec2 topleft;
+ fvec2 btmright;
+ fvec2 keys[kFaceKeyNum];
+
+ float rotation;
+ float face_cx;
+ float face_cy;
+ float face_w;
+ float face_h;
+ fvec2 face_pos[4];
+};
+
+struct face_detection_result_s {
+ int num;
+ face_t faces[MAX_FACE_NUM];
+};
+
+struct rect_t {
+ fvec2 topleft;
+ fvec2 btmright;
+};
+
+struct eye_region_t {
+ float rotation;
+ fvec2 center;
+ fvec2 size;
+};
+
+struct face_landmark_result_s {
+ float score;
+ fvec3 joint[FACE_KEY_NUM];
+ eye_region_t eye_rgn[2];
+ fvec2 eye_pos[2][4];
+};
+
+struct face_iris_result_s {
+ fvec3 eye_landmark[71];
+ fvec3 iris_landmark[5];
+};
+
+}
+}
+
+#endif
\ No newline at end of file
--- /dev/null
+/**
+ * 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 __MEDIA_VISION_FACE_IRIS_CONFIG_H__
+#define __MEDIA_VISION_FACE_IRIS_CONFIG_H__
+
+#define MV_FACE_DETECTION_MODEL_FILE_PATH "DETECTION_MODEL_FILE_PATH"
+#define MV_FACE_LANDMARK_MODEL_FILE_PATH "LANDMARK_MODEL_FILE_PATH"
+#define MV_FACE_IRIS_MODEL_FILE_PATH "IRIS_MODEL_FILE_PATH"
+
+#define MV_FACE_DETECTION_MODEL_META_PATH "DETECTION_MODEL_META_FILE_PATH"
+#define MV_FACE_LANDMARK_MODEL_META_PATH "LANDMARK_MODEL_META_FILE_PATH"
+#define MV_FACE_IRIS_MODEL_META_PATH "IRIS_MODEL_META_FILE_PATH"
+
+#define MV_FACE_IRIS_BACKEND_TYPE "BACKEND_TYPE"
+
+#define MV_FACE_IRIS_TARGET_DEVICE_TYPE "TARGET_DEVICE_TYPE"
+
+#define MV_FACE_IRIS_META_FILE_NAME "face_iris.json"
+
+#endif
--- /dev/null
+/**
+ * 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 __MEDIA_VISION_FACE_IRIS_OPEN_H__
+#define __MEDIA_VISION_FACE_IRIS_OPEN_H__
+
+#include <mv_common.h>
+#include <mv_private.h>
+#include <mv_face_iris_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int mv_face_iris_create_open(mv_face_iris_h *out_handle);
+
+int mv_face_iris_destroy_open(mv_face_iris_h handle);
+
+int mv_face_iris_configure_open(mv_face_iris_h handle);
+
+int mv_face_iris_prepare_open(mv_face_iris_h handle);
+
+int mv_face_iris_inference_open(mv_face_iris_h handle, mv_source_h source);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MEDIA_VISION_INFERENCE_OPEN_H__ */
--- /dev/null
+{
+ "attributes":
+ [
+ {
+ "name" : "DETECTION_MODEL_FILE_PATH",
+ "type" : "string",
+ "value" : "/home/owner/media/res/face_iris/tflite/face_detection_front.tflite"
+ },
+ {
+ "name" : "LANDMARK_MODEL_FILE_PATH",
+ "type" : "string",
+ "value" : "/home/owner/media/res/face_iris/tflite/face_landmark.tflite"
+ },
+ {
+ "name" : "IRIS_MODEL_FILE_PATH",
+ "type" : "string",
+ "value" : "/home/owner/media/res/face_iris/tflite/face_iris.tflite"
+ },
+ {
+ "name" : "DETECTION_MODEL_META_FILE_PATH",
+ "type" : "string",
+ "value" : "/home/owner/media/res/face_iris/tflite/face_detection_front.json"
+ },
+ {
+ "name" : "LANDMARK_MODEL_META_FILE_PATH",
+ "type" : "string",
+ "value" : "/home/owner/media/res/face_iris/tflite/face_landmark.json"
+ },
+ {
+ "name" : "IRIS_MODEL_META_FILE_PATH",
+ "type" : "string",
+ "value" : "/home/owner/media/res/face_iris/tflite/face_iris.json"
+ },
+ {
+ "name" : "BACKEND_TYPE",
+ "type" : "integer",
+ "value" : 1
+ },
+ {
+ "name" : "TARGET_DEVICE_TYPE",
+ "type" : "integer",
+ "value" : 1
+ }
+ ]
+}
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <map>
+#include <algorithm>
+#include <iostream>
+
+#include "machine_learning_exception.h"
+#include "face_detection_front.h"
+#include "mv_face_iris_config.h"
+#include "Postprocess.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace MediaVision::Common;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+FaceDetectionFront::FaceDetectionFront() : _result()
+{
+ _inference = make_unique<Inference>();
+ _parser = make_unique<FaceDetectionParser>();
+}
+
+FaceDetectionFront::~FaceDetectionFront()
+{}
+
+static bool IsJsonFile(const string &fileName)
+{
+ return (!fileName.substr(fileName.find_last_of(".") + 1).compare("json"));
+}
+
+void FaceDetectionFront::parseMetaFile()
+{
+ _config = make_unique<EngineConfig>(string(MV_CONFIG_PATH) + string(MV_FACE_IRIS_META_FILE_NAME));
+
+ int ret = _config->getIntegerAttribute(string(MV_FACE_IRIS_BACKEND_TYPE), &_backendType);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to get backend engine type.");
+
+ ret = _config->getIntegerAttribute(string(MV_FACE_IRIS_TARGET_DEVICE_TYPE), &_targetDeviceType);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to get target device type.");
+
+ ret = _config->getStringAttribute(MV_FACE_DETECTION_MODEL_FILE_PATH, &_modelFilePath);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to get model file path");
+
+ ret = _config->getStringAttribute(MV_FACE_DETECTION_MODEL_META_PATH, &_modelMetaFilePath);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to get model meta file path");
+
+ if (_modelMetaFilePath.empty())
+ throw InvalidOperation("Model meta file doesn't exist.");
+
+ if (!IsJsonFile(_modelMetaFilePath))
+ throw InvalidOperation("Model meta file should be json");
+
+ _parser->load(_modelMetaFilePath);
+}
+
+void FaceDetectionFront::after_prepare()
+{
+ CreateBlazefaceAnchors(_inference->getInputWidth(), _inference->getInputHeight());
+}
+
+float *FaceDetectionFront::GetBboxPtr(unsigned int anchor_idx)
+{
+ int idx = 16 * anchor_idx;
+ float *bboxes_ptr = reinterpret_cast<float *>(_bboxes_tensor->buffer);
+
+ return &bboxes_ptr[idx];
+}
+
+unsigned int FaceDetectionFront::CreateBlazefaceAnchors(unsigned int input_w, unsigned int input_h)
+{
+ /* ANCHORS_CONFIG */
+ int strides[2] = {8, 16};
+ int anchors[2] = {2, 6};
+ int numtotal = 0;
+
+ for (int idx = 0; idx < 2; idx++) {
+ int stride = strides[idx];
+ int gridCols = (input_w + stride -1) / stride;
+ int gridRows = (input_h + stride -1) / stride;
+ int anchorNum = anchors[idx];
+ fvec2 anchor;
+
+ for (int gridY = 0; gridY < gridRows; gridY++) {
+ anchor.y = stride * (gridY + 0.5f);
+
+ for (int gridX = 0; gridX < gridCols; gridX++) {
+ anchor.x = stride * (gridX + 0.5f);
+
+ for (int n = 0; n < anchorNum; n++) {
+ _anchors.push_back(anchor);
+ numtotal++;
+ }
+ }
+ }
+ }
+
+ return numtotal;
+}
+
+static bool SortRightMajor(face_t &v1, face_t &v2)
+{
+ if (v1.keys[kRightEye].x > v2.keys[kRightEye].x)
+ return true;
+ else
+ return false;
+}
+
+void FaceDetectionFront::RotVec(fvec2 &vec, float rotation)
+{
+ float sx = vec.x;
+ float sy = vec.y;
+ vec.x = sx * std::cos(rotation) - sy * std::sin(rotation);
+ vec.y = sx * std::sin(rotation) + sy * std::cos(rotation);
+}
+
+void FaceDetectionFront::ComputeFaceRect(face_t &face)
+{
+ float width = face.btmright.x - face.topleft.x;
+ float height = face.btmright.y - face.topleft.y;
+ float palm_cx = face.topleft.x + width * 0.5f;
+ float palm_cy = face.topleft.y + height * 0.5f;
+ float face_cx;
+ float face_cy;
+ float rotation = face.rotation;
+ float shift_x = 0;// 0.0f;
+ float shift_y = 0;//-0.5f;
+
+ if (rotation == 0.0f) {
+ face_cx = palm_cx + (width * shift_x);
+ face_cy = palm_cy + (height * shift_y);
+ } else {
+ float dx = (width * shift_x) * std::cos(rotation) -
+ (height * shift_y) * std::sin(rotation);
+ float dy = (width * shift_x) * std::sin(rotation) +
+ (height * shift_y) * std::cos(rotation);
+ face_cx = palm_cx + dx;
+ face_cy = palm_cy + dy;
+ }
+
+ float long_side = std::max(width, height);
+ width = long_side;
+ height = long_side;
+ float face_w = width * 1.5f;
+ float face_h = height * 1.5f;
+
+ face.face_cx = face_cx;
+ face.face_cy = face_cy;
+ face.face_w = face_w;
+ face.face_h = face_h;
+
+ float dx = face_w * 0.5f;
+ float dy = face_h * 0.5f;
+
+ face.face_pos[0].x = - dx; face.face_pos[0].y = - dy;
+ face.face_pos[1].x = + dx; face.face_pos[1].y = - dy;
+ face.face_pos[2].x = + dx; face.face_pos[2].y = + dy;
+ face.face_pos[3].x = - dx; face.face_pos[3].y = + dy;
+
+ for (int i = 0; i < 4; i ++) {
+ RotVec(face.face_pos[i], rotation);
+ face.face_pos[i].x += face_cx;
+ face.face_pos[i].y += face_cy;
+ }
+}
+
+float FaceDetectionFront::NormalizeRadians(float angle)
+{
+ return angle - 2 * M_PI * std::floor((angle - (-M_PI)) / (2 * M_PI));
+}
+
+void FaceDetectionFront::ComputeRotation(face_t &face)
+{
+ float x0 = face.keys[kRightEye].x;
+ float y0 = face.keys[kRightEye].y;
+ float x1 = face.keys[kLeftEye].x;
+ float y1 = face.keys[kLeftEye].y;
+
+ float target_angle = 0;//M_PI * 0.5f;
+ float rotation = target_angle - std::atan2(-(y1 - y0), x1 - x0);
+
+ face.rotation = NormalizeRadians(rotation);
+}
+
+void FaceDetectionFront::PackFaceResult(face_detection_result_s *facedet_result, list<face_t> &face_list)
+{
+ face_list.sort(SortRightMajor);
+
+ int num_faces = 0;
+ for (auto itr = face_list.begin(); itr != face_list.end(); itr ++) {
+ face_t face = *itr;
+
+ ComputeRotation(face);
+ ComputeFaceRect(face);
+
+ memcpy (&facedet_result->faces[num_faces], &face, sizeof (face));
+ num_faces ++;
+ facedet_result->num = num_faces;
+
+ if (num_faces >= MAX_FACE_NUM)
+ break;
+ }
+}
+
+float FaceDetectionFront::CalcIntersectionOverUnion(face_t &face0, face_t &face1)
+{
+ float sx0 = face0.topleft.x;
+ float sy0 = face0.topleft.y;
+ float ex0 = face0.btmright.x;
+ float ey0 = face0.btmright.y;
+ float sx1 = face1.topleft.x;
+ float sy1 = face1.topleft.y;
+ float ex1 = face1.btmright.x;
+ float ey1 = face1.btmright.y;
+
+ float xmin0 = std::min (sx0, ex0);
+ float ymin0 = std::min (sy0, ey0);
+ float xmax0 = std::max (sx0, ex0);
+ float ymax0 = std::max (sy0, ey0);
+ float xmin1 = std::min (sx1, ex1);
+ float ymin1 = std::min (sy1, ey1);
+ float xmax1 = std::max (sx1, ex1);
+ float ymax1 = std::max (sy1, ey1);
+
+ float area0 = (ymax0 - ymin0) * (xmax0 - xmin0);
+ float area1 = (ymax1 - ymin1) * (xmax1 - xmin1);
+ if (area0 <= 0 || area1 <= 0)
+ return 0.0f;
+
+ float intersect_xmin = std::max (xmin0, xmin1);
+ float intersect_ymin = std::max (ymin0, ymin1);
+ float intersect_xmax = std::min (xmax0, xmax1);
+ float intersect_ymax = std::min (ymax0, ymax1);
+
+ float intersect_area = std::max (intersect_ymax - intersect_ymin, 0.0f) *
+ std::max (intersect_xmax - intersect_xmin, 0.0f);
+
+ return intersect_area / (area0 + area1 - intersect_area);
+}
+
+static bool Compare(face_t &v1, face_t &v2)
+{
+ if (v1.score > v2.score)
+ return true;
+ else
+ return false;
+}
+
+void FaceDetectionFront::NonMaxSuppression(list<face_t> &face_list, list<face_t> &face_sel_list,
+ float iou_thresh)
+{
+ face_list.sort(Compare);
+
+ for (auto itr = face_list.begin(); itr != face_list.end(); itr ++) {
+ face_t face_candidate = *itr;
+
+ int ignore_candidate = false;
+ for (auto itr_sel = face_sel_list.rbegin(); itr_sel != face_sel_list.rend(); itr_sel ++) {
+ face_t face_sel = *itr_sel;
+
+ float iou = CalcIntersectionOverUnion(face_candidate, face_sel);
+ if (iou >= iou_thresh) {
+ ignore_candidate = true;
+ break;
+ }
+ }
+
+ if (!ignore_candidate) {
+ face_sel_list.push_back(face_candidate);
+ if (face_sel_list.size() >= MAX_FACE_NUM)
+ break;
+ }
+ }
+}
+
+void FaceDetectionFront::DecodeBoundingBox(list<face_t> &face_list, float score_thresh, unsigned int input_img_w,
+ unsigned int input_img_h, const float *scores_ptr)
+{
+ face_t face_item;
+ int idx = 0;
+
+ if (_anchors.empty())
+ throw InvalidOperation("anchors is empty.");
+
+ for (auto itr = _anchors.begin(); itr != _anchors.end(); idx++, itr++)
+ {
+ fvec2 anchor = *itr;
+ float score0 = scores_ptr[idx];
+ float score = 1.0f / (1.0f + exp(-score0));
+
+ if (score > score_thresh)
+ {
+ float *p = GetBboxPtr(idx);
+
+ /* boundary box */
+ float sx = p[0];
+ float sy = p[1];
+ float w = p[2];
+ float h = p[3];
+
+ float cx = sx + anchor.x;
+ float cy = sy + anchor.y;
+
+ cx /= (float)input_img_w;
+ cy /= (float)input_img_h;
+ w /= (float)input_img_w;
+ h /= (float)input_img_h;
+
+ fvec2 topleft, btmright;
+ topleft.x = cx - w * 0.5f;
+ topleft.y = cy - h * 0.5f;
+ btmright.x = cx + w * 0.5f;
+ btmright.y = cy + h * 0.5f;
+
+ face_item.score = score;
+ face_item.topleft = topleft;
+ face_item.btmright = btmright;
+
+ /* landmark positions (6 keys) */
+ for (int j = 0; j < kFaceKeyNum; j ++)
+ {
+ float lx = p[4 + (2 * j) + 0];
+ float ly = p[4 + (2 * j) + 1];
+ lx += anchor.x;
+ ly += anchor.y;
+ lx /= (float)input_img_w;
+ ly /= (float)input_img_h;
+
+ face_item.keys[j].x = lx;
+ face_item.keys[j].y = ly;
+ }
+
+ face_list.push_back(face_item);
+ }
+ }
+}
+
+face_detection_result_s &FaceDetectionFront::getResult()
+{
+ TensorBuffer &tensor_buffer_obj = _inference->GetOutputTensorBuffer();
+ IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+
+ for (IETensorBuffer::iterator it = ie_tensor_buffer.begin(); it != ie_tensor_buffer.end(); it++) {
+ if (it->first.compare("regressors") == 0) {
+ _bboxes_tensor = tensor_buffer_obj.getTensorBuffer(it->first);
+ if (!_bboxes_tensor)
+ throw InvalidOperation("Fail to get regressors tensor buffer.");
+ }
+
+ if (it->first.compare("classificators") == 0) {
+ _scores_tensor = tensor_buffer_obj.getTensorBuffer(it->first);
+ if (!_scores_tensor)
+ throw InvalidOperation("Fail to get classificators tensor buffer.");
+ }
+ }
+
+ if (!_bboxes_tensor || !_scores_tensor)
+ throw InvalidOperation("Invalid output tensor.");
+
+ list<face_t> face_list;
+ float score_thresh = 0.75f;
+ unsigned int input_img_w = _inference->getInputWidth();
+ unsigned int input_img_h = _inference->getInputHeight();
+
+ DecodeBoundingBox(face_list, score_thresh, input_img_w, input_img_h,
+ reinterpret_cast<float *>(_scores_tensor->buffer));
+
+ float iou_thresh = 0.3f;
+ list<face_t> face_nms_list;
+
+ NonMaxSuppression(face_list, face_nms_list,iou_thresh);
+
+ face_detection_result_s facedet_result;
+
+ PackFaceResult(&facedet_result, face_nms_list);
+ // TODO.
+
+ for (unsigned int idx = 0; idx < facedet_result.num; ++idx) {
+ face_t &face = facedet_result.faces[idx];
+
+ cout << "score = " << face.score << endl;
+ cout << "topleft = " << face.topleft.x << " : " << face.topleft.y << endl;
+ cout << "btmright = " << face.btmright.x << " : " << face.btmright.y << endl;
+ cout << "face_cx = " << face.face_cx << " face_cy = " << face.face_cy << endl;
+ cout << "face_w = " << face.face_w << " face_h = " << face.face_h << endl;
+ }
+
+ return _result;
+}
+
+}
+}
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "machine_learning_exception.h"
+#include "face_detection_front_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> FaceDetectionFrontAdapter<T, V>::FaceDetectionFrontAdapter() : _source()
+{}
+
+template<typename T, typename V> FaceDetectionFrontAdapter<T, V>::~FaceDetectionFrontAdapter()
+{}
+
+template<typename T, typename V> void FaceDetectionFrontAdapter<T, V>::create(int type)
+{
+ switch (type) {
+ case static_cast<int>(face_iris_task_type_e::FACE_DETECTION_TASK):
+ _face_detection = make_unique<FaceDetectionFront>();
+ break;
+ default:
+ throw InvalidParameter("Invalid face detection task type.");
+ }
+}
+
+template<typename T, typename V> void FaceDetectionFrontAdapter<T, V>::configure()
+{
+ try {
+ _face_detection->parseMetaFile();
+ _face_detection->configure();
+ } catch (const BaseException &e) {
+ throw e;
+ }
+}
+
+template<typename T, typename V> void FaceDetectionFrontAdapter<T, V>::prepare()
+{
+ try {
+ _face_detection->prepare();
+ _face_detection->after_prepare();
+ } catch (const BaseException &e) {
+ throw e;
+ }
+}
+
+template<typename T, typename V> void FaceDetectionFrontAdapter<T, V>::setInput(T &t)
+{
+ _source = t;
+}
+
+template<typename T, typename V> void FaceDetectionFrontAdapter<T, V>::perform()
+{
+ try {
+ _face_detection->preprocess(_source.inference_src);
+ _face_detection->inference(_source.inference_src);
+ _face_detection->getResult(); //
+ } catch (const BaseException &e) {
+ throw e;
+ }
+}
+
+template<typename T, typename V> V &FaceDetectionFrontAdapter<T, V>::getOutput()
+{
+ return _face_detection->getResult();
+}
+
+template class FaceDetectionFrontAdapter<face_detection_input_s, face_detection_result_s>;
+}
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include "machine_learning_exception.h"
+#include "face_detection_parser.h"
+
+using namespace std;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+FaceDetectionParser::FaceDetectionParser()
+{
+ LOGI("ENTER");
+ LOGI("LEAVE");
+}
+
+FaceDetectionParser::~FaceDetectionParser()
+{}
+
+void FaceDetectionParser::parsePostprocess(shared_ptr<MetaInfo> meta_info, JsonObject *in_obj)
+{
+ LOGI("ENTER");
+
+ LOGI("tensor name : %s", meta_info->name.c_str());
+
+ if (json_object_has_member(in_obj, "box"))
+ _postprocessParser.parseBox(meta_info, in_obj);
+
+ LOGI("LEAVE");
+}
+
+}
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <map>
+#include <memory>
+#include <algorithm>
+
+#include "machine_learning_exception.h"
+#include "face_iris.h"
+
+using namespace std;
+using namespace mediavision::inference;
+using namespace mediavision::machine_learning::exception;
+
+namespace mediavision
+{
+namespace machine_learning
+{
+FaceIris::FaceIris() : _backendType(), _targetDeviceType()
+{
+}
+
+void FaceIris::configure()
+{
+ int ret = _inference->Bind(_backendType, _targetDeviceType);
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to bind a backend engine.");
+}
+
+void FaceIris::prepare()
+{
+ int ret = _inference->configureInputMetaInfo(_parser->getInputMetaMap());
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to configure input tensor info from meta file.");
+
+ ret = _inference->configureOutputMetaInfo(_parser->getOutputMetaMap());
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to configure output tensor info from meta file.");
+
+ _inference->ConfigureModelFiles("", _modelFilePath, "");
+
+ // Request to load model files to a backend engine.
+ ret = _inference->Load();
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to load model files.");
+}
+void FaceIris::preprocess(mv_source_h &mv_src)
+{
+ LOGI("ENTER");
+
+ TensorBuffer &tensor_buffer_obj = _inference->getInputTensorBuffer();
+ IETensorBuffer &ie_tensor_buffer = tensor_buffer_obj.getIETensorBuffer();
+ vector<mv_source_h> mv_srcs = { mv_src };
+
+ _preprocess.run(mv_srcs, _parser->getInputMetaMap(), ie_tensor_buffer);
+
+ LOGI("LEAVE");
+}
+
+void FaceIris::inference(mv_source_h source)
+{
+ LOGI("ENTER");
+
+ vector<mv_source_h> sources;
+
+ sources.push_back(source);
+
+ int ret = _inference->Run();
+ if (ret != MEDIA_VISION_ERROR_NONE)
+ throw InvalidOperation("Fail to run inference");
+
+ LOGI("LEAVE");
+}
+
+}
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_private.h"
+#include "mv_face_iris_internal.h"
+#include "mv_face_iris_open.h"
+
+/**
+ * @file mv_face_iris.c
+ * @brief This file contains Media Vision inference module.
+ */
+
+int mv_face_iris_create(mv_face_iris_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 = MEDIA_VISION_ERROR_NONE;
+
+ ret = mv_face_iris_create_open(infer);
+
+ MEDIA_VISION_FUNCTION_LEAVE();
+ return ret;
+}
+
+int mv_face_iris_destroy(mv_face_iris_h infer)
+{
+ MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
+ MEDIA_VISION_INSTANCE_CHECK(infer);
+
+ MEDIA_VISION_FUNCTION_ENTER();
+
+ int ret = MEDIA_VISION_ERROR_NONE;
+
+ ret = mv_face_iris_destroy_open(infer);
+
+ MEDIA_VISION_FUNCTION_LEAVE();
+ return ret;
+}
+
+int mv_face_iris_configure(mv_face_iris_h infer)
+{
+ MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
+ MEDIA_VISION_INSTANCE_CHECK(infer);
+
+ MEDIA_VISION_FUNCTION_ENTER();
+
+ int ret = MEDIA_VISION_ERROR_NONE;
+
+ ret = mv_face_iris_configure_open(infer);
+
+ MEDIA_VISION_FUNCTION_LEAVE();
+ return ret;
+}
+
+int mv_face_iris_prepare(mv_face_iris_h infer)
+{
+ MEDIA_VISION_SUPPORT_CHECK(_mv_inference_check_system_info_feature_supported());
+ MEDIA_VISION_INSTANCE_CHECK(infer);
+
+ MEDIA_VISION_FUNCTION_ENTER();
+
+ int ret = MEDIA_VISION_ERROR_NONE;
+
+ ret = mv_face_iris_prepare_open(infer);
+
+ MEDIA_VISION_FUNCTION_LEAVE();
+ return ret;
+}
+
+int mv_face_iris_inference(mv_face_iris_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 = MEDIA_VISION_ERROR_NONE;
+
+ ret = mv_face_iris_inference_open(infer, source);
+
+ MEDIA_VISION_FUNCTION_LEAVE();
+
+ return ret;
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mv_private.h"
+#include "itask.h"
+#include "mv_face_iris_open.h"
+#include "face_detection_front_adapter.h"
+#include "machine_learning_exception.h"
+#include "face_iris_type.h"
+#include "context.h"
+
+#include <new>
+#include <unistd.h>
+#include <string>
+#include <algorithm>
+
+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<face_detection_input_s, face_detection_result_s>;
+using FaceLandmarkTask = ITask<face_landmark_input_s, face_landmark_result_s>;
+using FaceIrisTask = ITask<face_iris_input_s, face_iris_result_s>;
+
+int mv_face_iris_create_open(mv_face_iris_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 = new (nothrow) Context();
+ if (!context) {
+ LOGE("Fail to allocate a context.");
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ FaceDetectionTask *task = new (nothrow)
+ FaceDetectionFrontAdapter<face_detection_input_s, face_detection_result_s>();
+ if (!task) {
+ delete context;
+ LOGE("Fail to allocate a task.");
+ return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
+ }
+
+ try {
+ task->create(static_cast<int>(face_iris_task_type_e::FACE_DETECTION_TASK));
+ } catch (const BaseException &e) {
+ return e.getError();
+ }
+
+ context->__tasks.insert(make_pair("face_detection", task));
+ *out_handle = static_cast<mv_face_iris_h>(context);
+
+ LOGD("face iris handle [%p] has been created", *out_handle);
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_iris_destroy_open(mv_face_iris_h handle)
+{
+ if (!handle) {
+ LOGE("Handle is NULL.");
+ return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+ }
+
+ auto context = static_cast<Context *>(handle);
+
+ for (auto &m : context->__tasks) {
+ if (m.first.compare("face_detection") == 0)
+ delete static_cast<FaceDetectionTask *>(m.second);
+ }
+
+ delete context;
+
+ LOGD("face iris handle has been destroyed.");
+
+ return MEDIA_VISION_ERROR_NONE;
+}
+
+int mv_face_iris_configure_open(mv_face_iris_h handle)
+{
+ LOGD("ENTER");
+
+ 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["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_iris_prepare_open(mv_face_iris_h handle)
+{
+ LOGD("ENTER");
+
+ 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["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_iris_inference_open(mv_face_iris_h handle, mv_source_h source)
+{
+ LOGD("ENTER");
+
+ 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["face_detection"]);
+
+ face_detection_input_s 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;
+}
\ No newline at end of file
%{_libdir}/libmv_inference*.so
%{_datadir}/%{name}/object_detection_3d.json
%{_libdir}/libmv_object_detection*.so
+%{_datadir}/%{name}/face_iris.json
+%{_libdir}/libmv_face_iris*.so
%if "%{enable_ml_face_recognition}" == "1"
%{_datadir}/%{name}/face_recognition.json
%{_libdir}/libmv_training.so
%files machine_learning-devel
%{_includedir}/media/mv_infer*.h
%{_includedir}/media/mv_object_detection_3d*.h
+%{_includedir}/media/mv_face_iris*.h
%{_libdir}/pkgconfig/*inference.pc
%{_libdir}/pkgconfig/*object-detection.pc
+%{_libdir}/pkgconfig/*face-iris.pc
%if "%{enable_ml_face_recognition}" == "1"
%{_includedir}/media/mv_face_recognition*.h
%{_libdir}/pkgconfig/*training.pc
%{_libdir}/libmv_testsuite*.so
%{_bindir}/mv_*
%{_bindir}/test_object_detection_3d
+%{_bindir}/test_face_iris
%if "%{enable_ml_face_recognition}" == "1"
%{_bindir}/test_face_recognition
%{_bindir}/measure_face_recognition
add_subdirectory(${PROJECT_SOURCE_DIR}/inference)
add_subdirectory(${PROJECT_SOURCE_DIR}/object_detection)
+add_subdirectory(${PROJECT_SOURCE_DIR}/face_iris)
if (${ENABLE_ML_FACE_RECOGNITION})
message("Enabled machine learning face recognition test cases.")
--- /dev/null
+project(mv_face_iris_suite)
+cmake_minimum_required(VERSION 2.6...3.13)
+
+set(TEST_FACE_IRIS test_face_iris)
+
+add_executable(${TEST_FACE_IRIS} test_face_iris.cpp)
+
+target_link_libraries(${TEST_FACE_IRIS} gtest gtest_main
+ mv_inference
+ mv_face_iris
+ mv_image_helper
+)
+
+install(TARGETS ${TEST_FACE_IRIS} DESTINATION ${CMAKE_INSTALL_BINDIR})
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <iostream>
+#include <string.h>
+#include <map>
+
+#include "gtest/gtest.h"
+
+#include "ImageHelper.h"
+#include "mv_face_iris_internal.h"
+
+#define IMAGE_PATH "/res/inference/images/face_iris.jpeg"
+
+using namespace testing;
+using namespace std;
+
+using namespace MediaVision::Common;
+
+TEST(FaceIrisTest, InferenceShouldBeOk)
+{
+ mv_face_iris_h handle;
+
+ int ret = mv_face_iris_create(&handle);
+ ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+ ret = mv_face_iris_configure(handle);
+ ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+ ret = mv_face_iris_prepare(handle);
+ ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+ const string image_path = IMAGE_PATH;
+ mv_source_h mv_source = NULL;
+
+ ret = mv_create_source(&mv_source);
+ ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+ ret = ImageHelper::loadImageToSource(image_path.c_str(), mv_source);
+ ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+ ret = mv_face_iris_inference(handle, mv_source);
+ ASSERT_EQ(ret, 0);
+
+ ret = mv_destroy_source(mv_source);
+ ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+
+ ret = mv_face_iris_destroy(handle);
+ ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);
+}
\ No newline at end of file