首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用opencv束调整

如何使用opencv束调整
EN

Stack Overflow用户
提问于 2016-07-13 18:17:11
回答 2查看 16.2K关注 0票数 12

我已经计算了5个摄像机矩阵(c1, ... c5),相机矩阵是通过在5个不同位置放置一个3D对象来计算的,而对于每个位置,我已经计算了相机矩阵(摄像机是常数的)。用奇异值分解法计算摄像机矩阵。

现在,我想使用捆绑调整在opencv,以获得一个最佳的相机矩阵。我找到了文档这里

但是文档还不清楚,而且我也找不到任何示例代码。有人能解释我如何使用opencv包调整来获得optimal camera matrix吗?

EN

回答 2

Stack Overflow用户

发布于 2016-07-27 08:12:12

我的答案假设你使用一个特定的3D物体,它的尺寸是精确的,从物体的多幅图像中估计出一个相机的内在参数。鉴于您对@fireant的回答的评论,我认为这适用于您的问题。

浅谈相机矩阵的含义

“相机矩阵”这个术语非常模糊,可以用多种方式来理解:

  • 相机姿态T=R_t,也表示相机的外部参数。
  • 本征相机矩阵K= fx,s,cx;0,fy,cy;0,0,1。
  • 相机投影矩阵P= K.R|t。

当你说你有多个图像,但你想要一个单一的相机矩阵,我想你是在谈论内在的相机矩阵K。

为什么不使用捆绑调整?

束平差是一种用于解决比摄像机标定更普遍的问题的技术,其中外部摄像机参数(即三维方向和位置)和三维地标(例如三维点)都是未知的。正如@fireant所指出的,在这一全球联合优化中还可以包括内在的摄像机参数。另一方面,摄像机标定假设单个摄像机在多幅图像中已知并观察到三维地标,从而优化了单个摄像机参数集和每幅图像的一个摄像机姿态。

需要理解的是,更一般的优化问题涉及更多要优化的变量,因此很难使它们受到良好的约束。如果它们没有很好的约束,它们将以一种确实减少全局错误的方式来优化您的变量,但这不符合您真正问题的解决方案。这就是为什么在使用联合优化算法时,应该尽量减少要优化的变量的数量。

在捆绑调整与相机校准的情况下,只有当你有没有准确的概念的三维地标位置时,你才应该使用捆绑调整。即使在那时,也可能是一个更好的想法,尝试和解耦的问题,例如,通过校准的三维物体事先。如果你对三维地标的位置有一个准确的认识,那么它们不应该被认为是要优化的变量,因此你应该使用相机校准技术。

优化的初步估计

您是说,您有多个不准确的估计相机矩阵K,并希望执行联合优化,以获得一个单一的更准确的。问题是,由于您想要估计单个摄像机矩阵,您需要提供联合优化算法与,只有一个初始估计

您可以做的,为了仍然使用您的多重近似估计,是尝试选择,作为优化算法的初始估计,一个最接近真正的解决方案。为此,您可以使用几个启发式标准。例如,您可以选择与最小重投影误差相关联的,或者可以使用与校准对象最大的图像相关联的方法,等等。

然而,它可能不会对相机矩阵的最终估计产生很大的影响。

如何在此任务中使用“calibrateCamera”

假设您有一个带有特征点的校准对象。它可以是一个标准的二维棋盘或非标准圆网格,或任何校准的三维物体。并且假设您开发了一种方法来检测图像中的校准对象(例如,自定义特征检测器,或者手动确定对象位置的工具)。然后,您可以定义一个向量allObjectPoints,其中包含可以检测到的对象上的3D点。然后,对于每个图像i,您可以确定检测到的2D点的向量imagePoints_i是对象的一些3D点的观测值(请注意,一些对象点可能被排除,因此可能比allObjectPoints中的条目少)。然后,由于所有对象点都是可识别的(无论是直接的还是通过推理),您可以确定向量objectPoints_i,其中包含在图像i中实际观察到的对象三维点,并且与imagePoints_i排序一致。

然后将所有的objectPoints_i向量叠加在一个向量的大向量中,objectPoints。类似地,您将所有的imagePoints_i向量叠加在一个向量imagePoints的大向量中。然后,您可以调用calibrateCamera,并使用标志CV_CALIB_USE_INTRINSIC_GUESS来指示您希望优化算法使用您提供的初始值。

票数 14
EN

Stack Overflow用户

发布于 2016-07-26 21:59:52

参见利用OpenCV学习图像处理第155页的示例代码。就像这样:

代码语言:javascript
复制
vector<CameraParams> cameras;
vector<MatchesInfo> pairwise_matches;
vector<ImageFeatures> features(num_images);

// initialize the above params here

Ptr<BundleAdjusterBase> adjuster;
adjuster = makePtr<BundleAdjusterReproj>();
if (!(*adjuster)(features, pairwise_matches, cameras)) {
    cout << "Camera parameters adjusting failed." << endl; 
    return -1;
}

如果你提供一个MCVE,那么它更容易帮助。

编辑:给出了相同K矩阵的5种估计。最简单的方法是简单地平均你的5个估计,得到一个更精确的K,在一些温和的假设下,这将是一个最优的估计。如果重投影误差相差很大,那么就可以计算加权平均值。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38359046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档