两种由旋转矩阵计算欧拉角的办法

算法一:直接法

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(0,0)*matrix.at(0,0)+matrix.at(1,0)*matrix.at(1,0));

	bool singular = sy<1e-6;
	
	if(!singular)
	{
		theta_x=atan2(matrix.at(2,1),matrix.at(2,2));
		//theta_x= theta_x*180.0/3.1416 ;
		theta_y=atan2(-matrix.at(2,0), sy);
		//theta_y= theta_y*180.0/3.1416 ;
		theta_z=atan2(matrix.at(1,0), matrix.at(0,0));
		//theta_z= theta_z*180.0/3.1416 ;
	}
	else
	{
		theta_x=atan2(-matrix.at(1,2), matrix.at(1,1));
		//theta_x= theta_x*180.0/3.1416 ;
		theta_y=atan2(-matrix.at(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);
} 

无需判断奇异性,直接调用库函数,相对简单



你可能感兴趣的:(OpenCV)