Dlib C++ может очень хорошо обнаруживать ориентиры и оценивать позу лица. Однако, как я могу получить направление осей 3D-координат (x, y, z) позы головы?
Как получить 3D-координатные оси оценки позы головы в Dlib C++
comment
На этот вопрос уже есть принятый ответ. Тем не менее, просто для справки в будущем, на эту тему также есть отличный пост в блоге: learnopencv.com/head-pose-estimation-using-opencv-and-dlib
- person Luiz Vieira   schedule 05.01.2017
Ответы (1)
Я также столкнулся с той же проблемой некоторое время назад, искал и нашел 1-2 полезных сообщения в блоге, это link даст вам обзор задействованных методов. Если вам нужно вычислить только 3D-позу в десятичных разрядах, вы можете пропустить часть рендеринга OpenGL. , Однако, если вы хотите визуально получить обратную связь, вы также можете попробовать OpenGL, но я бы посоветовал вам игнорировать часть OpenGL как новичку, поэтому самый маленький фрагмент рабочего кода, извлеченный из github будет выглядеть примерно так:
// Reading image using OpenCV, you may use dlib as well.
cv::Mat img = cv::imread(imagePath);
std::vector<double> rv(3), tv(3);
cv::Mat rvec(rv),tvec(tv);
cv::Vec3d eav;
// Labelling the 3D Points derived from a 3D model of human face.
// You may replace these points as per your custom 3D head model if any
std::vector<cv::Point3f > modelPoints;
modelPoints.push_back(cv::Point3f(2.37427,110.322,21.7776)); // l eye (v 314)
modelPoints.push_back(cv::Point3f(70.0602,109.898,20.8234)); // r eye (v 0)
modelPoints.push_back(cv::Point3f(36.8301,78.3185,52.0345)); //nose (v 1879)
modelPoints.push_back(cv::Point3f(14.8498,51.0115,30.2378)); // l mouth (v 1502)
modelPoints.push_back(cv::Point3f(58.1825,51.0115,29.6224)); // r mouth (v 695)
modelPoints.push_back(cv::Point3f(-61.8886f,127.797,-89.4523f)); // l ear (v 2011)
modelPoints.push_back(cv::Point3f(127.603,126.9,-83.9129f)); // r ear (v 1138)
// labelling the position of corresponding feature points on the input image.
std::vector<cv::Point2f> srcImagePoints = {cv::Point2f(442, 442), // left eye
cv::Point2f(529, 426), // right eye
cv::Point2f(501, 479), // nose
cv::Point2f(469, 534), //left lip corner
cv::Point2f(538, 521), // right lip corner
cv::Point2f(349, 457), // left ear
cv::Point2f(578, 415) // right ear};
cv::Mat ip(srcImagePoints);
cv::Mat op = cv::Mat(modelPoints);
cv::Scalar m = mean(cv::Mat(modelPoints));
rvec = cv::Mat(rv);
double _d[9] = {1,0,0,
0,-1,0,
0,0,-1};
Rodrigues(cv::Mat(3,3,CV_64FC1,_d),rvec);
tv[0]=0;tv[1]=0;tv[2]=1;
tvec = cv::Mat(tv);
double max_d = MAX(img.rows,img.cols);
double _cm[9] = {max_d, 0, (double)img.cols/2.0,
0 , max_d, (double)img.rows/2.0,
0 , 0, 1.0};
cv::Mat camMatrix = cv::Mat(3,3,CV_64FC1, _cm);
double _dc[] = {0,0,0,0};
solvePnP(op,ip,camMatrix,cv::Mat(1,4,CV_64FC1,_dc),rvec,tvec,false,CV_EPNP);
double rot[9] = {0};
cv::Mat rotM(3,3,CV_64FC1,rot);
Rodrigues(rvec,rotM);
double* _r = rotM.ptr<double>();
printf("rotation mat: \n %.3f %.3f %.3f\n%.3f %.3f %.3f\n%.3f %.3f %.3f\n",
_r[0],_r[1],_r[2],_r[3],_r[4],_r[5],_r[6],_r[7],_r[8]);
printf("trans vec: \n %.3f %.3f %.3f\n",tv[0],tv[1],tv[2]);
double _pm[12] = {_r[0],_r[1],_r[2],tv[0],
_r[3],_r[4],_r[5],tv[1],
_r[6],_r[7],_r[8],tv[2]};
cv::Mat tmp,tmp1,tmp2,tmp3,tmp4,tmp5;
cv::decomposeProjectionMatrix(cv::Mat(3,4,CV_64FC1,_pm),tmp,tmp1,tmp2,tmp3,tmp4,tmp5,eav);
printf("Face Rotation Angle: %.5f %.5f %.5f\n",eav[0],eav[1],eav[2]);
Вывод:
**X** **Y** **Z**
Face Rotation Angle: 171.44027 -8.72583 -9.90596
person
ZdaR
schedule
13.04.2016
Я благодарен за вашу помощь, я попробую этот код сегодня вечером: D
- person Rain Maker; 13.04.2016
Я пробую ваше решение, но я застрял на этапе получения точечных положений глаз, носа,... из 3D-модели, предоставленной dlib по ссылке: sourceforge.net/projects/dclib/files/dlib/v18.10/. Файл .dat действительно универсальный. Я пытался изменить расширение файла, чтобы прочитать его из некоторых 3D-программ, но бесполезно. Есть ли у вас какие-либо предложения?
- person Rain Maker; 14.04.2016
Вам не нужно переписывать эти 3D-точки, вам просто нужно соответствующим образом обновить
srcImagePoints
.
- person ZdaR; 15.04.2016
Привет, я пробую ваше решение, как вы говорите, я должен поместить соответствующие точки в модель, чтобы сопоставить их с 3D-моделью. Но КАК данный файл shape_predictor_68_face_landmarks.dat помечает точки? Их 68, но, конечно, нам нужно получить правильные, чтобы поместить их в srcImagePoints. Я пытался искать какие-то документы, но не нашел ничего полезного, какие-нибудь предложения по этому поводу?
- person fiipi; 14.07.2016
@ZdaR: я пробую это решение, и оно, кажется, работает. Я хочу немного изменить использование, имея исходную позу, с которой будут сравниваться все остальные позы (я хочу знать, переместился ли объект из своего исходного положения, и если да, вычислить это изменение). Можно ли просто вычесть исходный угол поворота из текущего угла поворота? (То же самое с переводами?) Спасибо за помощь.
- person Irisciences; 26.06.2017
@Irisciences для части перевода это сработает нормально, но я не уверен насчет части вращения, однако вы можете попробовать и посмотреть, работает ли она?
- person ZdaR; 26.06.2017