三维视觉
Rodrigues vector, 旋转矩阵与四元数相互转换
#include <opencv2/core/core.hpp>
#include <opencv2/calib3d/calib3d.hpp>
void mat2quat(cv::Mat R, double Q[])
{
double trace = R.at<double>(0,0) + R.at<double>(1,1) + R.at<double>(2,2);
if (trace > 0.0)
{
double s = sqrt(trace + 1.0);
Q[3] = (s * 0.5);
s = 0.5 / s;
Q[0] = ((R.at<double>(2,1) - R.at<double>(1,2)) * s);
Q[1] = ((R.at<double>(0,2) - R.at<double>(2,0)) * s);
Q[2] = ((R.at<double>(1,0) - R.at<double>(0,1)) * s);
}
else
{
int i = R.at<double>(0,0) < R.at<double>(1,1) ? (R.at<double>(1,1) < R.at<double>(2,2) ? 2 : 1) : (R.at<double>(0,0) < R.at<double>(2,2) ? 2 : 0);
int j = (i + 1) % 3;
int k = (i + 2) % 3;
double s = sqrt(R.at<double>(i, i) - R.at<double>(j,j) - R.at<double>(k,k) + 1.0);
Q[i] = s * 0.5;
s = 0.5 / s;
Q[3] = (R.at<double>(k,j) - R.at<double>(j,k)) * s;
Q[j] = (R.at<double>(j,i) + R.at<double>(i,j)) * s;
Q[k] = (R.at<double>(k,i) + R.at<double>(i,k)) * s;
}
}
void quat2mat(double *q2, cv::Mat &rot_mat) {
double q[4];
q[0] = q2[3];
q[1] = q2[0];
q[2] = q2[1];
q[3] = q2[2];
// double *q = q2;
double x[3][3];
x[0][0] = 1 - 2 * (q[2]*q[2] + q[3] * q[3]);
x[0][1] = 2 * (q[1] * q[2] - q[0]*q[3]);
x[0][2] = 2 * (q[1] * q[3] + q[0] * q[2]);
x[1][0] = 2 * (q[1] * q[2] + q[0] * q[3]);
x[1][1] = 1 - 2 *(q[1] * q[1] + q[3] * q[3]);
x[1][2] = 2 * (q[2] * q[3] - q[0] * q[1]);
x[2][0] = 2 * (q[1] * q[3] - q[0] * q[2]);
x[2][1] = 2 * (q[2] * q[3] + q[0] * q[1]);
x[2][2] = 1 - 2 * (q[1] * q[1] + q[2] * q[2]);
rot_mat = cv::Mat(3, 3, CV_64F, x);
std::cout << rot_mat << std::endl;
}
int rotation_main() {
double r_vec[3] = {0.35710906, -2.29245728, -0.60095994};
cv::Mat rot_vec(3, 1, CV_64F, r_vec);
cv::Mat rot_mat;
cv::Rodrigues(rot_vec, rot_mat);
std::cout<<rot_mat<<std::endl;
double q[4];
mat2quat(rot_mat, q);
cv::Mat new_mat;
quat2mat(q, new_mat);
return 0;
}
int main() {
rotation_main();
return 0;
}
最后更新于