我有一个相机旋转矩阵3x3,然后我使用Rodrigues
函数从旋转矩阵中获取旋转矢量,但它给出的结果如rotVec = (0.02,0.32.-0.01)
,但OpenGL glRotate
函数需要度measurment。我认为rotVec = (0.02,0.32.-0.01)
是正常的,我应该将每个元素乘以360来获得学位。但OpenCV和OpenGL之间也存在坐标系差异。如何在OpenGL坐标系中获得以度为单位的旋转矢量?
答案 0 :(得分:0)
OpenCV和OpenGL使用不同的3D坐标系和不同的内存矩阵表示。 OpenGL矩阵以列主要顺序存储在内存中。例如:
m[0] m[4] m[8] m[12]=tx
m[1] m[5] m[9] m[13]=ty
m[2] m[6] m[10] m[14]=tz
m[3]=0 m[7]=0 m[11]=0 m[15]=1
与普通的OpenCV矩阵相比,这是转换的,这些矩阵是按行主顺序排列的。例如:
m[0] m[1] m[2] m[3]=tx
m[4] m[5] m[6] m[7]=ty
m[8] m[9] m[10] m[11]=tz
m[12]=0 m[13]=0 m[14]=0 m[15]=1
因此,您需要跟踪您的矩阵是OpenCV还是OpenGL格式。它们可以通过转置(cv::Mat::t()
运算符)进行转换。
因此,不是使用Rodrigues()(假设您的旋转矩阵是cv::Matx33
),您可以通过使用零转换填充它将其转换为cv::Matx44
,并使用{直接与OpenGL MODELVIEW转换连接{ {1}}。 (glMultMatrix(xform.t().val)
创建转置,t()
是指向16个浮点数的转置数组的指针。)
如果你这样做,它可能仍然无法工作,因为在用于摄像机校准的OpenCV 3D坐标系中,+ X在右边,+ Y在下,而+ Z在摄像机前面。在“普通”OpenGL坐标系中,+ X在右侧,+ Y在向上,+ Z在摄像机后面(也就是说,只有负Z坐标可见)。两者都是右手系统,通过围绕X的180度旋转相关联。因此,您可以在OpenGL MODELVIEW堆栈的底部插入这样的旋转。然后,您可以将OpenCV 3D坐标直接传递给OpenGL。
(如果您想要使用OpenCV相机校准,例如正确对齐的增强现实,那么您还需要使用相机的内在矩阵仔细设置投影矩阵。但这是一个单独的问题......)
但是由于你的实际问题是如何在OpenGL坐标系中获得以度为单位的旋转矢量,那么你需要:
不应考虑坐标系差异,因为两个系统都是右撇子。结果将在适合初始矩阵的坐标系中。