mv_machine_learning: update iris detection api
authorInki Dae <inki.dae@samsung.com>
Fri, 9 Dec 2022 02:58:08 +0000 (11:58 +0900)
committerInki Dae <inki.dae@samsung.com>
Wed, 14 Dec 2022 01:58:09 +0000 (10:58 +0900)
Change-Id: I180492020a2bda4d2b8ac1b91f971b1049b0cfd4
Signed-off-by: Inki Dae <inki.dae@samsung.com>
15 files changed:
include/mv_face_iris_internal.h
include/mv_face_iris_type_internal.h [new file with mode: 0644]
mv_machine_learning/face_iris/include/face_iris.h
mv_machine_learning/face_iris/include/face_iris_type.h
mv_machine_learning/face_iris/include/mv_face_iris_open.h
mv_machine_learning/face_iris/src/face_detection_front.cpp
mv_machine_learning/face_iris/src/face_detection_front_adapter.cpp
mv_machine_learning/face_iris/src/face_iris.cpp
mv_machine_learning/face_iris/src/face_iris_detection.cpp
mv_machine_learning/face_iris/src/face_iris_detection_adapter.cpp
mv_machine_learning/face_iris/src/face_landmark_detection.cpp
mv_machine_learning/face_iris/src/face_landmark_detection_adapter.cpp
mv_machine_learning/face_iris/src/mv_face_iris.c
mv_machine_learning/face_iris/src/mv_face_iris_open.cpp
test/testsuites/machine_learning/face_iris/test_face_iris.cpp

index 1a70becbcb7f62f51b014ae4b28186ed6047dc33..51975d22c018d278737024a6df5402860478ad29 100644 (file)
@@ -34,6 +34,8 @@ int mv_face_iris_prepare(mv_face_iris_h infer);
 
 int mv_face_iris_inference(mv_face_iris_h infer, mv_source_h source);
 
+int mv_face_iris_get_result(mv_face_iris_h infer, void *result);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/include/mv_face_iris_type_internal.h b/include/mv_face_iris_type_internal.h
new file mode 100644 (file)
index 0000000..0dcdb88
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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_INTERNAL_H__
+#define __TIZEN_MEDIAVISION_FACE_IRIS_TYPE_INTERNAL_H__
+
+#include <mv_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define MAX_FACE_NUM    10
+#define FACE_KEY_NUM    468
+
+enum face_key_id {
+    kRightEye = 0,  //  0
+    kLeftEye,       //  1
+    kNose,          //  2
+    kMouth,         //  3
+    kRightEar,      //  4
+    kLeftEar,       //  5
+    kFaceKeyNum
+};
+
+typedef struct {
+    float x, y;
+} fvec2;
+
+typedef struct {
+    float x, y, z;
+} fvec3;
+
+typedef struct {
+    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];
+} face_t;
+
+typedef struct {
+    int num;
+    face_t faces[MAX_FACE_NUM];
+} face_detection_result_s;
+
+typedef struct {
+    float rotation;
+    fvec2 center;
+    fvec2 size;
+} eye_region_t;
+
+typedef struct {
+    float score;
+    fvec3 joint[FACE_KEY_NUM];
+    eye_region_t    eye_rgn[2];
+    fvec2           eye_pos[2][4];
+} face_landmark_result_s;
+
+typedef struct {
+    fvec3 eye_landmark[71];
+    fvec3 iris_landmark[5];
+} face_iris_result_s;
+
+typedef struct {
+       face_detection_result_s detection;
+       face_landmark_result_s landmark[MAX_FACE_NUM];
+       face_iris_result_s iris[MAX_FACE_NUM][2];
+} face_iris_s;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TIZEN_MEDIAVISION_FACE_IRIS_TYPE_INTERNAL_H__ */
index 2365c123f8a4c0664a56cb759607a2a81e5ff45e..97ddef00631712e9af6f84935c6276132e6c572f 100644 (file)
@@ -46,8 +46,6 @@ protected:
        int _backendType;
        int _targetDeviceType;
 
-       void FlipHorizontalIrisLandmark (face_iris_result_s *irismesh);
-
 public:
        FaceIris();
        virtual ~FaceIris() = default;
index e8237a745f9a730c453cfa1a08cac98979b58a2b..b2ab88f4791dffd1853984fca89f994c05d0c000 100644 (file)
@@ -107,6 +107,12 @@ struct face_iris_result_s {
     fvec3 iris_landmark[5];
 };
 
+struct face_iris_s {
+       face_detection_result_s detection;
+       face_landmark_result_s landmark[MAX_FACE_NUM];
+       face_iris_result_s iris[MAX_FACE_NUM][2];
+};
+
 }
 }
 
index d80f91ddcffd587321642c65457067daec83f131..46ca08b0c09ebdaf203ff17a2930987d78490eb9 100644 (file)
@@ -35,6 +35,8 @@ 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);
 
+int mv_face_iris_get_result_open(mv_face_iris_h handle, void *result);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index a1a6fae7d14d8e26c583754fa94113b3162f6328..e95e132d252f32bffe93911267f4821579562782 100644 (file)
@@ -393,21 +393,7 @@ face_detection_result_s &FaceDetectionFront::getDetectionResult()
        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;
-       }
+       PackFaceResult(&_result, face_nms_list);
 
        return _result;
 }
index b06f5a01986d1a1f48b43eac101e7c6d4dd95c66..0970dafe9e392d64de3bbc8763acd4f957c05f6c 100644 (file)
@@ -74,7 +74,6 @@ 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->getDetectionResult(); //
        } catch (const BaseException &e) {
                throw e;
        }
index 12c878ae62db3f0dfaa88cc8b44c69ce254f8773..753b5c376dfc28f1c15e6eaa6e112810928bbd42 100644 (file)
@@ -88,17 +88,5 @@ void FaceIris::inference(mv_source_h source)
        LOGI("LEAVE");
 }
 
-void FaceIris::FlipHorizontalIrisLandmark (face_iris_result_s *irismesh)
-{
-       fvec3 *eye  = irismesh->eye_landmark;
-       fvec3 *iris = irismesh->iris_landmark;
-
-       for (int i = 0; i < 71; i ++)
-               eye[i].x = 1.0f - eye[i].x;
-
-       for (int i = 0; i < 5; i ++)
-               iris[i].x = 1.0f - iris[i].x;
-}
-
 }
 }
\ No newline at end of file
index 2bc3f1f81d15f9b1d384896b21f00a07ae16e765..7a7da25ba67dce530522ec89787e2ced55ab281f 100644 (file)
@@ -106,22 +106,16 @@ face_iris_result_s &FaceIrisDetection::getIrisResult()
        float *eye_ptr = reinterpret_cast<float *>(_eye_tensor->buffer);
        float *iris_ptr = reinterpret_cast<float *>(_iris_tensor->buffer);
 
-       cout << "eye info" << endl;
        for (unsigned int idx = 0; idx < 71; idx ++) {
                _result.eye_landmark[idx].x = eye_ptr[3 * idx + 0] / static_cast<float>(input_img_w);
                _result.eye_landmark[idx].y = eye_ptr[3 * idx + 1] / static_cast<float>(input_img_h);
                _result.eye_landmark[idx].z = eye_ptr[3 * idx + 2];
-
-               cout << "idx = " << idx << " x/y/z = " << _result.eye_landmark[idx].x << " / " << _result.eye_landmark[idx].y << " / " << _result.eye_landmark[idx].z << endl;
        }
 
-       cout << "eye info" << endl;
        for (unsigned int idx = 0; idx < 5; idx ++) {
                _result.iris_landmark[idx].x = iris_ptr[3 * idx + 0] / static_cast<float>(input_img_w);
                _result.iris_landmark[idx].y = iris_ptr[3 * idx + 1] / static_cast<float>(input_img_h);
                _result.iris_landmark[idx].z = iris_ptr[3 * idx + 2];
-
-               cout << "idx = " << idx << " x/y/z = " << _result.iris_landmark[idx].x << " / " << _result.iris_landmark[idx].y << " / " << _result.iris_landmark[idx].z << endl;
        }
 
        return _result;
index 21a90bd98f4f31510581d4914087a0c5e3d07ba3..641a94719974cbc0dcd9ec0b478ef5884b47df4b 100644 (file)
@@ -74,7 +74,6 @@ template<typename T, typename V> void FaceIrisDetectionAdapter<T, V>::perform()
        try {
                _face_iris->preprocess(_source.inference_src);
                _face_iris->inference(_source.inference_src);
-               _face_iris->getIrisResult(); //
        } catch (const BaseException &e) {
                throw e;
        }
index bfd7d40ae2c624a1b34e30948ee30c4c1f8e3ea8..0533d8274ae1face7037805e5dda3a4739b1f06b 100644 (file)
@@ -167,9 +167,6 @@ face_landmark_result_s &FaceLandmarkDetection::getLandmarkResult()
        float *mashscore_ptr = reinterpret_cast<float *>(_scores_tensor->buffer);
        float *landmark_ptr = reinterpret_cast<float *>(_landmark_tensor->buffer);
 
-       cout << "width = " << input_img_w << " height = " << input_img_h << endl;
-       cout << "score = " << *mashscore_ptr << endl;
-
        for (unsigned int idx = 0; idx < FACE_KEY_NUM; idx ++) {
                _result.joint[idx].x = landmark_ptr[3 * idx + 0] / (float)input_img_w;
                _result.joint[idx].y = landmark_ptr[3 * idx + 1] / (float)input_img_h;
@@ -178,19 +175,6 @@ face_landmark_result_s &FaceLandmarkDetection::getLandmarkResult()
 
        ComputeEyeRoi(&_result);
 
-       for (unsigned int id_idx = 0; id_idx < 2; ++id_idx) {
-               eye_region_t *eye_rgn = &_result.eye_rgn[id_idx];
-               cout << "id = " << id_idx << endl;
-               for (unsigned int idx = 0; idx < 4; ++idx) {
-                       fvec2 *eye_pos = _result.eye_pos[id_idx];
-                       cout << "x = " << eye_pos[idx].x << " y = " << eye_pos[idx].y << endl;
-               }
-
-               cout << "rotation = " << eye_rgn->rotation << endl;
-               cout << "center x/y = " << eye_rgn->center.x << " / " << eye_rgn->center.y << endl;
-               cout << "size x/y = " << eye_rgn->size.x << " / " << eye_rgn->size.y << endl;
-       }
-
        return _result;
 }
 
index 25c3ed9a33612060dd905cf708c2fd53f5cd880b..29e83bc4e54579dbe3a05dec8c2e5424efa63e6b 100644 (file)
@@ -74,7 +74,6 @@ template<typename T, typename V> void FaceLandmarkDetectionAdapter<T, V>::perfor
        try {
                _face_landmark->preprocess(_source.inference_src);
                _face_landmark->inference(_source.inference_src);
-               _face_landmark->getLandmarkResult(); //
        } catch (const BaseException &e) {
                throw e;
        }
index 77821f081f59acbbb19997395c40df9413f08f34..dff90c7031096b44a39ae1ab4882f777f5777b5c 100644 (file)
@@ -97,5 +97,21 @@ int mv_face_iris_inference(mv_face_iris_h infer, mv_source_h source)
 
        MEDIA_VISION_FUNCTION_LEAVE();
 
+       return ret;
+}
+
+int mv_face_iris_get_result(mv_face_iris_h infer, void *result)
+{
+       MEDIA_VISION_SUPPORT_CHECK(_mv_inference_image_check_system_info_feature_supported());
+       MEDIA_VISION_INSTANCE_CHECK(infer);
+
+       MEDIA_VISION_FUNCTION_ENTER();
+
+       int ret = MEDIA_VISION_ERROR_NONE;
+
+       ret = mv_face_iris_get_result_open(infer, result);
+
+       MEDIA_VISION_FUNCTION_LEAVE();
+
        return ret;
 }
\ No newline at end of file
index d54e28ca4efb9b8bacc48aae2662351fff807a76..6eef5d3bfd71957c02b443feb2cd751d0bf7c501 100644 (file)
@@ -180,6 +180,19 @@ int mv_face_iris_prepare_open(mv_face_iris_h handle)
        return MEDIA_VISION_ERROR_NONE;
 }
 
+
+static void FlipHorizontalIrisLandmark(face_iris_result_s *irismesh)
+{
+       fvec3 *eye  = irismesh->eye_landmark;
+       fvec3 *iris = irismesh->iris_landmark;
+
+       for (int i = 0; i < 71; i ++)
+               eye[i].x = 1.0f - eye[i].x;
+
+       for (int i = 0; i < 5; i ++)
+               iris[i].x = 1.0f - iris[i].x;
+}
+
 int mv_face_iris_inference_open(mv_face_iris_h handle, mv_source_h source)
 {
        LOGD("ENTER");
@@ -204,11 +217,61 @@ int mv_face_iris_inference_open(mv_face_iris_h handle, mv_source_h source)
                iris_task->setInput(iris_input);
 
                detection_task->perform();
-               landmark_task->perform();
-               iris_task->perform();
+       } catch (const BaseException &e) {
+               LOGE("%s", e.what());
+               return e.getError();
+       }
+
+       LOGD("LEAVE");
+
+       return MEDIA_VISION_ERROR_NONE;
+}
+
+
+int mv_face_iris_get_result_open(mv_face_iris_h handle, void *result)
+{
+       LOGD("ENTER");
+
+       if (!handle) {
+               LOGE("Handle is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!result) {
+               LOGE("result is NULL.");
+               return MEDIA_VISION_ERROR_INVALID_PARAMETER;
+       }
+
+       face_iris_s *p_result = static_cast<face_iris_s *>(result);
+
+       try {
+               auto context = static_cast<Context *>(handle);
+               auto detection_task = static_cast<FaceDetectionTask *>(context->__tasks["face_detection"]);
+               auto landmark_task = static_cast<FaceLandmarkTask *>(context->__tasks["face_landmark"]);
+               auto iris_task = static_cast<FaceIrisTask *>(context->__tasks["face_iris"]);
+
+               face_detection_result_s &detection_result = detection_task->getOutput();
+               p_result->detection = detection_result;
+
+               LOGD("detection num = %d", detection_result.num);
+
+               for (int face_id = 0; face_id < detection_result.num; ++face_id) {
+                       landmark_task->perform();
+                       face_landmark_result_s &landmark_result = landmark_task->getOutput();
+                       p_result->landmark[face_id] = landmark_result;
+               }
+
+               for (int face_id = 0; face_id < detection_result.num; ++face_id) {
+                       for (int eye_id = 0; eye_id < 2; ++eye_id) {
+                               iris_task->perform();
+                               face_iris_result_s &iris_result = iris_task->getOutput();
+                               p_result->iris[face_id][eye_id] = iris_result;
+                       }
+
+                       // For each face id, flip the landmark corresponding to eye index 1.
+                       FlipHorizontalIrisLandmark(&p_result->iris[face_id][1]);
+               }
 
-               // TODO. for each face id, flip the landmark corresponding to eye index 1.
-               // iris_task->FlipHorizontalIrisLandmark()
        } catch (const BaseException &e) {
                LOGE("%s", e.what());
                return e.getError();
index 3aa6c535579301ef172fe30e5fcb49448a6102a1..f14bf0c3baf891bc9bfd1f4741168bb7399dc485 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "ImageHelper.h"
 #include "mv_face_iris_internal.h"
+#include "mv_face_iris_type_internal.h"
 
 #define IMAGE_PATH "/res/inference/images/face_iris.jpeg"
 
@@ -30,6 +31,54 @@ using namespace std;
 
 using namespace MediaVision::Common;
 
+void ShowResult(face_iris_s &result)
+{
+       face_detection_result_s &detection_result = result.detection;
+
+       for (unsigned int idx = 0; idx < detection_result.num; ++idx) {
+               face_t &face = detection_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;
+
+               // Print landmark information.
+               face_landmark_result_s &landmark_result = result.landmark[idx];
+
+               for (unsigned int id_idx = 0; id_idx < 2; ++id_idx) {
+                       eye_region_t *eye_rgn = &landmark_result.eye_rgn[id_idx];
+                       cout << "id = " << id_idx << endl;
+                       for (unsigned int idx = 0; idx < 4; ++idx) {
+                               fvec2 *eye_pos = landmark_result.eye_pos[id_idx];
+                               cout << "x = " << eye_pos[idx].x << " y = " << eye_pos[idx].y << endl;
+                       }
+
+                       cout << "rotation = " << eye_rgn->rotation << endl;
+                       cout << "center x/y = " << eye_rgn->center.x << " / " << eye_rgn->center.y << endl;
+                       cout << "size x/y = " << eye_rgn->size.x << " / " << eye_rgn->size.y << endl;
+               }
+
+               // Print iris information.
+               for (int eye_id = 0; eye_id < 2; ++eye_id) {
+                       face_iris_result_s &iris_result = result.iris[idx][eye_id];
+
+                       cout << "eye info" << endl;
+                       for (unsigned int idx = 0; idx < 71; idx ++) {
+                               cout << "idx = " << idx << " x/y/z = " << iris_result.eye_landmark[idx].x
+                                       << " / " << iris_result.eye_landmark[idx].y << " / " << iris_result.eye_landmark[idx].z << endl;
+                       }
+
+                       cout << "iris info" << endl;
+                       for (unsigned int idx = 0; idx < 5; idx ++) {
+                               cout << "idx = " << idx << " x/y/z = " << iris_result.iris_landmark[idx].x
+                                        << " / " << iris_result.iris_landmark[idx].y << " / " << iris_result.iris_landmark[idx].z << endl;
+                       }
+               }
+       }
+}
+
 TEST(FaceIrisTest, InferenceShouldBeOk)
 {
        mv_face_iris_h handle;
@@ -55,6 +104,13 @@ TEST(FaceIrisTest, InferenceShouldBeOk)
        ret = mv_face_iris_inference(handle, mv_source);
        ASSERT_EQ(ret, 0);
 
+       face_iris_s result;
+
+       ret = mv_face_iris_get_result(handle, static_cast<void *>(&result));
+       ASSERT_EQ(ret, 0);
+
+       ShowResult(result);
+
        ret = mv_destroy_source(mv_source);
        ASSERT_EQ(ret, MEDIA_VISION_ERROR_NONE);