如何从 ML Kit 人脸标志点估计人脸姿势
Posted
技术标签:
【中文标题】如何从 ML Kit 人脸标志点估计人脸姿势【英文标题】:How to estimate face pose from ML Kit face landmark points 【发布时间】:2019-08-23 05:27:30 【问题描述】:我在 ios 上使用 Firebase ML Kit 来检测人脸。虽然它提供了欧拉 Y 角和 Z 角,但它不提供欧拉 X 角(螺距)。所以我想尝试使用 OpenCV solvePnp 计算音高,如下所述: https://www.learnopencv.com/head-pose-estimation-using-opencv-and-dlib/#code
这是我的 Objective C 函数:
+(void) estimatePose:(FIRVisionFace *)face imgSize:(CGSize)imgSize
// Contour legend: https://firebase.google.com/docs/ml-kit/images/examples/face_contours.svg
FIRVisionFaceContour* faceOval = [face contourOfType:FIRFaceContourTypeFace];
FIRVisionFaceContour* leftEyeContour = [face contourOfType:FIRFaceContourTypeLeftEye];
FIRVisionFaceContour* rightEyeContour = [face contourOfType:FIRFaceContourTypeRightEye];
FIRVisionFaceContour* noseBridge = [face contourOfType:FIRFaceContourTypeNoseBridge];
FIRVisionFaceContour* upperLipTop = [face contourOfType:FIRFaceContourTypeUpperLipTop];
FIRVisionPoint* chin = faceOval.points[18];
FIRVisionPoint* leftEyeLeftCorner = leftEyeContour.points[0];
FIRVisionPoint* rightEyeRightCorner = rightEyeContour.points[8];
FIRVisionPoint* noseTip = noseBridge.points[1];
FIRVisionPoint* leftMouthCorner = upperLipTop.points[0];
FIRVisionPoint* rightMouthCorner = upperLipTop.points[10];
// 2D/3D model points using https://www.learnopencv.com/head-pose-estimation-using-opencv-and-dlib/#code
image_points.push_back( cv::Point2d(noseTip.x.doubleValue, noseTip.y.doubleValue) ); // Nose tip
image_points.push_back( cv::Point2d(chin.x.doubleValue, chin.y.doubleValue) ); // Chin
image_points.push_back( cv::Point2d(leftEyeLeftCorner.x.doubleValue, leftEyeLeftCorner.y.doubleValue) ); // Left eye left corner
image_points.push_back( cv::Point2d(rightEyeRightCorner.x.doubleValue, rightEyeRightCorner.y.doubleValue) ); // Right eye right corner
image_points.push_back( cv::Point2d(leftMouthCorner.x.doubleValue, leftMouthCorner.y.doubleValue) ); // Left Mouth corner
image_points.push_back( cv::Point2d(rightMouthCorner.x.doubleValue, rightMouthCorner.y.doubleValue) ); // Right mouth corner
model_points.push_back(cv::Point3d(0.0f, 0.0f, 0.0f)); // Nose tip
model_points.push_back(cv::Point3d(0.0f, -330.0f, -65.0f)); // Chin
model_points.push_back(cv::Point3d(-225.0f, 170.0f, -135.0f)); // Left eye left corner
model_points.push_back(cv::Point3d(225.0f, 170.0f, -135.0f)); // Right eye right corner
model_points.push_back(cv::Point3d(-150.0f, -150.0f, -125.0f)); // Left Mouth corner
model_points.push_back(cv::Point3d(150.0f, -150.0f, -125.0f)); // Right mouth corner
double focal_length = imgSize.width; // Approximate focal length.
cv::Point2d center = cv::Point2d(imgSize.width / 2, imgSize.height / 2);
cv::Mat camera_matrix = (cv::Mat_<double>(3,3) << focal_length, 0, center.x, 0 , focal_length, center.y, 0, 0, 1);
cv::Mat dist_coeffs = cv::Mat::zeros(4,1,cv::DataType<double>::type); // Assuming no lens distortion
// Output rotation and translation
cv::Mat rotation_vector; // Rotation in axis-angle form
cv::Mat translation_vector;
// Solve for pose
cv::solvePnP(model_points, image_points, camera_matrix, dist_coeffs, rotation_vector, translation_vector);
NSLog(@"Rotation Vector %f %f %f", rotation_vector.at<float>(0), rotation_vector.at<float>(1), rotation_vector.at<float>(2));
函数末尾的 print 语句正在为大部分笔直的摆脸产生不切实际的值,例如:
Rotation Vector 430085088834445557973284941130104832.000000 -2.169656 -37005999085886043916656699445870592.000000
Rotation Vector -31942776355636779193640943616.000000 -2.163979 51918482290645906067188728866013184.000000
我做错了什么?
【问题讨论】:
【参考方案1】:问题在于日志语句。它需要打印双精度而不是浮点数:
NSLog(@"Rotation Vector %f %f %f", rotation_vector.at<double>(0), rotation_vector.at<double>(1), rotation_vector.at<double>(2));
另外,旋转向量不是欧拉角。需要转换:
http://answers.opencv.org/question/16796/computing-attituderoll-pitch-yaw-from-solvepnp/?answer=52913#post-id-52913
【讨论】:
嗨 Jacob,我有兴趣将 EulerX 检测添加到 ML Kit Vision 的颤振库中。您的解决方案效果如何?以上是关于如何从 ML Kit 人脸标志点估计人脸姿势的主要内容,如果未能解决你的问题,请参考以下文章
如何避免在 firebase ML Kit 的人脸检测 API 中捕获模糊图像
如何在 Firebase ML kit Android 中正确绘制检测到的人脸边界框?
使用 CameraView 在 Android 上使用 ML Kit 检测人脸