openMVG / openMVG

open Multiple View Geometry library. Basis for 3D computer vision and Structure from Motion.
Mozilla Public License 2.0
5.67k stars 1.67k forks source link

global SfM and pose graph BA #1810

Closed CanCanZeng closed 2 years ago

CanCanZeng commented 3 years ago

Hi, I read the document and code about global SfM, an idea came to me that the global SfM and pose graph BA in SLAM are similar in some degree. The difference is that pose graph BA has an initial state but global SfM needs to compute an initial state and then do bundle adjustment. So, if I hve an initial state from visual odometry, the camera poses are accurate in local but have drift in global, which means some adjecent (in spatial) images will have no connections. The initial state is obtained from online and very fast, and the relative poses between time continuous images are very accurate and reliable. The absent connection can be computed by pair-wise image registration, since I have an initial state, I can triangulate the images first and then in regitration I can get rather good loop connections. Follow the above thinking, I get a fully connected relative pose graph. But when I follow the way pose graph BA doing, the result sometimes are not so good. Most of time, the drift can be eliminated, but sometimes there will be some images float lightly in the air. I think the cause is that there are two much drift, not in one place but in many places, since there are many 'circles', each circle will has its own dirft, so if I want to correct these drift at once, just do a bundle adjustment is not enough. So I think use the algorithm in global SfM to compute a better initial state will be more reasonable. Is there any way to just provide an pose graph, which has full relative poses between images and a dirfted global rotation and translation, to compute a better state?

an example data can be found here sphere.g2o.zip

, it's from g2o ,general graph optimization, https://github.com/RainerKuemmerle/g2o

the initial state and the ground truth (a sphere) is listed below Screenshot from 2020-10-11 19-32-04 Screenshot from 2020-10-11 19-32-44

the data structure in sphere.g2o is rather simple,

VERTEX_SE3:QUAT 0 18.7381 2.74428e-07 98.2287 0 0 0 1 this represents an vertex (image pose), 'VERTEX_SE3:QUAT' means it's an vertex, 0 is its ID, and the next 7 numbers are 'tx ty tz qx qy qz qw', tx ty tz is the position of image in global, and qx qy qz qw is the orientation of image in global coordinates.

EDGE_SE3:QUAT 446 496 4.23049 -0.0805415 -4.51211 -0.0782633 0.000851916 0.0870273 0.993127 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 3977.25 -4.34005 87.7012 3999.19 4.85959 3971.45 this represents a connection, 'EDGE_SE3:QUAT' means its an edge, and '446 496' are the IDs of vertices the edge connects, the next 7 number are tranform from 446 to 496 in tx ty tz qx qy qz qw, the next numbers are weights and can be ignored.

Any discussion or suggestion are welcome!

pmoulon commented 3 years ago

Importing relative ROtation and Translation to the GLobalSfM pipeline should be doable:

CanCanZeng commented 3 years ago

Thank you for your help, I already hacked the code to fill sfm_data file with my visual odometry pose, but the result of globalSfM is not very good, I didn't continue to trying this way.