22
33
44PositionSolver::PositionSolver (int width, int height,
5- float prior_pitch, float prior_yaw, float prior_distance) :
6- contour_indices{ 0 , 1 , 8 , 15 , 16 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 39 , 42 , 45 },
7- landmark_points_buffer (NB_CONTOUR_POINTS , 1 , CV_32FC2),
5+ float prior_pitch, float prior_yaw, float prior_distance, bool complex , float fov ) :
6+ // TODO: Refactor removing prior_yaw/pitch parameters
7+ landmark_points_buffer(complex ? NB_CONTOUR_POINTS_COMPLEX: NB_CONTOUR_POINTS_BASE , 1 , CV_32FC2),
88 rv({ 0 , 0 , 0 }),
99 tv({ 0 , 0 , 0 })
1010{
11- this ->prior_pitch = ( 1 . 1f * (prior_pitch + 90 . f ) / 180 . f ) - ( double ) 2 . 5f ;
12- this ->prior_distance = prior_distance * - 2 . ;
13- this ->prior_yaw = ( 1 . 84f * (prior_yaw + 90 . f ) / 180 . f ) - ( double ) 3 . 14f ;
11+ this ->prior_pitch = - 1.57 ;
12+ this ->prior_yaw = - 1.57 ;
13+ this ->prior_distance = prior_distance * - 1 . ;
1414
1515 this ->rv [0 ] = this ->prior_pitch ;
1616 this ->rv [1 ] = this ->prior_yaw ;
17+ this ->rv [2 ] = -1.57 ;
1718 this ->tv [2 ] = this ->prior_distance ;
1819
19- // std::cout << "PRIORS CALCULATED: \nPITCH: " <<this->prior_pitch << " YAW: " << this->prior_yaw << " DISTANCE: " << this->prior_distance;
20-
21- mat3dcontour = (cv::Mat_<double >(18 , 3 ) <<
22- 0.45517698 , -0.30089578 , 0.76442945 ,
23- 0.44899884 , -0.16699584 , 0.765143 ,
24- 0 ., 0.621079 , 0.28729478 ,
25- -0.44899884 , -0.16699584 , 0.765143 ,
26- -0.45517698 , -0.30089578 , 0.76442945 ,
27- 0 ., -0.2933326 , 0.1375821 ,
28- 0 ., -0.1948287 , 0.06915811 ,
29- 0 ., -0.10384402 , 0.00915182 ,
30- 0 ., 0 ., 0 .,
31- 0.08062635 , 0.04127607 , 0.13416104 ,
32- 0.04643935 , 0.05767522 , 0.10299063 ,
33- 0 ., 0.06875312 , 0.09054535 ,
34- -0.04643935 , 0.05767522 , 0.10299063 ,
35- -0.08062635 , 0.04127607 , 0.13416104 ,
36- 0.31590518 , -0.2983375 , 0.2851074 ,
37- 0.13122973 , -0.28444737 , 0.23423915 ,
38- -0.13122973 , -0.28444737 , 0.23423915 ,
39- -0.31590518 , -0.2983375 , 0.2851074
40- );
4120
42- camera_matrix = (cv::Mat_<double >(3 , 3 ) <<
21+ if (!complex )
22+ {
23+ contour_indices = { 0 ,1 ,8 ,15 ,16 ,27 ,28 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,39 ,42 ,45 };
24+ mat3dcontour = (cv::Mat_<double >(NB_CONTOUR_POINTS_BASE, 3 ) <<
25+ 0.45517698 , -0.30089578 , 0.76442945 ,
26+ 0.44899884 , -0.16699584 , 0.765143 ,
27+ 0 ., 0.621079 , 0.28729478 ,
28+ -0.44899884 , -0.16699584 , 0.765143 ,
29+ -0.45517698 , -0.30089578 , 0.76442945 ,
30+ 0 ., -0.2933326 , 0.1375821 ,
31+ 0 ., -0.1948287 , 0.06915811 ,
32+ 0 ., -0.10384402 , 0.00915182 ,
33+ 0 ., 0 ., 0 .,
34+ 0.08062635 , 0.04127607 , 0.13416104 ,
35+ 0.04643935 , 0.05767522 , 0.10299063 ,
36+ 0 ., 0.06875312 , 0.09054535 ,
37+ -0.04643935 , 0.05767522 , 0.10299063 ,
38+ -0.08062635 , 0.04127607 , 0.13416104 ,
39+ 0.31590518 , -0.2983375 , 0.2851074 ,
40+ 0.13122973 , -0.28444737 , 0.23423915 ,
41+ -0.13122973 , -0.28444737 , 0.23423915 ,
42+ -0.31590518 , -0.2983375 , 0.2851074
43+ );
44+ }
45+ else
46+ {
47+ contour_indices = { 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 ,27 ,28 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,39 ,42 ,45 };
48+
49+ landmark_points_buffer = cv::Mat (contour_indices.size (), 1 , CV_32FC2);
50+
51+ mat3dcontour = (cv::Mat_<double >(contour_indices.size (), 3 ) <<
52+ 0.45517698 , -0.30089578 , 0.76442945 ,
53+ 0.44899884 , -0.16699584 , 0.76514298 ,
54+ 0.43743154 , -0.02265548 , 0.73926717 ,
55+ 0.41503343 , 0.08894145 , 0.74794745 ,
56+ 0.38912359 , 0.23238003 , 0.70478839 ,
57+ 0.3346301 , 0.36126539 , 0.61558759 ,
58+ 0.2637251 , 0.46000972 , 0.49147922 ,
59+ 0.16241622 , 0.55803716 , 0.33944517 ,
60+ 0 ., 0.62107903 , 0.28729478 ,
61+ -0.16241622 , 0.55803716 , 0.33944517 ,
62+ -0.2637251 , 0.46000972 , 0.49147922 ,
63+ -0.3346301 , 0.36126539 , 0.61558759 ,
64+ -0.38912359 , 0.23238003 , 0.70478839 ,
65+ -0.41503343 , 0.08894145 , 0.74794745 ,
66+ -0.43743154 , -0.02265548 , 0.73926717 ,
67+ -0.44899884 , -0.16699584 , 0.76514298 ,
68+ 0 ., -0.29333261 , 0.13758209 ,
69+ 0 ., -0.1948287 , 0.06915811 ,
70+ 0 ., -0.10384402 , 0.00915182 ,
71+ 0 ., 0 ., 0 .,
72+ 0.08062635 , 0.04127607 , 0.13416104 ,
73+ 0.04643935 , 0.05767522 , 0.10299063 ,
74+ 0 ., 0.06875312 , 0.09054535 ,
75+ -0.04643935 , 0.05767522 , 0.10299063 ,
76+ -0.08062635 , 0.04127607 , 0.13416104 ,
77+ 0.31590518 , -0.29833749 , 0.2851074 ,
78+ 0.13122973 , -0.28444737 , 0.23423915 ,
79+ -0.13122973 , -0.28444737 , 0.23423915 ,
80+ -0.31590518 , -0.29833749 , 0.2851074
81+ );
82+ }
83+
84+ // Taken from
85+ // https://github.com/opentrack/opentrack/blob/3cc3ef246ad71c463c8952bcc96984b25d85b516/tracker-aruco/ftnoir_tracker_aruco.cpp#L193
86+ // Taking into account the camera FOV instead of assuming raw image dims is more clever and
87+ // will make the solver more camera-agnostic.
88+ float diag_fov = fov * TO_RAD;
89+
90+ // Get expressed in sensor-size units
91+
92+ double fov_w = 2 . * atan (tan (diag_fov / 2 .) / sqrt (1 . + height / (double )width * height / (double )width));
93+ double fov_h = 2 . * atan (tan (diag_fov / 2 .) / sqrt (1 . + width / (double )height * width / (double )height));
94+
95+ float i_height = .5 * height / (tan (.5 *fov_w));
96+ float i_width = .5 * width / (tan (.5 *fov_h));
97+
98+ /* camera_matrix = (cv::Mat_<double>(3, 3) <<
4399 height, 0, height / 2,
44100 0, height, width / 2,
45101 0, 0, 1
46- );
102+ );*/
103+
104+ camera_matrix = (cv::Mat_<double >(3 , 3 ) <<
105+ i_width, 0 , height / 2 ,
106+ 0 , i_height, width / 2 ,
107+ 0 , 0 , 1
108+ );
47109
48110 camera_distortion = (cv::Mat_<double >(4 , 1 ) << 0 , 0 , 0 , 0 );
111+
112+ if (complex ) std::cout << " Using complex solver" << std::endl;
49113}
50114
51115void PositionSolver::solve_rotation (FaceData* face_data)
52116{
53117 int contour_idx = 0 ;
54118 for (int j = 0 ; j < 2 ; j++)
55119 {
56- for (int i = 0 ; i < NB_CONTOUR_POINTS ; i++)
120+ for (int i = 0 ; i < contour_indices. size () ; i++)
57121 {
58122 contour_idx = contour_indices[i];
59123 landmark_points_buffer.at <float >(i, j) = (int )face_data->landmark_coords [2 * contour_idx + j];
@@ -63,23 +127,14 @@ void PositionSolver::solve_rotation(FaceData* face_data)
63127
64128 cv::Mat rvec (rv, true ), tvec (tv, true );
65129
66- /* solvePnP(mat3dcontour,
67- landmark_points_buffer,
68- this->camera_matrix,
69- this->camera_distortion,
70- rvec,
71- tvec,
72- true, //extrinsic guess
73- cv::SOLVEPNP_ITERATIVE
74- );*/
75130
76- solvePnP (mat3dcontour,
131+ solvePnP (mat3dcontour,
77132 landmark_points_buffer,
78133 this ->camera_matrix ,
79134 this ->camera_distortion ,
80135 rvec,
81136 tvec,
82- true , // extrinsic guess
137+ false , // extrinsic guess
83138 cv::SOLVEPNP_ITERATIVE
84139 );
85140
@@ -93,6 +148,8 @@ void PositionSolver::solve_rotation(FaceData* face_data)
93148 face_data->translation [i] = tvec.at <double >(i, 0 ) * 10 ;
94149 }
95150
151+ std::cout << face_data->to_string () << std::endl;
152+
96153 correct_rotation (*face_data);
97154
98155}
0 commit comments