[WIP-06] Add FaceShapeModelManager and face shape model
authorTae-Young Chung <ty83.chung@samsung.com>
Fri, 26 Apr 2024 03:15:46 +0000 (12:15 +0900)
committerTae-Young Chung <ty83.chung@samsung.com>
Fri, 26 Apr 2024 03:15:53 +0000 (12:15 +0900)
pdm.txt is from https://github.com/TadasBaltrusaitis/OpenFace/blob/master/lib/local/LandmarkDetector/model/pdms/In-the-wild_aligned_PDM_68.txt
It consists of 68 landmarks in 3D coordinate. The xyz order is xxxxx....yyyyy...zzzz... .

Signed-off-by: Tae-Young Chung <ty83.chung@samsung.com>
packaging/singleo.spec
services/CMakeLists.txt
services/smart_pointer/CMakeLists.txt
services/smart_pointer/include/FaceShapeModelManager.h [new file with mode: 0644]
services/smart_pointer/include/GazeEstimator.h
services/smart_pointer/include/PoseVector.h
services/smart_pointer/res/pdm.txt [new file with mode: 0644]
services/smart_pointer/src/FaceShapeModelManager.cpp [new file with mode: 0644]
services/smart_pointer/src/GazeEstimator.cpp

index 6562c0cf35be173696186f09b50be0a6b25f63a6..3999ca023fec553acb4de8b54b69832a6bad59df 100644 (file)
@@ -77,6 +77,7 @@ rm -rf %{buildroot}
 %files release
 %manifest singleo.manifest
 %license LICENSE.APLv2
+%{_datadir}/%{name}/pdm.txt
 
 %files devel
 %{_libdir}/pkgconfig/*.pc
index ba60d02cac34646ac475c42543f3b0dffe8edfed..6c42f413f7e7d876fc0c77c33cbfeac24473936f 100644 (file)
@@ -14,6 +14,7 @@ ENDIF()
 IF (${USE_SMARTPOINTER})
     INCLUDE(smart_pointer/CMakeLists.txt)
     LIST(APPEND SERVICE_HEADER_LIST ${CMAKE_CURRENT_SOURCE_DIR}/smart_pointer/include)
+    SET(SINGLEO_SERVICE_RESOURCE_FILES ${SINGLEO_SERVICE_RESOURCE_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/smart_pointer/res/pdm.txt)
 ENDIF()
 
 ADD_LIBRARY(${PROJECT_NAME} SHARED ${SINGLEO_SERVICE_SOURCE_FILES})
@@ -21,4 +22,6 @@ ADD_LIBRARY(${PROJECT_NAME} SHARED ${SINGLEO_SERVICE_SOURCE_FILES})
 TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE include common/include ../capi/ ../input/include ../log/include ../inference/include ../common/include ${SERVICE_HEADER_LIST})
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE opencv_imgcodecs singleo_log singleo_input ${SERVICE_LIBRARY_LIST})
 
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
\ No newline at end of file
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
+
+INSTALL(FILES ${SINGLEO_SERVICE_RESOURCE_FILES} DESTINATION /usr/share/singleo)
\ No newline at end of file
index 199489d4067faab7eb1b9a32c48d0e4f19f40b2e..298e736d261dd52f49ed948ae05b8ae3327bb769 100644 (file)
@@ -1,7 +1,8 @@
-set(SINGLEO_SERVICE_SOURCE_FILES
+SET(SINGLEO_SERVICE_SOURCE_FILES
     ${SINGLEO_SERVICE_SOURCE_FILES}
     smart_pointer/src/SmartPointer.cpp
     smart_pointer/src/GazeEstimator.cpp
+    smart_pointer/src/FaceShapeModelManager.cpp
 )
 
 LIST(APPEND SERVICE_LIBRARY_LIST singleo_inference)
\ No newline at end of file
diff --git a/services/smart_pointer/include/FaceShapeModelManager.h b/services/smart_pointer/include/FaceShapeModelManager.h
new file mode 100644 (file)
index 0000000..e430bda
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#ifndef __FACE_SHAPE_MODEL_MANAGER_H__
+#define __FACE_SHAPE_MODEL_MANAGER_H__
+
+#include <memory>
+#include <vector>
+#include <PoseVector.h>
+
+namespace singleo
+{
+namespace services
+{
+namespace smartpointer
+{
+class FaceShapeModelManager
+{
+private:
+    std::vector<Point3f> _faceShape;
+
+    void loadModelFromFile(const std::string &model_path);
+    template <typename T>
+    T ToNumber(const std::string &text);
+
+public:
+    FaceShapeModelManager(const std::string &model_path);
+    ~FaceShapeModelManager();
+};
+} // smartpointer
+} // services 
+} // singleo
+
+#endif
index 09786a8a7c8fe7c173837380013bcd640d30a58a..28aec9ddf6a4a7aa0f8071cc24b5b8634ecf2cad 100644 (file)
@@ -22,6 +22,7 @@
 #include "IInputService.h"
 #include "SingleoInferenceTypes.h"
 #include "PoseVector.h"
+#include "FaceShapeModelManager.h"
 
 namespace singleo
 {
@@ -34,13 +35,15 @@ class GazeEstimator
 private:
     std::unique_ptr<singleo::inference::IInferenceFaceService> _face_estimator;
     std::unique_ptr<singleo::input::IInputService> _input_service;
+    std::unique_ptr<FaceShapeModelManager> _face_shape_model_manager;
 
     std::vector<inference::TaskType> _tasks { inference::TaskType::FACE_DETECTION, inference::TaskType::FACE_LANDMARK_DETECTION };
 
+    PoseVector _headPose;
 public:
     explicit GazeEstimator(input::InputConfigBase &config);
     ~GazeEstimator();
-    PoseVector estimateHeadpose(BaseDataType &input);
+    PoseVector &estimateHeadpose(BaseDataType &input);
 
 };
 } // smartpointer
index 9146f355e182c5953cf1f80eb9f6b41329395c82..116f423263cba9e2ae0624d0ee2d54cc492982fb 100644 (file)
@@ -23,12 +23,24 @@ namespace services
 {
 namespace smartpointer
 {
-struct PoseVector
+
+struct Point3f
 {
     float x;
     float y;
     float z;
 };
+
+struct PoseVector
+{
+    Point3f vec;
+    void reset()
+    {
+        vec.x = 0.0f;
+        vec.y = 0.0f;
+        vec.z = 0.0f;
+    }
+};
 } // smartpointer
 } // services
 } // singleo
diff --git a/services/smart_pointer/res/pdm.txt b/services/smart_pointer/res/pdm.txt
new file mode 100644 (file)
index 0000000..f415390
--- /dev/null
@@ -0,0 +1,205 @@
+68
+-73.393523 
+-72.775014 
+-70.533638 
+-66.850058 
+-59.790187 
+-48.368973 
+-34.121101 
+-17.875411 
+0.098749 
+17.477031 
+32.648966 
+46.372358 
+57.343480 
+64.388482 
+68.212038 
+70.486405 
+71.375822 
+-61.119406 
+-51.287588 
+-37.804800 
+-24.022754 
+-11.635713 
+12.056636 
+25.106256 
+38.338588 
+51.191007 
+60.053851 
+0.653940 
+0.804809 
+0.992204 
+1.226783 
+-14.772472 
+-7.180239 
+0.555920 
+8.272499 
+15.214351 
+-46.047290 
+-37.674688 
+-27.883856 
+-19.648268 
+-28.272965 
+-38.082418 
+19.265868 
+27.894191 
+37.437529 
+45.170805 
+38.196454 
+28.764989 
+-28.916267 
+-17.533194 
+-6.684590 
+0.381001 
+8.375443 
+18.876618 
+28.794412 
+19.057574 
+8.956375 
+0.381549 
+-7.428895 
+-18.160634 
+-24.377490 
+-6.897633 
+0.340663 
+8.444722 
+24.474473 
+8.449166 
+0.205322 
+-7.198266 
+-29.801432 
+-10.949766 
+7.929818 
+26.074280 
+42.564390 
+56.481080 
+67.246992 
+75.056892 
+77.061286 
+74.758448 
+66.929021 
+56.311389 
+42.419126 
+25.455880 
+6.990805 
+-11.666193 
+-30.365191 
+-49.361602 
+-58.769795 
+-61.996155 
+-61.033399 
+-56.686759 
+-57.391033 
+-61.902186 
+-62.777713 
+-59.302347 
+-50.190255 
+-42.193790 
+-30.993721 
+-19.944596 
+-8.414541 
+2.598255 
+4.751589 
+6.562900 
+4.661005 
+2.643046 
+-37.471411 
+-42.730510 
+-42.711517 
+-36.754742 
+-35.134493 
+-34.919043 
+-37.032306 
+-43.342445 
+-43.110822 
+-38.086515 
+-35.532024 
+-35.484289 
+28.612716 
+22.172187 
+19.029051 
+20.721118 
+19.035460 
+22.394109 
+28.079924 
+36.298248 
+39.634575 
+40.395647 
+39.836405 
+36.677899 
+28.677771 
+25.475976 
+26.014269 
+25.326198 
+28.323008 
+30.596216 
+31.408738 
+30.844876 
+47.667532 
+45.909403 
+44.842580 
+43.141114 
+38.635298 
+30.750622 
+18.456453 
+3.609035 
+-0.881698 
+5.181201 
+19.176563 
+30.770570 
+37.628629 
+40.886309 
+42.281449 
+44.142567 
+47.140426 
+14.254422 
+7.268147 
+0.442051 
+-6.606501 
+-11.967398 
+-12.051204 
+-7.315098 
+-1.022953 
+5.349435 
+11.615746 
+-13.380835 
+-21.150853 
+-29.284036 
+-36.948060 
+-20.132003 
+-23.536684 
+-25.944448 
+-23.695741 
+-20.858157 
+7.037989 
+3.021217 
+1.353629 
+-0.111088 
+-0.147273 
+1.476612 
+-0.665746 
+0.247660 
+1.696435 
+4.894163 
+0.282961 
+-1.172675 
+-2.240310 
+-15.934335 
+-22.611355 
+-23.748437 
+-22.721995 
+-15.610679 
+-3.217393 
+-14.987997 
+-22.554245 
+-23.591626 
+-22.406106 
+-15.121907 
+-4.785684 
+-20.893742 
+-22.220479 
+-21.025520 
+-5.712776 
+-20.671489 
+-21.903670 
+-20.328022 
diff --git a/services/smart_pointer/src/FaceShapeModelManager.cpp b/services/smart_pointer/src/FaceShapeModelManager.cpp
new file mode 100644 (file)
index 0000000..207d9cc
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+#include "FaceShapeModelManager.h"
+#include "SingleoLog.h"
+
+using namespace std;
+
+namespace singleo
+{
+namespace services
+{
+namespace smartpointer
+{
+
+FaceShapeModelManager::FaceShapeModelManager(const std::string &model_path)
+{
+    if (model_path.empty())
+        throw std::invalid_argument("Invalid face shape model path");
+
+    loadModelFromFile(model_path);
+}
+
+FaceShapeModelManager::~FaceShapeModelManager()
+{
+
+}
+
+template <typename T>
+T FaceShapeModelManager::ToNumber(const string &text)
+{
+    std::stringstream ss(text);
+    T number;
+    ss >> number;
+    return number;
+}
+
+void FaceShapeModelManager::loadModelFromFile(const std::string &model_path)
+{
+    fstream file(model_path, ios::in);
+    if (!file.is_open())
+        throw std::runtime_error("Fail to open face shape model file");
+    
+    std::string line;
+    getline(file, line);
+
+    _faceShape.resize(ToNumber<int>(line));
+    for (auto &point : _faceShape) {
+        getline(file, line);
+        point.x = ToNumber<float>(line);
+    }
+
+    for (auto &point : _faceShape) {
+        getline(file, line);
+        point.y = ToNumber<float>(line);
+    }
+
+    for (auto &point : _faceShape) {
+        getline(file, line);
+        point.z = ToNumber<float>(line);
+    }
+
+    SINGLEO_LOGI("%zd landarks", _faceShape.size());
+}
+
+template float FaceShapeModelManager::ToNumber(const string &text);
+} // smartpointer
+} // services
+} // singleo
index a8b03aff79b390ff1bd5d3f04397d0dff761b1b9..2519fcd0db7e67750da4caabd6ac43f379d95750 100644 (file)
@@ -36,6 +36,9 @@ GazeEstimator::GazeEstimator(InputConfigBase& config)
 
     _face_estimator->configure();
        _face_estimator->prepare();
+
+    _face_shape_model_manager = make_unique<FaceShapeModelManager>("/usr/share/singleo/pdm.txt");
+    _headPose.reset();
 }
 
 GazeEstimator::~GazeEstimator()
@@ -43,21 +46,18 @@ GazeEstimator::~GazeEstimator()
 
 }
 
-PoseVector GazeEstimator::estimateHeadpose(BaseDataType &input)
+PoseVector &GazeEstimator::estimateHeadpose(BaseDataType &input)
 {
     _face_estimator->invoke(input);
 
     SINGLEO_LOGD("Invoke done");
     auto &result = _face_estimator->result();
     SINGLEO_LOGD("Result done");
-    // if (!result._rects.empty())
-    //     SINGLEO_LOGD("ROI: %d, %d, %d,%d",
-    //             result._rects[0].top, result._rects[0].left, result._rects[0].bottom, result._rects[0].right);
 
     // auto &headPose = dynamic_cast<FldResultType&>(result);
     // SINGLEO_LOGD("Landmark: %zd, %zd",
     //             headPose._landmarks[0].x, headPose._landmarks[0].y);
-    return PoseVector{-1, -1, -1};
+    return _headPose;
 }
 
 } // smartpointer