2017-10-28 18 views
0

頭のノーズ姿勢からのドライバーの疲労を検出するアンドロイドアプリケーションを作っています。ピッチ角からの頭のノーズ姿勢の検出

What I did:

  1. IはDLIBライブラリを使用して画像から顔の目印68を検出しました。
  2. solvePnPを使用して回転行列を求め、その行列からロール角、ピッチ角、ヨー角を得ました。 今、私はピッチ角からヘッドノードを検出する必要があります。閾値以下または以上の角度がヘッドNODとして言うことができるように閾値を設定する方法

My Problem:

  1. この結果、いくつかの負の角度が生じます。 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; 
} 

答えて

0

まず、あなたは、3Dのコンテキストで使用される3角であるかを理解する必要があります。基本的には、原点を基準にして3D空間内のオブジェクトを回転させます(原点は状況によって変わります)が、3つの角度はどのように適用されますか?

この質問は次のように表すことができます。どの順序でオブジェクトを回転させるか?ヨーイングを適用し、ピッチを合わせてロールすると、逆の順序で行うとオブジェクトの向きが異なることがあります。それを言って、あなたはそれらの価値観が何であるかを理解し、それらと何をするべきかを理解する必要があります。

ここで、どのようなしきい値になるのかよく分かりますが、それは依存しています。何の上に?まあ、それらが適用される順序で。たとえば、45度でピッチを適用して見下ろしてからロールを180度適用すると、ルックアップしているので、しきい値を定義するのは少し難しいです。

あなたはモデルポイントを持っているので、3D回転行列を作成し、異なるピッチ角でそれらを適用することができます(残りの角度は0になるため、ここでの順序は重要ではありません)あなたが考えているものはうなずきます。これはちょっと主観的なので、あなたはそれをやっているべきです。

今、2番目の質問です。もう一度答えは、それは異なります。今回は何ですか?あなたは求めるかもしれません。シンプル、あなたのシステムは左利きですか、右利きですか? 1つは回転が時計回りで、もう1つは反時計回りであることを意味し、負の符号は方向を変えます。したがって、左手系では時計回り、負号では反時計回りになります。右手系は反時計回り、負号は右回りになります。

あなたのz軸が後方を向いていると仮定して、ベクトル(0,0、-1)を作ることができます。次に、回転を適用して、z軸に平行な2D平面にプロジエクトします。ここでベクトルの先端を取って、ここで角度を確認します。このようにして、あなたは何を得ているのか確信しています。

関連する問題