-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathtest_eigen_basics.cpp
155 lines (133 loc) · 5.2 KB
/
test_eigen_basics.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// #include <iostream>
// int main(void){
// return (1);
// }
// This is for testing basic functions/datatypes in Eigen.
// 1. Datatype conversions between:
// OpenCV and Matrix3d/Vector3d/Isometry3d/Affine3d.
#include "my_slam/basics/eigen_funcs.h" // namespce my
using namespace std;
using namespace cv;
using namespace Eigen;
// tutorials:
// https://eigen.tuxfamily.org/dox/group__TutorialGeometry.html
void printRtT(Eigen::Matrix3d &Re, Eigen::Vector3d &te,
Eigen::Isometry3d &Te, Eigen::Affine3d &Te_affine);
void transRtFromCV2Eigen_good_method(const cv::Mat &R, const cv::Mat &t,
Eigen::Matrix3d &Re, Eigen::Vector3d &te,
Eigen::Isometry3d &Te, Eigen::Affine3d &Te_affine);
void transRtFromCV2Eigen_manually(const cv::Mat &R_vec, const cv::Mat &t,
Eigen::Matrix3d &Re, Eigen::Vector3d &te,
Eigen::Isometry3d &Te, Eigen::Affine3d &Te_affine);
void transRtFromCV2Eigen_copy_elements(const cv::Mat &R, const cv::Mat &t,
Eigen::Isometry3d &Te);
void notes_about_AngelAxis();
int main(void)
{
// Suppose I get camera pose from OpenCV.
cv::Mat t = (cv::Mat_<double>(3, 1) << 1, 2, 3);
cv::Mat R_vec = (cv::Mat_<double>(3, 1) << 0, 0.1, 0);
cv::Mat R;
cv::Rodrigues(R_vec, R);
// Print
cout << "Printing R and t in OpenCV mat format:" << endl;
cout << "t: " << t.t() << endl;
cout << "R: \n"
<< R << endl;
Eigen::Matrix3d Re;
Eigen::Vector3d te;
Eigen::Isometry3d Te;
Eigen::Affine3d Te_affine;
transRtFromCV2Eigen_good_method(R, t, Re, te, Te, Te_affine);
transRtFromCV2Eigen_manually(R_vec, t, Re, te, Te, Te_affine);
transRtFromCV2Eigen_copy_elements(R, t, Te);
return 1;
}
void printRtT(Eigen::Matrix3d &Re, Eigen::Vector3d &te,
Eigen::Isometry3d &Te, Eigen::Affine3d &Te_affine)
{
cout << endl;
cout << "--------------------------------------" << endl;
cout << "Print result after transforming from cv to Eigen:" << endl;
cout << "t:" << te.transpose() << endl;
cout << "R:\n"
<< Re << endl;
cout << "T:\n"
<< Te.matrix() << endl;
cout << "T_affine:\n"
<< Te_affine.matrix() << endl;
cout << "--------------------------------------" << endl;
}
void transRtFromCV2Eigen_good_method(const cv::Mat &R, const cv::Mat &t,
Eigen::Matrix3d &Re, Eigen::Vector3d &te,
Eigen::Isometry3d &Te, Eigen::Affine3d &Te_affine)
{
assert(R.rows == 3 && R.cols == 3);
typedef Eigen::Matrix<double, 3, 3, Eigen::RowMajor> RMatrix3d;
Re = RMatrix3d::Map(reinterpret_cast<const double *>(R.data));
te = Eigen::Vector3d::Map(reinterpret_cast<const double *>(t.data));
if (1)
{
Te.linear() = Re;
Te.translation() = te;
}
else
{ // or directly assign values
Te.linear() = RMatrix3d::Map(reinterpret_cast<const double *>(R.data));
Te.translation() = Eigen::Vector3d::Map(reinterpret_cast<const double *>(t.data));
}
Te_affine = Te.matrix();
// print result
printRtT(Re, te, Te, Te_affine);
}
void transRtFromCV2Eigen_manually(const cv::Mat &R_vec, const cv::Mat &t,
Eigen::Matrix3d &Re, Eigen::Vector3d &te,
Eigen::Isometry3d &Te, Eigen::Affine3d &Te_affine)
{
assert(R_vec.rows == 3 && R_vec.cols == 1);
// 1. convert te
te = Eigen::Vector3d(t.at<double>(0, 0), t.at<double>(1, 0), t.at<double>(2, 0));
// 2. convert Re
double xyz_euler_angles[3] = {
R_vec.at<double>(0, 0), R_vec.at<double>(1, 0), R_vec.at<double>(2, 0)};
Re = AngleAxisd(xyz_euler_angles[0], Vector3d::UnitX()) *
AngleAxisd(xyz_euler_angles[1], Vector3d::UnitY()) *
AngleAxisd(xyz_euler_angles[2], Vector3d::UnitZ()).toRotationMatrix();
// 3. convert Te
Te = Eigen::Isometry3d::Identity();
Te.rotate(Re).pretranslate(te);
// 4. convert Te_affine
Te_affine = Te.matrix();
// print result
printRtT(Re, te, Te, Te_affine);
}
cv::Mat convertRt2T(const cv::Mat &R, const cv::Mat &t)
{
cv::Mat T = (cv::Mat_<double>(4, 4) << R.at<double>(0, 0), R.at<double>(0, 1), R.at<double>(0, 2), t.at<double>(0, 0),
R.at<double>(1, 0), R.at<double>(1, 1), R.at<double>(1, 2), t.at<double>(1, 0),
R.at<double>(2, 0), R.at<double>(2, 1), R.at<double>(2, 2), t.at<double>(2, 0),
0, 0, 0, 1);
return T;
}
void transRtFromCV2Eigen_copy_elements(const cv::Mat &R, const cv::Mat &t,
Eigen::Isometry3d &Te)
{
cv::Mat T_cv2 = convertRt2T(R, t);
for (int row = 0; row < 4; ++row)
for (int col = 0; col < 4; ++col)
Te.matrix()(row, col) = T_cv2.at<double>(row, col);
cout << "\nT in eigen:\n"
<< Te.matrix() << endl;
}
void notes_about_AngelAxis()
{
/*
Correct:
Matrix3f m;
m = AngleAxisf(1.0, Vector3f::UnitY());
Correct:
Matrix3f m=AngleAxisf(1.0, Vector3f::UnitY()).toRotationMatrix();
Wrong:
Matrix3f m=AngleAxisf(1.0, Vector3f::UnitY());
*/
}