由旋轉矩陣計算尤拉角的方法
阿新 • • 發佈:2018-12-11
演算法一:直接法
- bool isRotationMatrix(cv::Mat &R)
- {
- cv::Mat R_t;
- cv::transpose(R,R_t);
- cv::Mat shouldBeIdentity=R_t*R;
- cv::Mat I = cv::Mat::eye(3,3,shouldBeIdentity.type());
- return norm(I,shouldBeIdentity)< 1e-6;
- }
- void getEulerAngles(cv::Mat matrix)
- {
- assert(isRotationMatrix(matrix));
- float sy=sqrt(matrix.at<double
>(0,0)*matrix.at<double>(0,0)+matrix.at<double>(1,0)*matrix.at<double>(1,0)); - bool singular = sy<1e-6;
- if(!singular)
- {
- theta_x=atan2(matrix.at<double>(2,1),matrix.at<double>(2,2));
- //theta_x= theta_x*180.0/3.1416 ;
- theta_y=atan2(-matrix.at<double>(2,0), sy);
- //theta_y= theta_y*180.0/3.1416 ;
- theta_z=atan2(matrix.at<double>(1,0), matrix.at<double>(0,0));
- //theta_z= theta_z*180.0/3.1416 ;
- }
- else
- {
- theta_x=atan2(-matrix.at<double>(1,2), matrix.at<double>(1,1));
- //theta_x= theta_x*180.0/3.1416 ;
- theta_y=atan2(-matrix.at<double>(2,0), sy);
- //theta_y= theta_y*180.0/3.1416 ;
- theta_z=0
; - //theta_z= theta_z*180.0/3.1416 ;
- }
- Debug("theta_x");
- Debug(theta_x);
- Debug("theta_y");
- Debug(theta_y);
- Debug("theta_z");
- Debug(theta_z);
- }
NOTE:需要判斷奇異性(singularity)!
演算法二:拆分法
- void getEulerAngles(cv::Mat &R,cv::Mat &t,cv::Mat &euler_angles)
- {
- cv::Mat camMatrix,rotMatrix,transVect,theta_x,theta_y,theta_z;
- cv::Mat rotation_vec;
- cv::Mat projMatrix = cv::Mat(3,4,CV_64FC1);
- //cv::Mat euler_angles = cv::Mat(3,1,CV_64FC1);
- cv::Mat out_intrinsics = cv::Mat(3,3,CV_64FC1);
- cv::Mat out_rotation = cv::Mat(3,3,CV_64FC1);
- cv::Mat out_translation = cv::Mat(4,1,CV_64FC1);
- cv::hconcat(R,t,projMatrix);//將R、t拼接維投影矩陣
- cv::decomposeProjectionMatrix(projMatrix,out_intrinsics,out_rotation,out_translation,
- cv::noArray(),cv::noArray(),cv::noArray(),euler_angles);
- //將投影矩陣分解為旋轉矩陣和相機(內參)矩陣
- Debug("Euler Angle");
- Debug(euler_angles);
- }
無需判斷奇異性,直接呼叫庫函式,相對簡單