相机姿态估计(OpenCV的PNP)(Camera pose estimation (OpenCV

2019-09-01 07:15发布

我想从使用我的摄像头4个基准与全球知名位置的图像的全球姿态估计。

我已经检查过很多stackexchange问​​题和几张纸,我似乎无法得到正确的AA解决方案。 该位置号码我不出去是可重复的,但绝不是线性正比于相机移动。 仅供参考,我使用C ++ OpenCV的2.1。

在这个环节被描绘我的坐标系和下面使用的测试数据。

% Input to solvePnP():
imagePoints =     [ 481, 831; % [x, y] format
                    520, 504;
                   1114, 828;
                   1106, 507]
objectPoints = [0.11, 1.15, 0; % [x, y, z] format
                0.11, 1.37, 0; 
                0.40, 1.15, 0;
                0.40, 1.37, 0]

% camera intrinsics for Logitech C910
cameraMat = [1913.71011, 0.00000,    1311.03556;
             0.00000,    1909.60756, 953.81594;
             0.00000,    0.00000,    1.00000]
distCoeffs = [0, 0, 0, 0, 0]

% output of solvePnP():
tVec = [-0.3515;
         0.8928; 
         0.1997]

rVec = [2.5279;
       -0.09793;
        0.2050]
% using Rodrigues to convert back to rotation matrix:

rMat = [0.9853, -0.1159,  0.1248;
       -0.0242, -0.8206, -0.5708;
        0.1686,  0.5594, -0.8114]

到目前为止, 任何人都可以看到什么不对这些数字呢? 我将不胜感激,如果有人在检查它们例如MATLAB(上面的代码是m文件友好)。

从这一点来说,我不确定如何从RMAT和tVec全球姿势。 从我在看过这个问题 ,摆脱RMAT和tVec姿势很简单:

position = transpose(rMat) * tVec   % matrix multiplication

不过我从其他渠道怀疑我看了它不是那么简单。

让相机在现实世界中的坐标位置,我需要做什么? 由于我不能确定这是否是一个执行问题(但很可能是一个理论问题)我想的人谁使用了solvePnP功能成功OpenCV的回答这个问题,但任何想法,欢迎呢!

非常感谢您的宝贵时间。

Answer 1:

我解决了这个前一阵子,全年延迟道歉。

在Python 2.1的OpenCV我所用,而新版本3.0.0-dev的,我已经验证,让相机的姿态在全球框架必须:

_, rVec, tVec = cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs)
Rt = cv2.Rodrigues(rvec)
R = Rt.transpose()
pos = -R * tVec

现在pos是摄像机在全局帧所表示的位置(在同一帧中的objectPoints表示在)。 R是一种态度矩阵DCM这是一个很好的形式存储在态度如果您需要欧拉角,那么你可以转换DCM欧拉角度给出使用XYZ的轮转顺序:

roll = atan2(-R[2][1], R[2][2])
pitch = asin(R[2][0])
yaw = atan2(-R[1][0], R[0][0])


Answer 2:

如果你的意思是全球姿势一个4x4相机姿态矩阵,可在OpenGL中使用,我做这种方式

CvMat* ToOpenGLCos( const CvMat* tVec, const CvMat* rVec )
{
    //** flip COS 180 degree around x-axis **//

    // Rodrigues to rotation matrix
    CvMat* extRotAsMatrix = cvCreateMat(3,3,CV_32FC1);
    cvRodrigues2(rVec,extRotAsMatrix);

    // Simply merge rotation matrix and translation vector to 4x4 matrix 
    CvMat* world2CameraTransformation = CreateTransformationMatrixH(tVec,
    extRotAsMatrix );

    // Create correction rotation matrix (180 deg x-axis)
    CvMat* correctionMatrix = cvCreateMat(4,4,CV_32FC1);
    /* 1.00000   0.00000   0.00000   0.00000
       0.00000  -1.00000  -0.00000   0.00000
       0.00000   0.00000  -1.00000   0.00000
       0.00000   0.00000   0.00000   1.00000 */
    cvmSet(correctionMatrix,0,0,1.0); cvmSet(correctionMatrix,0,1,0.0);
    ... 

    // Flip it
    CvMat* world2CameraTransformationOpenGL = cvCreateMat(4,4,CV_32FC1);
    cvMatMul(correctionMatrix,world2CameraTransformation,   world2CameraTransformationOpenGL);

    CvMat* camera2WorldTransformationOpenGL = cvCreateMat(4,4,CV_32FC1);
    cvInv(world2CameraTransformationOpenGL,camera2WorldTransformationOpenGL,
    CV_LU );

    cvReleaseMat( &world2CameraTransformationOpenGL );
    ...

    return camera2WorldTransformationOpenGL;
}

我想翻转的坐标系统是必要的,因为OpenCV的和OpenGL / VTK /等。 使用不同的坐标系统,在这张照片中所示的OpenGL和OpenCV坐标系

嗯,是这样工作的,但有人可能有一个更好的解释。



Answer 3:

相机的位置将是{ - 转置(R)* T}。 而已。

而你已经正确一切,除了,CV :: solvePnp给出(4×1)向量翻译,如果我没记错的话,你就必须分配X,Y,Z用W坐标。



文章来源: Camera pose estimation (OpenCV PnP)