如果用“世界坐标”表示“对象坐标”,则必须对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则以列优先顺序存储在内存中。
0
我有一个经过校准的相机(本征矩阵和失真系数),我想知道一些3d点及其在图像中的对应点(2d点),以了解相机的位置。
我知道,
cv::solvePnP
可以帮助我,看完这个和这个我明白,solvePnP I的输出rvec
和tvec
是旋转和对象在相机平移坐标系。因此,我需要找出相机在世界坐标系中的旋转/平移。
从上面的链接看来,该代码在python中很简单:
我不知道python / numpy的东西(我正在使用C ++),但这对我来说没有多大意义:
glTranslatef
和glRotate
调用在opengl中使用它?