27
#ifndef OPENCV_CORE_QUATERNION_INL_HPP
28
#define OPENCV_CORE_QUATERNION_INL_HPP
30
#ifndef OPENCV_CORE_QUATERNION_HPP
31
#erorr This is not a standalone header. Include quaternion.hpp instead.
40Quat<T>::Quat() : w(0), x(0), y(0), z(0) {}
43Quat<T>::Quat(
const
Vec<T, 4> &coeff):w(coeff[0]), x(coeff[1]), y(coeff[2]), z(coeff[3]){}
46Quat<T>::Quat(
const
T qw,
const
T qx,
const
T qy,
const
T qz):w(qw), x(qx), y(qy), z(qz){}
49Quat<T> Quat<T>::createFromAngleAxis(
const
T angle,
const
Vec<T, 3> &axis)
53
if
(vNorm < CV_QUAT_EPS)
55
CV_Error(Error::StsBadArg,
"this quaternion does not represent a rotation");
57
const
T angle_half = angle * 0.5;
59
const
T sin_v =
std::sin(angle_half);
60
const
T sin_norm = sin_v / vNorm;
61
x = sin_norm * axis[0];
62
y = sin_norm * axis[1];
63
z = sin_norm * axis[2];
64
return
Quat<T>(w, x, y, z);
68Quat<T> Quat<T>::createFromRotMat(InputArray _R)
71
if
(_R.rows() != 3 || _R.cols() != 3)
73
CV_Error(Error::StsBadArg,
"Cannot convert matrix to quaternion: rotation matrix should be a 3x3 matrix");
79
T
trace
= R(0, 0) + R(1, 1) + R(2, 2);
83
x = (R(1, 2) - R(2, 1)) / S;
84
y = (R(2, 0) - R(0, 2)) / S;
85
z = (R(0, 1) - R(1, 0)) / S;
88
else
if
(R(0, 0) > R(1, 1) && R(0, 0) > R(2, 2))
91
S =
std::sqrt(1.0 + R(0, 0) - R(1, 1) - R(2, 2)) * 2;
93
y = -(R(1, 0) + R(0, 1)) / S;
94
z = -(R(0, 2) + R(2, 0)) / S;
95
w = (R(1, 2) - R(2, 1)) / S;
97
else
if
(R(1, 1) > R(2, 2))
99
S =
std::sqrt(1.0 - R(0, 0) + R(1, 1) - R(2, 2)) * 2;
100
x = (R(0, 1) + R(1, 0)) / S;
102
z = (R(1, 2) + R(2, 1)) / S;
103
w = (R(0, 2) - R(2, 0)) / S;
107
S =
std::sqrt(1.0 - R(0, 0) - R(1, 1) + R(2, 2)) * 2;
108
x = (R(0, 2) + R(2, 0)) / S;
109
y = (R(1, 2) + R(2, 1)) / S;
111
w = -(R(0, 1) - R(1, 0)) / S;
113
return
Quat<T> (w, x, y, z);
116
template
<
typename
T>
117Quat<T> Quat<T>::createFromRvec(InputArray _rvec)
119
if
(!((_rvec.cols() == 1 && _rvec.rows() == 3) || (_rvec.cols() == 3 && _rvec.rows() == 1))) {
120
CV_Error(Error::StsBadArg,
"Cannot convert rotation vector to quaternion: The length of rotation vector should be 3");
125
if
(
abs(psi) < CV_QUAT_EPS) {
126
return
Quat<T> (1, 0, 0, 0);
128
Vec<T, 3> axis = rvec / psi;
129
return
createFromAngleAxis(psi, axis);
132
template
<
typename
T>
135
return
Quat<T>(-w, -x, -y, -z);
139
template
<
typename
T>
140
inline
bool
Quat<T>::operator==(
const
Quat<T> &q)
const
142
return
(
abs(w - q.w) < CV_QUAT_EPS &&
abs(x - q.x) < CV_QUAT_EPS &&
abs(y - q.y) < CV_QUAT_EPS &&
abs(z - q.z) < CV_QUAT_EPS);
145
template
<
typename
T>
148
return
Quat<T>(w + q1.w, x + q1.x, y + q1.y, z + q1.z);
151
template
<
typename
T>
152
inline
Quat<T>
operator+(
const
T a,
const
Quat<T>& q)
154
return
Quat<T>(q.w + a, q.x, q.y, q.z);
157
template
<
typename
T>
158
inline
Quat<T>
operator+(
const
Quat<T>& q,
const
T a)
160
return
Quat<T>(q.w + a, q.x, q.y, q.z);
163
template
<
typename
T>
164
inline
Quat<T>
operator-(
const
T a,
const
Quat<T>& q)
166
return
Quat<T>(a - q.w, -q.x, -q.y, -q.z);
169
template
<
typename
T>
170
inline
Quat<T>
operator-(
const
Quat<T>& q,
const
T a)
172
return
Quat<T>(q.w - a, q.x, q.y, q.z);
175
template
<
typename
T>
178
return
Quat<T>(w - q1.w, x - q1.x, y - q1.y, z - q1.z);
181
template
<
typename
T>
182
inline
Quat<T>& Quat<T>::operator+=(
const
Quat<T> &q1)
191
template
<
typename
T>
192
inline
Quat<T>& Quat<T>::operator-=(
const
Quat<T> &q1)
201
template
<
typename
T>
204
Vec<T, 4> q{w, x, y, z};
205
Vec<T, 4> q2{q1.w, q1.x, q1.y, q1.z};
206
return
Quat<T>(q * q2);
210
template
<
typename
T>
211Quat<T>
operator*(
const
Quat<T> &q1,
const
T a)
213
return
Quat<T>(a * q1.w, a * q1.x, a * q1.y, a * q1.z);
216
template
<
typename
T>
217Quat<T>
operator*(
const
T a,
const
Quat<T> &q1)
219
return
Quat<T>(a * q1.w, a * q1.x, a * q1.y, a * q1.z);
222
template
<
typename
T>
223
inline
Quat<T>& Quat<T>::operator*=(
const
Quat<T> &q1)
226
qw = w * q1.w - x * q1.x - y * q1.y - z * q1.z;
227
qx = x * q1.w + w * q1.x + y * q1.z - z * q1.y;
228
qy = y * q1.w + w * q1.y + z * q1.x - x * q1.z;
229
qz = z * q1.w + w * q1.z + x * q1.y - y * q1.x;
237
template
<
typename
T>
238
inline
Quat<T>& Quat<T>::operator/=(
const
Quat<T> &q1)
240
Quat<T> q(*
this
* q1.inv());
247
template
<
typename
T>
248Quat<T>& Quat<T>::operator*=(
const
T q1)
257
template
<
typename
T>
258
inline
Quat<T>& Quat<T>::operator/=(
const
T a)
260
const
T a_inv = 1.0 / a;
268
template
<
typename
T>
271
const
T a_inv = 1.0 / a;
272
return
Quat<T>(w * a_inv, x * a_inv, y * a_inv, z * a_inv);
275
template
<
typename
T>
278
return
*
this
* q.inv();
281
template
<
typename
T>
282
inline
const
T& Quat<T>::operator[](std::size_t n)
const
294
CV_Error(Error::StsOutOfRange,
"subscript exceeds the index range");
298
template
<
typename
T>
299
inline
T& Quat<T>::operator[](std::size_t n)
311
CV_Error(Error::StsOutOfRange,
"subscript exceeds the index range");
315
template
<
typename
T>
316std::ostream &
operator<<(std::ostream &os,
const
Quat<T> &q)
318
os <<
"Quat "
<< Vec<T, 4>{q.w, q.x, q.y, q.z};
322
template
<
typename
T>
323
inline
T Quat<T>::at(
size_t
index)
const
325
return
(*
this)[index];
328
template
<
typename
T>
329
inline
Quat<T> Quat<T>::conjugate()
const
331
return
Quat<T>(w, -x, -y, -z);
334
template
<
typename
T>
340
template
<
typename
T>
341Quat<T>
exp(
const
Quat<T> &q)
346
template
<
typename
T>
349
Vec<T, 3> v{x, y, z};
351
T k = normV < CV_QUAT_EPS ? 1 :
std::sin(normV) / normV;
352
return
std::exp(w) * Quat<T>(
std::cos(normV), v[0] * k, v[1] * k, v[2] * k);
355
template
<
typename
T>
358
return
q.log(assumeUnit);
361
template
<
typename
T>
364
Vec<T, 3> v{x, y, z};
368
T k = vNorm < CV_QUAT_EPS ? 1 :
std::acos(w) / vNorm;
369
return
Quat<T>(0, v[0] * k, v[1] * k, v[2] * k);
372
if
(qNorm < CV_QUAT_EPS)
374
CV_Error(Error::StsBadArg,
"Cannot apply this quaternion to log function: undefined");
376
T k = vNorm < CV_QUAT_EPS ? 1 :
std::acos(w / qNorm) / vNorm;
377
return
Quat<T>(
std::log(qNorm), v[0] * k, v[1] * k, v[2] *k);
380
template
<
typename
T>
381
inline
Quat<T> power(
const
Quat<T> &q1,
const
T alpha,
QuatAssumeType
assumeUnit)
383
return
q1.power(alpha, assumeUnit);
386
template
<
typename
T>
387
inline
Quat<T> Quat<T>::power(
const
T alpha,
QuatAssumeType
assumeUnit)
const
389
if
(x * x + y * y + z * z > CV_QUAT_EPS)
391
T angle = getAngle(assumeUnit);
392
Vec<T, 3> axis = getAxis(assumeUnit);
395
return
createFromAngleAxis(alpha * angle, axis);
397
return
std::pow(
norm(), alpha) * createFromAngleAxis(alpha * angle, axis);
406
template
<
typename
T>
409
return
q.sqrt(assumeUnit);
412
template
<
typename
T>
415
return
power(0.5, assumeUnit);
419
template
<
typename
T>
420
inline
Quat<T> power(
const
Quat<T> &p,
const
Quat<T> &q,
QuatAssumeType
assumeUnit)
422
return
p.power(q, assumeUnit);
426
template
<
typename
T>
427
inline
Quat<T> Quat<T>::power(
const
Quat<T> &q,
QuatAssumeType
assumeUnit)
const
432
template
<
typename
T>
433
inline
T Quat<T>::dot(Quat<T> q1)
const
435
return
w * q1.w + x * q1.x + y * q1.y + z * q1.z;
439
template
<
typename
T>
440
inline
Quat<T>
crossProduct(
const
Quat<T> &p,
const
Quat<T> &q)
442
return
p.crossProduct(q);
446
template
<
typename
T>
449
return
Quat<T> (0, y * q.z - z * q.y, z * q.x - x * q.z, x * q.y - q.x * y);
452
template
<
typename
T>
456
if
(normVal < CV_QUAT_EPS)
458
CV_Error(Error::StsBadArg,
"Cannot normalize this quaternion: the norm is too small.");
460
return
Quat<T>(w / normVal, x / normVal, y / normVal, z / normVal) ;
463
template
<
typename
T>
466
return
q.inv(assumeUnit);
470
template
<
typename
T>
477
T norm2 = dot(*
this);
478
if
(norm2 < CV_QUAT_EPS)
480
CV_Error(Error::StsBadArg,
"This quaternion do not have inverse quaternion");
485
template
<
typename
T>
486
inline
Quat<T>
sinh(
const
Quat<T> &q)
492
template
<
typename
T>
495
Vec<T, 3> v{x, y ,z};
502
template
<
typename
T>
503
inline
Quat<T>
cosh(
const
Quat<T> &q)
509
template
<
typename
T>
512
Vec<T, 3> v{x, y ,z};
518
template
<
typename
T>
519
inline
Quat<T>
tanh(
const
Quat<T> &q)
524
template
<
typename
T>
531
template
<
typename
T>
532
inline
Quat<T>
sin(
const
Quat<T> &q)
538
template
<
typename
T>
541
Vec<T, 3> v{x, y ,z};
547
template
<
typename
T>
548
inline
Quat<T>
cos(
const
Quat<T> &q)
553
template
<
typename
T>
556
Vec<T, 3> v{x, y ,z};
562
template
<
typename
T>
563
inline
Quat<T>
tan(
const
Quat<T> &q)
568
template
<
typename
T>
571
return
sin() *
cos().inv();
574
template
<
typename
T>
575
inline
Quat<T>
asinh(
const
Quat<T> &q)
580
template
<
typename
T>
583
return
cv::log(*
this
+
cv::power(*
this
* *
this
+ Quat<T>(1, 0, 0, 0), 0.5));
586
template
<
typename
T>
587
inline
Quat<T>
acosh(
const
Quat<T> &q)
592
template
<
typename
T>
598
template
<
typename
T>
599
inline
Quat<T>
atanh(
const
Quat<T> &q)
604
template
<
typename
T>
607
Quat<T> ident(1, 0, 0, 0);
608
Quat<T> c1 = (ident + *
this).
log();
609
Quat<T> c2 = (ident - *
this).
log();
610
return
0.5 * (c1 - c2);
613
template
<
typename
T>
614
inline
Quat<T>
asin(
const
Quat<T> &q)
619
template
<
typename
T>
622
Quat<T> v(0, x, y, z);
624
T k = vNorm < CV_QUAT_EPS ? 1 : vNorm;
625
return
-v / k * (*
this
* v / k).
asinh();
628
template
<
typename
T>
629
inline
Quat<T>
acos(
const
Quat<T> &q)
634
template
<
typename
T>
637
Quat<T> v(0, x, y, z);
639
T k = vNorm < CV_QUAT_EPS ? 1 : vNorm;
640
return
-v / k *
acosh();
643
template
<
typename
T>
644
inline
Quat<T>
atan(
const
Quat<T> &q)
649
template
<
typename
T>
652
Quat<T> v(0, x, y, z);
654
T k = vNorm < CV_QUAT_EPS ? 1 : vNorm;
655
return
-v / k * (*
this
* v / k).
atanh();
658
template
<
typename
T>
665
if
(
norm() < CV_QUAT_EPS)
667
CV_Error(Error::StsBadArg,
"This quaternion does not represent a rotation");
672
template
<
typename
T>
673
inline
Vec<T, 3> Quat<T>::getAxis(
QuatAssumeType
assumeUnit)
const
675
T angle = getAngle(assumeUnit);
676
const
T sin_v =
std::sin(angle * 0.5);
679
return
Vec<T, 3>{x, y, z} / sin_v;
681
return
Vec<T, 3> {x, y, z} / (
norm() * sin_v);
684
template
<
typename
T>
685Matx<T, 4, 4> Quat<T>::toRotMat4x4(
QuatAssumeType
assumeUnit)
const
687
T a = w, b = x, c = y, d = z;
697
1 - 2 * (c * c + d * d), 2 * (b * c - a * d) , 2 * (b * d + a * c) , 0,
698
2 * (b * c + a * d) , 1 - 2 * (b * b + d * d), 2 * (c * d - a * b) , 0,
699
2 * (b * d - a * c) , 2 * (c * d + a * b) , 1 - 2 * (b * b + c * c), 0,
705
template
<
typename
T>
706Matx<T, 3, 3> Quat<T>::toRotMat3x3(
QuatAssumeType
assumeUnit)
const
708
T a = w, b = x, c = y, d = z;
718
1 - 2 * (c * c + d * d), 2 * (b * c - a * d) , 2 * (b * d + a * c),
719
2 * (b * c + a * d) , 1 - 2 * (b * b + d * d), 2 * (c * d - a * b),
720
2 * (b * d - a * c) , 2 * (c * d + a * b) , 1 - 2 * (b * b + c * c)
725
template
<
typename
T>
728
T angle = getAngle(assumeUnit);
729
Vec<T, 3> axis = getAxis(assumeUnit);
733
template
<
typename
T>
734Vec<T, 4> Quat<T>::toVec()
const
736
return
Vec<T, 4>{w, x, y, z};
739
template
<
typename
T>
740Quat<T> Quat<T>::lerp(
const
Quat<T> &q0,
const
Quat<T> &q1,
const
T t)
742
return
(1 - t) * q0 + t * q1;
745
template
<
typename
T>
746Quat<T> Quat<T>::slerp(
const
Quat<T> &q0,
const
Quat<T> &q1,
const
T t,
QuatAssumeType
assumeUnit,
bool
directChange)
755
T cosTheta = v0.dot(v1);
756
constexpr
T DOT_THRESHOLD = 0.995;
757
if
(cosTheta > DOT_THRESHOLD)
762
if
(directChange && cosTheta < 0)
765
cosTheta = -cosTheta;
767
T sinTheta =
std::sqrt(1 - cosTheta * cosTheta);
768
T angle = atan2(sinTheta, cosTheta);
769
return
(
std::sin((1 - t) * angle) / (sinTheta) * v0 +
std::sin(t * angle) / (sinTheta) * v1).normalize();
773
template
<
typename
T>
774
inline
Quat<T> Quat<T>::nlerp(
const
Quat<T> &q0,
const
Quat<T> &q1,
const
T t,
QuatAssumeType
assumeUnit)
776
Quat<T> v0(q0), v1(q1);
783
return
((1 - t) * v0 + t * v1).normalize();
787
return
((1 - t) * v0 + t * v1).normalize();
791
template
<
typename
T>
792
inline
bool
Quat<T>::isNormal(T eps)
const
795
double
normVar =
norm();
796
if
((normVar > 1 - eps) && (normVar < 1 + eps))
801
template
<
typename
T>
802
inline
void
Quat<T>::assertNormal(T eps)
const
805
CV_Error(Error::StsBadArg,
"Quaternion should be normalized");
809
template
<
typename
T>
810
inline
Quat<T> Quat<T>::squad(
const
Quat<T> &q0,
const
Quat<T> &q1,
811
const
Quat<T> &q2,
const
Quat<T> &q3,
815
Quat<T> v0(q0), v1(q1), v2(q2), v3(q3);
824
Quat<T> c0 = slerp(v0, v3, t, assumeUnit, directChange);
825
Quat<T> c1 = slerp(v1, v2, t, assumeUnit, directChange);
826
return
slerp(c0, c1, 2 * t * (1 - t), assumeUnit, directChange);
829
template
<
typename
T>
830Quat<T> Quat<T>::interPoint(
const
Quat<T> &q0,
const
Quat<T> &q1,
833
Quat<T> v0(q0), v1(q1), v2(q2);
840
return
v1 *
cv::exp(-(
cv::log(v1.conjugate() * v0, assumeUnit) + (
cv::log(v1.conjugate() * v2, assumeUnit))) / 4);
843
template
<
typename
T>
844Quat<T> Quat<T>::spline(
const
Quat<T> &q0,
const
Quat<T> &q1,
const
Quat<T> &q2,
const
Quat<T> &q3,
const
T t,
QuatAssumeType
assumeUnit)
846
Quatd v0(q0), v1(q1), v2(q2), v3(q3);
855
std::vector<Quat<T>> vec{v0, v1, v2, v3};
856
for
(
size_t
i = 0; i < 3; ++i)
858
cosTheta = vec[i].dot(vec[i + 1]);
861
vec[i + 1] = -vec[i + 1];
871
template
<
typename
T>
static
872Quat<T> createFromAxisRot(
int
axis,
const
T theta)
875
return
Quat<T>::createFromXRot(theta);
877
return
Quat<T>::createFromYRot(theta);
879
return
Quat<T>::createFromZRot(theta);
883
inline
bool
isIntAngleType(QuatEnum::EulerAnglesType eulerAnglesType)
885
return
eulerAnglesType < QuatEnum::EXT_XYZ;
888
inline
bool
isTaitBryan(QuatEnum::EulerAnglesType eulerAnglesType)
890
return
eulerAnglesType/6 == 1 || eulerAnglesType/6 == 3;
894
template
<
typename
T>
895Quat<T> Quat<T>::createFromYRot(
const
T theta)
900
template
<
typename
T>
901Quat<T> Quat<T>::createFromXRot(
const
T theta){
905
template
<
typename
T>
906Quat<T> Quat<T>::createFromZRot(
const
T theta){
911
template
<
typename
T>
912Quat<T> Quat<T>::createFromEulerAngles(
const
Vec<T, 3> &angles, QuatEnum::EulerAnglesType eulerAnglesType) {
913
CV_Assert(eulerAnglesType < QuatEnum::EulerAnglesType::EULER_ANGLES_MAX_VALUE);
914
static
const
int
rotationAxis[24][3] = {
940
Quat<T> q1 = detail::createFromAxisRot(rotationAxis[eulerAnglesType][0], angles(0));
941
Quat<T> q2 = detail::createFromAxisRot(rotationAxis[eulerAnglesType][1], angles(1));
942
Quat<T> q3 = detail::createFromAxisRot(rotationAxis[eulerAnglesType][2], angles(2));
943
if
(detail::isIntAngleType(eulerAnglesType))
953
template
<
typename
T>
954Vec<T, 3> Quat<T>::toEulerAngles(QuatEnum::EulerAnglesType eulerAnglesType){
955
CV_Assert(eulerAnglesType < QuatEnum::EulerAnglesType::EULER_ANGLES_MAX_VALUE);
956
Matx33d R = toRotMat3x3();
962
R_0_0 = N_CONSTANTS, R_0_1, R_0_2,
966
static
const
T constants_[N_CONSTANTS] = {
971
static
const
int
rotationR_[24][12] = {
972
{+R_0_2, +R_1_0, +R_1_1, C_PI_2, +R_2_1, +R_1_1, -C_PI_2, -R_1_2, +R_2_2, +R_0_2, -R_0_1, +R_0_0},
973
{+R_0_1, -R_1_2, +R_2_2, -C_PI_2, +R_2_0, +R_2_2, C_PI_2, +R_2_1, +R_1_1, -R_0_1, +R_0_2, +R_0_0},
974
{+R_1_2, -R_0_1, +R_0_0, -C_PI_2, +R_0_1, +R_0_0, C_PI_2, +R_0_2, +R_2_2, -R_1_2, +R_1_0, +R_1_1},
975
{+R_1_0, +R_0_2, +R_2_2, C_PI_2, +R_0_2, +R_0_1, -C_PI_2, -R_2_0, +R_0_0, +R_1_0, -R_1_2, +R_1_1},
976
{+R_2_1, +R_1_0, +R_0_0, C_PI_2, +R_1_0, +R_0_0, -C_PI_2, -R_0_1, +R_1_1, +R_2_1, -R_2_0, +R_2_2},
977
{+R_2_0, -R_0_1, +R_1_1, -C_PI_2, +R_1_2, +R_1_1, C_PI_2, +R_1_0, +R_0_0, -R_2_0, +R_2_1, +R_2_2},
978
{+R_0_0, +R_2_1, +R_2_2, C_ZERO, +R_1_2, +R_1_1, C_PI, +R_1_0, -R_2_0, +R_0_0, +R_0_1, +R_0_2},
979
{+R_0_0, +R_2_1, +R_2_2, C_ZERO, -R_2_1, +R_2_2, C_PI, +R_2_0, +R_1_0, +R_0_0, +R_0_2, -R_0_1},
980
{+R_1_1, +R_0_2, +R_0_0, C_ZERO, -R_2_0, +R_0_0, C_PI, +R_0_1, +R_2_1, +R_1_1, +R_1_0, -R_1_2},
981
{+R_1_1, +R_0_2, +R_0_0, C_ZERO, +R_0_2, -R_0_0, C_PI, +R_2_1, -R_0_1, +R_1_1, +R_1_2, +R_1_0},
982
{+R_2_2, +R_1_0, +R_1_1, C_ZERO, +R_1_0, +R_0_0, C_PI, +R_0_2, -R_1_2, +R_2_2, +R_2_0, +R_2_1},
983
{+R_2_2, +R_1_0, +R_0_0, C_ZERO, +R_1_0, +R_0_0, C_PI, +R_1_2, +R_0_2, +R_2_2, +R_2_1, -R_2_0},
985
{+R_2_0, -C_PI_2, -R_0_1, +R_1_1, C_PI_2, +R_1_2, +R_1_1, +R_2_1, +R_2_2, -R_2_0, +R_1_0, +R_0_0},
986
{+R_1_0, C_PI_2, +R_0_2, +R_2_2, -C_PI_2, +R_0_2, +R_0_1, -R_1_2, +R_1_1, +R_1_0, -R_2_0, +R_0_0},
987
{+R_2_1, C_PI_2, +R_1_0, +R_0_0, -C_PI_2, +R_1_0, +R_0_0, -R_2_0, +R_2_2, +R_2_1, -R_0_1, +R_1_1},
988
{+R_0_2, -C_PI_2, -R_1_2, +R_2_2, C_PI_2, +R_2_0, +R_2_2, +R_0_2, +R_0_0, -R_0_1, +R_2_1, +R_1_1},
989
{+R_1_2, -C_PI_2, -R_0_1, +R_0_0, C_PI_2, +R_0_1, +R_0_0, +R_1_0, +R_1_1, -R_1_2, +R_0_2, +R_2_2},
990
{+R_0_2, C_PI_2, +R_1_0, +R_1_1, -C_PI_2, +R_2_1, +R_1_1, -R_0_1, +R_0_0, +R_0_2, -R_1_2, +R_2_2},
991
{+R_0_0, C_ZERO, +R_2_1, +R_2_2, C_PI, +R_1_2, +R_1_1, +R_0_1, +R_0_2, +R_0_0, +R_1_0, -R_2_0},
992
{+R_0_0, C_ZERO, +R_2_1, +R_2_2, C_PI, +R_2_1, +R_2_2, +R_0_2, -R_0_1, +R_0_0, +R_2_0, +R_1_0},
993
{+R_1_1, C_ZERO, +R_0_2, +R_0_0, C_PI, -R_2_0, +R_0_0, +R_1_0, -R_1_2, +R_1_1, +R_0_1, +R_2_1},
994
{+R_1_1, C_ZERO, +R_0_2, +R_0_0, C_PI, +R_0_2, -R_0_0, +R_1_2, +R_1_0, +R_1_1, +R_2_1, -R_0_1},
995
{+R_2_2, C_ZERO, +R_1_0, +R_1_1, C_PI, +R_1_0, +R_0_0, +R_2_0, +R_2_1, +R_2_2, +R_0_2, -R_1_2},
996
{+R_2_2, C_ZERO, +R_1_0, +R_0_0, C_PI, +R_1_0, +R_0_0, +R_2_1, -R_2_0, +R_2_2, +R_1_2, +R_0_2},
999
for
(
int
i = 0; i < 12; i++)
1001
int
id
= rotationR_[eulerAnglesType][i];
1004
if
(idx < N_CONSTANTS)
1006
value = constants_[idx];
1010
unsigned
r_idx = idx - N_CONSTANTS;
1012
value = R.val[r_idx];
1014
bool
isNegative =
id
< 0;
1017
rotationR[i] = value;
1020
if
(detail::isIntAngleType(eulerAnglesType))
1022
if
(
abs(rotationR[0] - 1) < CV_QUAT_CONVERT_THRESHOLD)
1024
CV_LOG_WARNING(NULL,
"Gimbal Lock occurs. Euler angles are non-unique, we set the third angle to 0");
1025
angles = {std::atan2(rotationR[1], rotationR[2]), rotationR[3], 0};
1028
else
if(
abs(rotationR[0] + 1) < CV_QUAT_CONVERT_THRESHOLD)
1030
CV_LOG_WARNING(NULL,
"Gimbal Lock occurs. Euler angles are non-unique, we set the third angle to 0");
1031
angles = {std::atan2(rotationR[4], rotationR[5]), rotationR[6], 0};
1037
if
(
abs(rotationR[0] - 1) < CV_QUAT_CONVERT_THRESHOLD)
1039
CV_LOG_WARNING(NULL,
"Gimbal Lock occurs. Euler angles are non-unique, we set the first angle to 0");
1040
angles = {0, rotationR[1], std::atan2(rotationR[2], rotationR[3])};
1043
else
if
(
abs(rotationR[0] + 1) < CV_QUAT_CONVERT_THRESHOLD)
1045
CV_LOG_WARNING(NULL,
"Gimbal Lock occurs. Euler angles are non-unique, we set the first angle to 0");
1046
angles = {0, rotationR[4], std::atan2(rotationR[5], rotationR[6])};
1051
angles(0) = std::atan2(rotationR[7], rotationR[8]);
1052
if
(detail::isTaitBryan(eulerAnglesType))
1056
angles(2) = std::atan2(rotationR[10], rotationR[11]);
CV_EXPORTS FileStorage & operator<<(FileStorage &fs, const String &str)
Writes string to a file storage.
CV_EXPORTS MatExpr abs(const Mat &m)
Calculates an absolute value of each matrix element.
CV_EXPORTS_W void sqrt(InputArray src, OutputArray dst)
Calculates a square root of array elements.
CV_EXPORTS_W void exp(InputArray src, OutputArray dst)
Calculates the exponent of every array element.
CV_EXPORTS_W double norm(InputArray src1, int normType=NORM_L2, InputArray mask=noArray())
Calculates the absolute norm of an array.
CV_EXPORTS_W void pow(InputArray src, double power, OutputArray dst)
Raises every array element to a power.
CV_EXPORTS_W Scalar trace(InputArray mtx)
Returns the trace of a matrix.
CV_EXPORTS_W void log(InputArray src, OutputArray dst)
Calculates the natural logarithm of every array element.
CV_EXPORTS_W void normalize(InputArray src, InputOutputArray dst, double alpha=1, double beta=0, int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray())
Normalizes the norm or value range of an array.
CV_INLINE v_reg< _Tp, n > operator*(const v_reg< _Tp, n > &a, const v_reg< _Tp, n > &b)
Multiply values
CV_INLINE v_reg< _Tp, n > operator+(const v_reg< _Tp, n > &a, const v_reg< _Tp, n > &b)
Add values
CV_INLINE v_reg< _Tp, n > operator/(const v_reg< _Tp, n > &a, const v_reg< _Tp, n > &b)
Divide values
CV_INLINE v_reg< _Tp, n > operator-(const v_reg< _Tp, n > &a, const v_reg< _Tp, n > &b)
Subtract values
softfloat abs(softfloat a)
Absolute value
Definition:
softfloat.hpp:444
#define CV_Error(code, msg)
Call the error handler.
Definition:
base.hpp:320
#define CV_Assert(expr)
Checks a condition at runtime and throws exception if it fails
Definition:
base.hpp:342
#define CV_DbgAssert(expr)
Definition:
base.hpp:375
Quat< T > tan(const Quat< T > &q)
Quat< T > asinh(const Quat< T > &q)
Quat< T > asin(const Quat< T > &q)
Quat< T > tanh(const Quat< T > &q)
Quat< T > crossProduct(const Quat< T > &p, const Quat< T > &q)
Quat< T > inv(const Quat< T > &q, QuatAssumeType assumeUnit=QUAT_ASSUME_NOT_UNIT)
Quat< T > acosh(const Quat< T > &q)
Quat< T > atanh(const Quat< T > &q)
Quat< T > cos(const Quat< T > &q)
Quat< T > sinh(const Quat< T > &q)
QuatAssumeType
Unit quaternion flag
Definition:
quaternion.hpp:39
Quat< T > cosh(const Quat< T > &q)
Quat< T > atan(const Quat< T > &q)
Quat< T > sin(const Quat< T > &q)
Quat< T > acos(const Quat< T > &q)
@ QUAT_ASSUME_NOT_UNIT
Definition:
quaternion.hpp:46
@ QUAT_ASSUME_UNIT
Definition:
quaternion.hpp:52
"black box" representation of the file storage associated with a file on disk.
Definition:
aruco.hpp:75
DualQuat< T > conjugate(const DualQuat< T > &dq)
Definition:
dualquaternion.inl.hpp:125
DualQuat< T > power(const DualQuat< T > &dq, const T t, QuatAssumeType assumeUnit=QUAT_ASSUME_NOT_UNIT)
Definition:
dualquaternion.inl.hpp:358
Definition:
traits.hpp:386