Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将OpenCV摄影机旋转矢量转换为OpenGL旋转矢量?_C++_Opencv_Opengl - Fatal编程技术网

C++ 如何将OpenCV摄影机旋转矢量转换为OpenGL旋转矢量?

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矩阵以列大顺

我有一个摄像机旋转矩阵3x3,然后我使用
Rodrigues
函数从旋转矩阵中获取旋转向量,但它给出的结果类似于
rotVec=(0.02,0.32.-0.01)
,但OpenGL
glRotate
函数需要度测量。我认为
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。非常感谢!它确实帮助了我的运动捕捉系统)