C++ 如何将OpenCV摄影机旋转矢量转换为OpenGL旋转矢量?
我有一个摄像机旋转矩阵3x3,然后我使用C++ 如何将OpenCV摄影机旋转矢量转换为OpenGL旋转矢量?,c++,opencv,opengl,C++,Opencv,Opengl,我有一个摄像机旋转矩阵3x3,然后我使用Rodrigues函数从旋转矩阵中获取旋转向量,但它给出的结果类似于rotVec=(0.02,0.32.-0.01),但OpenGLglRotate函数需要度测量。我认为rotVec=(0.02,0.32.-0.01)是标准化的,我应该将每个元素乘以360度。但OpenCV和OpenGL之间也存在坐标系差异。如何在OpenGL坐标系中获得以度为单位的旋转向量?OpenCV和OpenGL使用不同的3D坐标系,以及不同的内存矩阵表示法。OpenGL矩阵以列大顺
Rodrigues
函数从旋转矩阵中获取旋转向量,但它给出的结果类似于rotVec=(0.02,0.32.-0.01)
,但OpenGLglRotate
函数需要度测量。我认为rotVec=(0.02,0.32.-0.01)
是标准化的,我应该将每个元素乘以360度。但OpenCV和OpenGL之间也存在坐标系差异。如何在OpenGL坐标系中获得以度为单位的旋转向量?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
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矩阵相比,这是换位的,OpenCV矩阵按行大顺序排列。例如:
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
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()
operator)进行转换。
因此,不必使用Rodrigues()(假设旋转矩阵是cv::Matx33
),您可以通过填充零平移将其转换为cv::Matx44
,并使用glMultMatrix(xform.t().val)
直接与OpenGL MODELVIEW转换连接。(t()
创建转置,并且.val
是指向16个浮点的转置数组的指针。)
如果这样做,它可能仍然不起作用,因为在用于相机校准的OpenCV 3D坐标系中,+X在右侧,+Y在下方,+Z在相机前面。在“法线”OpenGL坐标系中,+X在右侧,+Y在上方,+Z在相机后面(也就是说,只有负Z坐标可见)。这两个系统都是右手系统,围绕X旋转180度。因此,您可以在OpenGL MODELVIEW堆栈的底部插入这样的旋转。然后可以将OpenCV 3D坐标直接传递给OpenGL
(如果您想使用OpenCV相机校准,例如,用于正确对齐的增强现实,那么您还需要使用相机的内部矩阵仔细设置投影矩阵。但这是一个单独的问题…)
但由于实际问题是如何在OpenGL坐标系中获得以度为单位的旋转向量,因此您需要:
- 决定矩阵是OpenGL格式还是OpenCV格式;如果是OpenGL,请转置它
- 调用Rodrigues()获取向量
- 取矢量长度,即以弧度为单位的旋转角度,乘以180/pi得到度
- 调用glRotate(vector.x、vector.y、vector.z、degrees)执行旋转
不必考虑坐标系的差异,因为这两个系统都是惯用右手的。结果将在适用于初始矩阵的坐标系中。为什么不直接使用矩阵?否则我不会假设它是标准化的,而是弧度。试试value*180/p这里有一个关于如何在opengl中使用3d旋转矩阵的示例:当我使用
gl时,变量rtmx@mika看起来很有效。Rotate(180*(float)rotVec[0,0]、-180*(float)rotVec[1,0]、-180*(float)rotVec[2,0])
甚至没有只使用3个参数的glRotate
函数。你们所做的并不是罗德里格斯的轴角表示法works@derhassc#中的gl.Rotate
需要3个参数(欧拉角),但在rodrigues
正确后,我仍然无法理解如何使用glRotate。非常感谢!它确实帮助了我的运动捕捉系统)