6
2

クオータニオンからオイラー角に戻せるcv::Quatクラス

Posted at

はじめに

TL;DR

  • あんな、回転行列って6種類ぐらいあると言ったな、あれは嘘だ。
  • 回転角を計算する際に軸の順序を指定するオプションは存在しないと言ったな、あれは嘘だ。

OpenCVのAPIについて

回転角を計算する際に軸の順序を指定するオプションは存在しない

OpenCV 4.5.1から登場

6種類じゃきかなかった回転行列

前述したように、回転行列は回転軸の順序によって6種類存在する

  • が、cv::Quatd::toEulerAngleメンバ関数のドキュメントを読むと、引数として、回転軸の順序を指定するためにcv::QuatEnum::EulerAnglesType を指定するパラメタが存在し、このenumは、以下の24通り(!)存在する
    enum EulerAnglesType
    {
        INT_XYZ, ///< Intrinsic rotations with the Euler angles type X-Y-Z
        INT_XZY, ///< Intrinsic rotations with the Euler angles type X-Z-Y
        INT_YXZ, ///< Intrinsic rotations with the Euler angles type Y-X-Z
        INT_YZX, ///< Intrinsic rotations with the Euler angles type Y-Z-X
        INT_ZXY, ///< Intrinsic rotations with the Euler angles type Z-X-Y
        INT_ZYX, ///< Intrinsic rotations with the Euler angles type Z-Y-X
        INT_XYX, ///< Intrinsic rotations with the Euler angles type X-Y-X
        INT_XZX, ///< Intrinsic rotations with the Euler angles type X-Z-X
        INT_YXY, ///< Intrinsic rotations with the Euler angles type Y-X-Y
        INT_YZY, ///< Intrinsic rotations with the Euler angles type Y-Z-Y
        INT_ZXZ, ///< Intrinsic rotations with the Euler angles type Z-X-Z
        INT_ZYZ, ///< Intrinsic rotations with the Euler angles type Z-Y-Z

        EXT_XYZ, ///< Extrinsic rotations with the Euler angles type X-Y-Z
        EXT_XZY, ///< Extrinsic rotations with the Euler angles type X-Z-Y
        EXT_YXZ, ///< Extrinsic rotations with the Euler angles type Y-X-Z
        EXT_YZX, ///< Extrinsic rotations with the Euler angles type Y-Z-X
        EXT_ZXY, ///< Extrinsic rotations with the Euler angles type Z-X-Y
        EXT_ZYX, ///< Extrinsic rotations with the Euler angles type Z-Y-X
        EXT_XYX, ///< Extrinsic rotations with the Euler angles type X-Y-X
        EXT_XZX, ///< Extrinsic rotations with the Euler angles type X-Z-X
        EXT_YXY, ///< Extrinsic rotations with the Euler angles type Y-X-Y
        EXT_YZY, ///< Extrinsic rotations with the Euler angles type Y-Z-Y
        EXT_ZXZ, ///< Extrinsic rotations with the Euler angles type Z-X-Z
        EXT_ZYZ, ///< Extrinsic rotations with the Euler angles type Z-Y-Z
        #ifndef CV_DOXYGEN
            EULER_ANGLES_MAX_VALUE // 24だよっ!
        #endif
    };
  • INTEXTの接頭辞はそれぞれ回転軸の順序を逆順に並べ替えることに相当する
    • 例:2日目の記事ではXYZZ軸Y軸X軸の順に回転させる、と解説した。これはINT接頭辞がつく方の説明に相当する
    • EXT接頭辞がつくパターンはXYZX軸Y軸Z軸の順に回転させる、
  • また、2日目の記事では触れなかったINT_XYXなるパターンも存在する
    • これはどんな回転行列でも、回転軸2つの回転各を適切にとることで、XYXのように、3軸のうち2軸だけの回転だけで回転行列を表す組み合わせが存在する(ただし、その際2軸のうち1軸を2階適用する)
    • ここについては私も理解が不十分なので、詳細は割愛します
  • すくなくともOpenCVでの実装は、2日目の記事で紹介した範囲より、4倍広い範囲をカバーしているといえる

ジンバルロック

  • 2日目の記事で、用語の裏付けを取る余裕がなくて敢えて触れなかったのだが、

回転角は特定の条件下で回転角2つが混ざった状態でしか復元できなくなる。

  • この特定条件にはジンバルロック(Gimbal Lock) と名前が付いている
  • toEulerAnglesメンバ関数内ではジンバルロックが発生しているかチェックし、発生した場合にはコンソールに以下の警告メッセージが表示される
[ WARN:0@87.260] global quaternion.inl.hpp:1030 toEulerAngles Gimbal Lock occurs. Euler angles are non-unique, we set the third angle to 0
  • 余談ではあるがこのクラス、関数の存在に気づいたのはこのログメッセージがきっかけである

おわりに

  • 1日目の記事のみならず、2日目の記事にも嘘が存在していました。
  • しかも24日担当がギリギリになってしまいまいました。thpr。
  • 明日は25日目、hon_no_mushiさんの「OpenCV Advent Calendar 2023まとめ」です
6
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2