pose estimation:判断旋转变换矩阵是否正确
pose estimation: determine whether rotation and transmation matrix are right
最近我正在努力解决单个相机的姿势估计问题。我在图像上有一些 3D 点和相应的 2D 点。然后我使用 solvePnP 来获取旋转和平移向量。 问题是,如何确定向量是否是正确的结果?
现在我用一种间接的方式来做到这一点:
我使用某个点的旋转矩阵,平移向量和世界3D坐标来获取Camera系统中该点的坐标。那么我要做的就是判断坐标是否合理。我想我知道相机系统的 x、y 和 z 轴的方向。
- Camera center是Camera系统的原点吗?
- 现在考虑该点的 x 分量。 x在Camera的x轴方向上是否等于camera和world中的点space的距离(那么可以通过点放在camera的哪一边来判断符号)?
下图是在世界space中,而描绘的轴是在相机系统中。
========How Camera and the point be placed in the world space=============
|
|
Camera--------------------------> Z axis
| |} Xw?
| P(Xw, Yw, Zw)
|
v x-axis
我的 rvec 和 tvec 结果似乎对与错。对于一个指定的点,z值似乎是合理的,我的意思是,如果这个点在z方向上距离相机大约一米,那么z值大约为1。但是对于x和y,根据点我认为x和y应该是正数但它们是负数。而且,在原图中检测到的图案是这样的:
但是使用相机系统中计算的点坐标和相机内参,我得到了这样的图像:
目标保持其模式。但它从右下角移到了左上角。我不明白为什么。
是的,相机中心是相机坐标系的原点,好像是紧跟this post。
在相机姿态估计的情况下,值似乎合理可以命名为反投影误差。这是衡量您生成的旋转和平移将 3D 点映射到 2D 像素的程度。不幸的是,solvePnP 没有 return 残差度量。因此必须计算它:
cv::solvePnP(worldPoints, pixelPoints, camIntrinsics, camDistortion, rVec, tVec);
// Use computed solution to project 3D pattern to image
cv::Mat projectedPattern;
cv::projectPoints(worldPoints, rVec, tVec, camIntrinsics, camDistortion, projectedPattern);
// Compute error of each 2D-3D correspondence.
std::vector<float> errors;
for( int i=0; i < corners.size(); ++i)
{
float dx = pixelPoints.at(i).x - projectedPattern.at<float>(i, 0);
float dy = pixelPoints.at(i).y - projectedPattern.at<float>(i, 1);
// Euclidean distance between projected and real measured pixel
float err = sqrt(dx*dx + dy*dy);
errors.push_back(err);
}
// Here, compute max or average of your "errors"
校准相机的平均反投影误差可能在 0 - 2 像素范围内。根据你的两张照片,这会更多。对我来说,这看起来像是一个缩放问题。如果我是对的,你自己计算投影。也许你可以尝试一次 cv::projectPoints() 并进行比较。
当谈到变换时,我学会了不要跟随我的想象 :) 我用 returned rVec 和 tVec 做的第一件事通常是从中创建一个 4x4 刚性变换矩阵(我发布一次代码 here)。这让事情变得更不直观,但它更紧凑、更方便。
现在我知道答案了。
是的,相机中心就是相机坐标系的原点。
假设相机系统中的坐标计算为(xc,yc,zc)。然后 xc 应该是相机和相机之间的距离
现实世界中 x 方向的点。
接下来如何判断输出矩阵是否正确?
1. 正如@eidelen 指出的那样,反投影误差是一种指示性措施。
2.根据点在世界坐标系中的坐标和矩阵计算点的坐标
那么为什么我得到了错误的结果(图案保留但移动到图像的不同区域)?
solvePnP()
中的参数cameraMatrix
是一个矩阵,提供了相机外参的参数。在相机矩阵中,cx 和 cy 应该使用 width/2 和 height/2。虽然我使用图像大小的宽度和高度。我认为这导致了错误。在我纠正并重新校准相机后,一切似乎都很好。
最近我正在努力解决单个相机的姿势估计问题。我在图像上有一些 3D 点和相应的 2D 点。然后我使用 solvePnP 来获取旋转和平移向量。 问题是,如何确定向量是否是正确的结果?
现在我用一种间接的方式来做到这一点:
我使用某个点的旋转矩阵,平移向量和世界3D坐标来获取Camera系统中该点的坐标。那么我要做的就是判断坐标是否合理。我想我知道相机系统的 x、y 和 z 轴的方向。
- Camera center是Camera系统的原点吗?
- 现在考虑该点的 x 分量。 x在Camera的x轴方向上是否等于camera和world中的点space的距离(那么可以通过点放在camera的哪一边来判断符号)?
下图是在世界space中,而描绘的轴是在相机系统中。
========How Camera and the point be placed in the world space=============
|
|
Camera--------------------------> Z axis
| |} Xw?
| P(Xw, Yw, Zw)
|
v x-axis
我的 rvec 和 tvec 结果似乎对与错。对于一个指定的点,z值似乎是合理的,我的意思是,如果这个点在z方向上距离相机大约一米,那么z值大约为1。但是对于x和y,根据点我认为x和y应该是正数但它们是负数。而且,在原图中检测到的图案是这样的:
但是使用相机系统中计算的点坐标和相机内参,我得到了这样的图像:
目标保持其模式。但它从右下角移到了左上角。我不明白为什么。
是的,相机中心是相机坐标系的原点,好像是紧跟this post。
在相机姿态估计的情况下,值似乎合理可以命名为反投影误差。这是衡量您生成的旋转和平移将 3D 点映射到 2D 像素的程度。不幸的是,solvePnP 没有 return 残差度量。因此必须计算它:
cv::solvePnP(worldPoints, pixelPoints, camIntrinsics, camDistortion, rVec, tVec);
// Use computed solution to project 3D pattern to image
cv::Mat projectedPattern;
cv::projectPoints(worldPoints, rVec, tVec, camIntrinsics, camDistortion, projectedPattern);
// Compute error of each 2D-3D correspondence.
std::vector<float> errors;
for( int i=0; i < corners.size(); ++i)
{
float dx = pixelPoints.at(i).x - projectedPattern.at<float>(i, 0);
float dy = pixelPoints.at(i).y - projectedPattern.at<float>(i, 1);
// Euclidean distance between projected and real measured pixel
float err = sqrt(dx*dx + dy*dy);
errors.push_back(err);
}
// Here, compute max or average of your "errors"
校准相机的平均反投影误差可能在 0 - 2 像素范围内。根据你的两张照片,这会更多。对我来说,这看起来像是一个缩放问题。如果我是对的,你自己计算投影。也许你可以尝试一次 cv::projectPoints() 并进行比较。
当谈到变换时,我学会了不要跟随我的想象 :) 我用 returned rVec 和 tVec 做的第一件事通常是从中创建一个 4x4 刚性变换矩阵(我发布一次代码 here)。这让事情变得更不直观,但它更紧凑、更方便。
现在我知道答案了。
是的,相机中心就是相机坐标系的原点。
假设相机系统中的坐标计算为(xc,yc,zc)。然后 xc 应该是相机和相机之间的距离 现实世界中 x 方向的点。
接下来如何判断输出矩阵是否正确?
1. 正如@eidelen 指出的那样,反投影误差是一种指示性措施。
2.根据点在世界坐标系中的坐标和矩阵计算点的坐标
那么为什么我得到了错误的结果(图案保留但移动到图像的不同区域)?
solvePnP()
中的参数cameraMatrix
是一个矩阵,提供了相机外参的参数。在相机矩阵中,cx 和 cy 应该使用 width/2 和 height/2。虽然我使用图像大小的宽度和高度。我认为这导致了错误。在我纠正并重新校准相机后,一切似乎都很好。