gpt4 book ai didi

c++ - 如何将OpenCV摄像机旋转 vector 转换为OpenGL旋转 vector ?

转载 作者:行者123 更新时间:2023-12-02 10:24:29 27 4
gpt4 key购买 nike

我有一个3x3的相机旋转矩阵,然后我使用Rodrigues函数从旋转矩阵获取旋转 vector ,但是它给出的结果类似于rotVec = (0.02,0.32.-0.01),但是OpenGL glRotate函数需要度数。我认为rotVec = (0.02,0.32.-0.01)是规范化的,我应该将每个元素乘以360以得到度。但是在OpenCV和OpenGL之间也存在坐标系统差异。如何在OpenGL坐标系中获得以度为单位的旋转 vector ?

最佳答案

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,并使用 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坐标系中获取以度为单位的旋转 vector ,因此您需要:
  • 决定矩阵是OpenGL还是OpenCV格式;如果是OpenGL,请对其进行转置。
  • 调用Rodrigues()获得 vector 。
  • 取 vector 长度(以弧度为单位的旋转 Angular ),然后乘以180 / pi以得到度。
  • 调用glRotate(vector.x,vector.y,vector.z,度)执行旋转。

  • 由于两个系统都是右撇子,因此无需考虑坐标系的差异。结果将在适合初始矩阵的坐标系中。

    关于c++ - 如何将OpenCV摄像机旋转 vector 转换为OpenGL旋转 vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49219595/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com