OpenCV计算相机位置&&旋转

Ter*_*ris 4 c++ camera opencv position rotation

对于一个项目,我需要计算摄像机相对于已知物体的真实世界位置和方向.我有一组照片,每个都从不同的角度展示棋盘.使用CalibrateCamera和solvePnP我可以在2d重新投影点数,以获得AR事物.所以我的情况是这样的:

  • 内在参数是已知的

  • 失真系数是已知的

  • 翻译矢量和旋转矢量是每张照片都知道的.

我根本无法弄清楚如何计算相机的位置.我的猜测是:

  • 反转翻译矢量.(= T')

  • 将旋转矢量转换为度(似乎是弧度)并反转

  • 在旋转矢量上使用罗德里格兹

  • 计算RotationMatrix*t'

但结果完全不合适......基本上我想为世界坐标中的每个像素计算一条光线.如果需要更多关于我的问题的信息,我很乐意快速回答.

我不明白......不知怎的,光线仍在关闭.这是我的代码btw:

Mat image1CamPos = tvecs[0].clone(); //From calibrateCamera
Mat rot = rvecs[0].clone(); //From calibrateCamera
Rodrigues(rot, rot);
rot = rot.t();

//Position of Camera
Mat pos = rot * image1CamPos;

//Ray-Normal (( (double)mk[i][k].x) are known image-points)
float x = (( (double)mk[i][0].x) / fx) - (cx / fx);
float y = (( (double)mk[i][0].y) / fy) - (cy / fy);
float z = 1;
float mag = sqrt(x*x + y*y + z*z);
x /= mag;
y /= mag;
z /= mag;

Mat unit(3, 1, CV_64F);
unit.at<double>(0, 0) = x;
unit.at<double>(1, 0) = y;
unit.at<double>(2, 0) = z;

//Rotation of Ray
Mat rot = stof1 * unit;
Run Code Online (Sandbox Code Playgroud)

但是当绘制这个时,光线是关闭的:/

Nik*_*iko 7

对象相对于相机的平移t(3x1向量)和旋转R(3x3矩阵)等于从对象到相机空间的坐标变换,其由下式给出:

v' = R * v  + t
Run Code Online (Sandbox Code Playgroud)

旋转矩阵的反转只是转置:

R^-1 = R^T
Run Code Online (Sandbox Code Playgroud)

知道这一点,您可以轻松地将转换(第一个等式)解析为v:

v = R^T * v' - R^T * t
Run Code Online (Sandbox Code Playgroud)

这是从相机到对象空间的转换,即相机相对于对象的位置(旋转= R^T和平移= -R^T * t).

你可以简单地得到一个4x4齐次变换矩阵:

T = ( R^T  -R^T * t )
    (  0       1    )
Run Code Online (Sandbox Code Playgroud)

如果您现在在相机坐标中有任何点,则可以将其转换为对象坐标:

p' = T * (x, y, z, 1)^T
Run Code Online (Sandbox Code Playgroud)

所以,如果你想从一个带有坐标(a,b)的像素投射光线(可能你需要定义图像的中心,即由CalibrateCamera(0,0)报告的主点) - - 让那个像素成为P = (a,b)^T.然后它在相机空间中的3D坐标P_3D = (a,b,0)^T.让我们在正z方向投影100像素,即到点Q_3D = (a,b,100)^T.您需要做的就是使用变换矩阵T将3D坐标转换为对象坐标系,您应该能够在对象空间中的两个点之间绘制一条线.但是,请确保不要混淆单位:CalibrateCamera将报告像素值,同时可以定义对象坐标系,例如cm或mm.