来自cv :: solvePnP的相机在世界坐标中的位置
c++
computer-vision
opencv
7
0

我有一个经过校准的相机(本征矩阵和失真系数),我想知道一些3d点及其在图像中的对应点(2d点),以了解相机的位置。

我知道, cv::solvePnP可以帮助我,看完这个这个我明白,solvePnP I的输出rvectvec是旋转和对象在相机平移坐标系。

因此,我需要找出相机在世界坐标系中的旋转/平移。

从上面的链接看来,该代码在python中很简单:

found,rvec,tvec = cv2.solvePnP(object_3d_points, object_2d_points, camera_matrix, dist_coefs)
rotM = cv2.Rodrigues(rvec)[0]
cameraPosition = -np.matrix(rotM).T * np.matrix(tvec)

我不知道python / numpy的东西(我正在使用C ++),但这对我来说没有多大意义:

  • rvec,solvePnP的tvec输出是3x1矩阵,3个元素向量
  • cv2.Rodrigues(rvec)是一个3x3矩阵
  • cv2.Rodrigues(rvec)[0]是3x1矩阵,3个元素向量
  • cameraPosition是一个3x1 * 1x3矩阵乘法,它是一个3x3矩阵。如何通过简单的glTranslatefglRotate调用在opengl中使用它?
参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

如果用“世界坐标”表示“对象坐标”,则必须对pnp算法给出的结果进行逆变换。

有一个反转转换矩阵的技巧,可让您节省通常很昂贵的反转操作,并解释了Python中的代码。给定的变换[R|t] ,我们有inv([R|t]) = [R'|-R'*t] ,其中R'是转置R 。因此,您可以编写代码(未经测试):

cv::Mat rvec, tvec;
solvePnP(..., rvec, tvec, ...);
// rvec is 3x1, tvec is 3x1

cv::Mat R;
cv::Rodrigues(rvec, R); // R is 3x3

R = R.t();  // rotation of inverse
tvec = -R * tvec; // translation of inverse

cv::Mat T = cv::Mat::eye(4, 4, R.type()); // T is 4x4
T( cv::Range(0,3), cv::Range(0,3) ) = R * 1; // copies R into T
T( cv::Range(0,3), cv::Range(3,4) ) = tvec * 1; // copies tvec into T

// T is a 4x4 matrix with the pose of the camera in the object frame

更新:以后,要将T与OpenGL一起使用,必须记住OpenCV和OpenGL的摄像机框架轴不同。

OpenCV使用通常在计算机视觉中使用的参考:X指向右侧,Y指向下方,Z指向前面( 如此图所示 )。 OpenGL中相机的框架为:X指向右侧,Y指向上方,Z指向背面( 如此图像的左侧)。因此,您需要绕X轴旋转180度。该旋转矩阵的公式在Wikipedia中

// T is your 4x4 matrix in the OpenCV frame
cv::Mat RotX = ...; // 4x4 matrix with a 180 deg rotation around X
cv::Mat Tgl = T * RotX; // OpenGL camera in the object frame

这些转换总是令人困惑,在某些步骤上我可能是错的,因此请一of而就。

最后,考虑到OpenCV中的矩阵以行优先顺序存储在内存中,而OpenGL则以列优先顺序存储在内存中。

收藏
评论

如果要将其转换为指定摄像机位置的标准4x4姿势矩阵。使用rotM作为左上3x3正方形,使用tvec作为右3个元素,并使用0,0,0,1作为下一行

pose = [rotation   tvec(0)
        matrix     tvec(1)
        here       tvec(2)
        0  , 0, 0,  1]

然后将其反转(获取摄影机的姿势而不是世界的姿势)

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号