我想从使用我的摄像头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的回答这个问题,但任何想法,欢迎呢!
非常感谢您的宝贵时间。
我解决了这个前一阵子,全年延迟道歉。
在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])
如果你的意思是全球姿势一个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坐标系
嗯,是这样工作的,但有人可能有一个更好的解释。
相机的位置将是{ - 转置(R)* T}。 而已。
而你已经正确一切,除了,CV :: solvePnp给出(4×1)向量翻译,如果我没记错的话,你就必须分配X,Y,Z用W坐标。