【问题标题】:Detection of head nod pose from pitch angle从俯仰角检测头部点头姿势
【发布时间】:2018-04-09 20:32:06
【问题描述】:

我正在制作一个 Android 应用程序,该应用程序将通过点头姿势检测驾驶员的疲劳程度。

What I did:

  1. 我使用 dlib 库从图像中检测到 68 个面部标志。
  2. 使用solvePnP 找出旋转矩阵,从该矩阵中我得到滚动角、俯仰角和偏航角。 现在,我必须从俯仰角度检测头部点头。

My Problem:

  1. 如何设置阈值,使低于或高于阈值的角度都可以说是点头?
  2. 它会产生一些负角。 3 维轴上的负角是什么意思?

我的代码:

 void getEulerAngles(Mat &rotCamerMatrix,Vec3d &eulerAngles)
{
     Mat cameraMatrix,rotMatrix,transVect,rotMatrixX,rotMatrixY,rotMatrixZ;
     double* _r = rotCamerMatrix.ptr<double>();
     double projMatrix[12] = {_r[0],_r[1],_r[2],0,
                  _r[3],_r[4],_r[5],0,
                  _r[6],_r[7],_r[8],0};

      decomposeProjectionMatrix( Mat(3,4,CV_64FC1,projMatrix),
                       cameraMatrix,
                       rotMatrix,
                       transVect,
                       rotMatrixX,
                       rotMatrixY,
                       rotMatrixZ,
                       eulerAngles);

 }
int renderToMat(std::vector<full_object_detection>& dets, Mat& dst)
{
     Scalar color;
     std::vector<cv::Point2d> image_points;
     std::vector<cv::Point3d> model_points;
     string disp;

     int sz = 3,l;
     color = Scalar(0,255,0);
     double p1,p2,p3,leftear,rightear,ear=0,yawn=0.00,yaw=0.00,pitch=0.00,roll=0.00;
     l=dets.size();
     //I am calculating only for one face.. so assuming l=1
     for(unsigned long idx = 0; idx < l; idx++)
     {
          image_points.push_back( 
          Point2d(dets[idx].part(30).x(),dets[idx].part(30).x() ) );
          image_points.push_back(Point2d(dets[idx].part(8).x(),dets[idx].part(8).x() ) );
          image_points.push_back(Point2d(dets[idx].part(36).x(),dets[idx].part(36).x() ) );
          image_points.push_back(Point2d(dets[idx].part(45).x(),dets[idx].part(45).x() ) );
          image_points.push_back(Point2d(dets[idx].part(48).x(),dets[idx].part(48).x() ) );
          image_points.push_back(Point2d(dets[idx].part(54).x(),dets[idx].part(54).x() ) );
     }
     double focal_length = dst.cols;
     Point2d center = cv::Point2d(dst.cols/2.00,dst.rows/2.00);
     cv::Mat camera_matrix = (cv::Mat_<double>(3.00,3.00) << 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);
     cv::Mat rotation_vector; //s Rotation in axis-angle form
     cv::Mat translation_vector;
     cv::Mat rotCamerMatrix1;

     if(l!=0)
     {
          model_points.push_back(cv::Point3d(0.0f, 0.0f, 0.0f));
          model_points.push_back(cv::Point3d(0.0f, -330.0f, -65.0f));
          model_points.push_back(cv::Point3d(-225.0f, 170.0f, -135.0f));
          model_points.push_back(cv::Point3d(225.0f, 170.0f, -135.0f));
          model_points.push_back(cv::Point3d(-150.0f, -150.0f, -125.0f));
          model_points.push_back(cv::Point3d(150.0f, -150.0f, -125.0f));
          cv::solvePnP(model_points, image_points, camera_matrix, dist_coeffs,rotation_vector, translation_vector);
          Rodrigues(rotation_vector,rotCamerMatrix1);
          Vec3d eulerAngles;
          getEulerAngles(rotCamerMatrix1,eulerAngles);

          yaw   = eulerAngles[1];
          pitch = eulerAngles[0];
          roll  = eulerAngles[2];
         /*My problem begins here. I don't know how to set a threshold value for pitch so that I can say a value below or 
above the pitch is a head nod!*/

     }
     return 0;
}

【问题讨论】:

    标签: c++ opencv math image-processing linear-algebra


    【解决方案1】:

    首先,您必须了解 3D 环境中如何使用 3 个角度。基本上,它们在 3D 空间中相对于原点旋转对象(原点可以根据上下文而变化),但是如何应用 3 个角度?

    这个问题可以表达为:他们以什么顺序旋转对象。如果您应用偏航,然后俯仰然后滚动它可能会给您一个不同的对象方向,如果您以相反的顺序执行它。话虽如此,您必须了解这些值代表什么,才能了解如何处理它们。

    现在,你问什么是一个好的阈值,这取决于。什么?好吧,按照它们的应用顺序。例如,如果您首先应用 45 度的俯仰,使其向下看,然后应用滚动 180 度,然后它正在向上看,因此定义阈值有点困难。

    由于您有模型点,您可以创建一个 3D 旋转矩阵并以不同的俯仰角将其应用于它们(其余角度将为 0,因此此处的顺序并不重要)并可视化它们并选择你考虑的一个是点头。这有点主观,所以你应该是这样做的人。

    现在,第二个问题。答案是,这取决于。这次是什么?你可能会问。很简单,你的系统是左撇子还是右撇子?一种是顺时针旋转,另一种是逆时针旋转,负号改变方向。因此,在左手系统中,它将是顺时针方向,而负号将是逆时针方向。右手系为逆时针方向,负号为顺时针方向。

    作为建议,您可以创建一个向量 (0,0,-1),假设您的 z 轴向后看。然后对其应用旋转并将其投影到平行于 z 轴的 2D 平面上,这里取矢量的尖端,看看这里的角度是多少。这样你就可以确定你得到了什么。

    【讨论】:

      猜你喜欢
      • 2021-02-17
      • 2020-10-31
      • 1970-01-01
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      相关资源
      最近更新 更多