简体   繁体   English

如何使用opencv bundle调整

[英]How to use opencv bundle adjustment

I have calculated 5 camera matrices ( c1, ... c5 ), camera matrices are calculated by placing a 3D object at 5 different positions and for each position I have calculated camera matrix (and camera is constant). 我已经计算了5个相机矩阵( c1, ... c5 ),通过将3D物体放置在5个不同的位置来计算相机矩阵,并且对于每个位置我已经计算出相机矩阵(并且相机是恒定的)。 Camera matrix is calculated using SVD method. 相机矩阵使用SVD方法计算。

Now I want to use bundle adjustment in opencv to get one optimal camera matrix. 现在我想在opencv使用bundle调整来获得一个最佳的相机矩阵。 I found the documentation here 我在这里找到了文档

But documentation is not clear and also I was not able to find any sample code. 但文档不清楚,我也无法找到任何示例代码。 Can anybody explain how can I use opencv bundle adjustment to get the optimal camera matrix ? 任何人都可以解释我如何使用opencv bundle调整来获得optimal camera matrix

See the sample code at page 155 of Learning Image Processing with OpenCV . 请参阅使用OpenCV学习图像处理的第155页的示例代码。 Something like this: 像这样的东西:

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;
}

If you provide a MCVE then it's easier to help. 如果您提供MCVE,那么它会更容易提供帮助。

Edit: Given you have 5 estimates of the same K matrix. 编辑:鉴于您有5个相同K矩阵的估计值。 The easiest method is to simply average your 5 estimations to get a more accurate K. Under some mild assumptions that will be an optimal estimation. 最简单的方法是简单地平均您的5个估计值以获得更准确的K.在一些温和的假设下,这将是一个最佳估计。 If the reprojection errors vastly differ, then you can calculate a weighted average. 如果重投影错误差异很大,那么您可以计算加权平均值。

My answer assumes that you use a specific 3D object, whose dimensions are known accurately , to estimate the intrinsic parameters of one camera from multiple images of the object. 我的回答是假设你使用一个特定的三维物体,其尺寸已经准确知道,从物体的多个图像估计一个摄像机的内在参数。 In light of your comment to @fireant 's answer, I think this applies to your question. 根据你对@fireant的回答的评论,我认为这适用于你的问题。

Quick note on the meanings of 'camera matrix' 关于'相机矩阵'含义的快速说明

The term 'camera matrix' is very vague and can be understood in multiple ways: 术语“相机矩阵”非常模糊,可以通过多种方式理解:

  • The camera pose T = [R|t], also denoted extrinsic camera parameters. 相机姿势T = [R | t],也表示外部相机参数。
  • The intrinsic camera matrix K = [fx, s, cx; 内在相机矩阵K = [fx,s,cx; 0, fy, cy; 0,fy,cy; 0, 0, 1]. 0,0,1]。
  • The camera projection matrix P = K.[R|t]. 相机投影矩阵P = K. [R | t]。

As you say that you have multiple images but you want a single camera matrix, I think that you are talking about the intrinsic camera matrix K. 正如你所说,你有多个图像,但你想要一个相机矩阵,我认为你在谈论内在的相机矩阵K.

Why you should not use Bundle Adjustment 为什么你不应该使用捆绑调整

Bundle Adjustment is a technique used to solve a more general problem than camera calibration, where both the extrinsic camera parameters (ie 3D orientations and positions) and the 3D landmarks (eg 3D points) are unknown. 捆绑调整是一种用于解决比摄像机校准更普遍的问题的技术,其中外部摄像机参数(即3D方向和位置)和3D地标(例如3D点)都是未知的。 As @fireant noted, it is also possible to include intrinsic camera parameters in this global joint optimization. 正如@fireant所指出的,在全局联合优化中也可以包含内在的相机参数。 On the other hand, camera calibration assumes the 3D landmarks are known and observed by a single camera in multiple images, therefore it optimizes a single set of intrinsic camera parameters and one camera pose for each image. 另一方面,相机校准假设3D地标是已知的并且由多个图像中的单个相机观察,因此它针对每个图像优化了一组固有相机参数和一个相机姿势。

The thing to understand is that more general optimization problems involve more variables to be optimized, and it is therefore harder to make them well-constrained. 要理解的是,更一般的优化问题涉及更多要优化的变量,因此更难以使它们受到良好约束。 If they are not well-constrained, they will optimize your variables in a way that indeed decrease the global error, but that does not correspond to a solution of your real problem. 如果它们没有很好的约束,它们将以确实减少全局误差的方式优化变量,但这并不符合您真正问题的解决方案。 This is why, when using a joint optimization algorithm, you should always try to reduce the number of variables to be optimized. 这就是为什么在使用联合优化算法时,您应该总是尝试减少要优化的变量数量。

In the case of Bundle Adjustment VS Camera Calibration, you should only use Bundle Adjustment if you have no accurate idea of positions of the 3D landmarks. 在捆绑调整VS摄像机校准的情况下,如果您不准确了解 3D地标的位置,则应该仅使用捆绑调整。 Even then, it is probably a better idea to try and decouple the problems, for instance by calibrating the 3D object beforehand. 即便如此,尝试解耦问题可能是更好的主意,例如事先校准3D对象。 If you do have an accurate idea of the positions of the 3D landmarks, then they should not be considered as variables to be optimized, hence you should use the Camera Calibration technique. 如果您对3D地标的位置有准确的了解,那么它们不应被视为要优化的变量,因此您应该使用相机校准技术。

Initial estimate for the optimization 优化的初步估计

You are saying that you have multiple inaccurate estimates of the camera matrix K, and want to perform a joint optimization to obtain a single more accurate one. 您说您对相机矩阵K有多个不准确的估计值,并且想要执行联合优化以获得单个更准确的估计。 The problem is that, since you want to estimate a single camera matrix, you need to provide the joint optimization algorithm with only one initial estimate . 问题在于,由于您想要估计单个摄像机矩阵,因此需要为联合优化算法提供一个初始估计

What you could do, in order to still use your multiple approximate estimates, is to try to select, as initial estimate for the optimization algorithm, the one closest to the true solution. 为了仍然使用多个近似估计,您可以做的是尝试选择最接近真实解决方案的优化算法的初始估计。 For this purpose, you can use several heuristic criteria. 为此,您可以使用多个启发式标准。 For example you can select the one associated with the minimum reprojection error, or you can use the one associated to the image where the calibration object is the largest, etc. 例如,您可以选择与最小重投影误差相关联的那个,或者您可以使用与校准对象最大的图像相关联的那个,等等。

However, it will probably not make a big difference in the final estimate of the camera matrix. 但是,它可能不会对相机矩阵的最终估计产生很大的影响。

How to use 'calibrateCamera' for this task 如何使用'calibrateCamera'完成此任务

Suppose you have a calibration object with characteristic points. 假设您有一个带有特征点的校准对象。 It can be a standard 2D chessboard or assymetric circle grid, or any calibrated 3D object. 它可以是标准的2D棋盘或不对称圆网格,或任何校准的3D对象。 And suppose you have developped a way to detect this calibration object in an image (eg a custom feature detector, or a tool to manually determine the position of the object). 并且假设您已经开发出一种在图像中检测此校准对象的方法(例如,自定义特征检测器或手动确定对象位置的工具)。 Then you can define a vector allObjectPoints , containing the 3D points on the object that can be detected. 然后,您可以定义一个矢量allObjectPoints ,其中包含可以检测到的对象上的3D点。 Then for each image i , you can determine a vector imagePoints_i of the 2D points detected to be observations of some the object's 3D points (note that some object points may be occluded, hence there may be less items than in allObjectPoints ). 然后,对于每个图像i ,您可以确定检测到的2D点的矢量imagePoints_i是对某些对象的3D点的观察(注意,一些对象点可能被遮挡,因此可能存在比在allObjectPoints更少的项目)。 Then, since all the object points are identifiable (either directly or by reasoning), you can determine the vector objectPoints_i , containing the object 3D points actually observed in image i and ordered consistantly with imagePoints_i . 然后,由于所有对象点都是可识别的(直接或通过推理),您可以确定向量objectPoints_i ,其中包含在图像i实际观察到的对象3D点并与imagePoints_i一致地进行imagePoints_i

Then you stack all the objectPoints_i vectors in one big vector of vectors objectPoints . 然后将所有objectPoints_i向量堆叠在向量objectPoints一个大向量中。 Similarly you stack all the imagePoints_i vectors in one big vector of vectors imagePoints . 类似地,您将所有imagePoints_i向量堆叠在一个矢量imagePoints大向量中。 You can then make the call to calibrateCamera , with the flag CV_CALIB_USE_INTRINSIC_GUESS to indicate that you want the optimization algorithm to use the initial value that you provided. 然后,您可以使用标志CV_CALIB_USE_INTRINSIC_GUESS调用calibrateCamera ,以指示您希望优化算法使用您提供的初始值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM