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