Use OpenSeeFace to control Live2D model
[facial-landmarks-for-cubism.git] / include / facial_landmark_detector.h
CommitLineData
830d0ba4
AIL
1// -*- mode: c++ -*-
2
cb483d3b
AIL
3#ifndef FACIAL_LANDMARK_DETECTOR_H
4#define FACIAL_LANDMARK_DETECTOR_H
830d0ba4
AIL
5
6/****
cb483d3b 7Copyright (c) 2020-2021 Adrian I. Lam
830d0ba4
AIL
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in all
17copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25SOFTWARE.
26****/
27
28#include <deque>
29#include <string>
af96b559
AIL
30
31struct Point
32{
33 double x;
34 double y;
35
36 Point(double _x = 0, double _y = 0)
37 {
38 x = _x;
39 y = _y;
40 }
41};
830d0ba4
AIL
42
43class FacialLandmarkDetector
44{
45public:
46 struct Params
47 {
48 double leftEyeOpenness;
49 double rightEyeOpenness;
50 double leftEyeSmile;
51 double rightEyeSmile;
52 double mouthOpenness;
53 double mouthForm;
54 double faceXAngle;
55 double faceYAngle;
56 double faceZAngle;
2b1f0c7c
AIL
57 bool autoBlink;
58 bool autoBreath;
59 bool randomMotion;
830d0ba4 60 // TODO eyebrows currently not supported...
cb483d3b 61 // I'd like to include them, but the dlib / OSF detection is very
830d0ba4
AIL
62 // noisy and inaccurate (at least for my face).
63 };
64
65 FacialLandmarkDetector(std::string cfgPath);
cb483d3b 66 ~FacialLandmarkDetector();
830d0ba4
AIL
67
68 Params getParams(void) const;
69
70 void stop(void);
71
72 void mainLoop(void);
73
74private:
cb483d3b
AIL
75 FacialLandmarkDetector(const FacialLandmarkDetector&) = delete;
76 FacialLandmarkDetector& operator=(const FacialLandmarkDetector &) = delete;
77
830d0ba4
AIL
78 enum LeftRight : bool
79 {
80 LEFT,
81 RIGHT
82 };
83
830d0ba4
AIL
84 bool m_stop;
85
cb483d3b
AIL
86 int m_sock;
87 static const int m_faceId = 0; // Only support one face for now
88
af96b559
AIL
89 double calcEyeAspectRatio(Point& p1, Point& p2,
90 Point& p3, Point& p4,
91 Point& p5, Point& p6) const;
830d0ba4 92
af96b559
AIL
93 double calcRightEyeAspectRatio(Point landmarks[]) const;
94 double calcLeftEyeAspectRatio(Point landmarks[]) const;
830d0ba4
AIL
95
96 double calcEyeOpenness(LeftRight eye,
af96b559 97 Point landmarks[],
830d0ba4
AIL
98 double faceYAngle) const;
99
af96b559
AIL
100 double calcMouthForm(Point landmarks[]) const;
101 double calcMouthOpenness(Point landmarks[], double mouthForm) const;
830d0ba4 102
af96b559
AIL
103 double calcFaceXAngle(Point landmarks[]) const;
104 double calcFaceYAngle(Point landmarks[], double faceXAngle, double mouthForm) const;
105 double calcFaceZAngle(Point landmarks[]) const;
830d0ba4
AIL
106
107 void populateDefaultConfig(void);
108 void parseConfig(std::string cfgPath);
109 void throwConfigError(std::string paramName, std::string expectedType,
110 std::string line, unsigned int lineNum);
111
112
113 std::deque<double> m_leftEyeOpenness;
114 std::deque<double> m_rightEyeOpenness;
115
116 std::deque<double> m_mouthOpenness;
117 std::deque<double> m_mouthForm;
118
119 std::deque<double> m_faceXAngle;
120 std::deque<double> m_faceYAngle;
121 std::deque<double> m_faceZAngle;
122
123 struct Config
124 {
cb483d3b
AIL
125 std::string osfIpAddress;
126 int osfPort;
830d0ba4
AIL
127 double faceYAngleCorrection;
128 double eyeSmileEyeOpenThreshold;
129 double eyeSmileMouthFormThreshold;
130 double eyeSmileMouthOpenThreshold;
830d0ba4
AIL
131 std::size_t faceXAngleNumTaps;
132 std::size_t faceYAngleNumTaps;
133 std::size_t faceZAngleNumTaps;
134 std::size_t mouthFormNumTaps;
135 std::size_t mouthOpenNumTaps;
136 std::size_t leftEyeOpenNumTaps;
137 std::size_t rightEyeOpenNumTaps;
830d0ba4
AIL
138 double eyeClosedThreshold;
139 double eyeOpenThreshold;
140 double mouthNormalThreshold;
141 double mouthSmileThreshold;
142 double mouthClosedThreshold;
143 double mouthOpenThreshold;
144 double mouthOpenLaughCorrection;
145 double faceYAngleXRotCorrection;
146 double faceYAngleSmileCorrection;
147 double faceYAngleZeroValue;
148 double faceYAngleUpThreshold;
149 double faceYAngleDownThreshold;
cb483d3b 150 bool winkEnable;
2b1f0c7c
AIL
151 bool autoBlink;
152 bool autoBreath;
153 bool randomMotion;
830d0ba4
AIL
154 } m_cfg;
155};
156
157#endif
158