Acquire each camera's extrinsic martix #483
Replies: 5 comments 5 replies
-
Hi @yichuan1998 (Murphy)! The phrase you want to google is "bundle adjustment." This is a process for estimating the point locations and the camera positions in such a way that it minimizes the reprojection error (or some cost function based on the reprojection error). It seems intimidating, but really it's just a least_squares problem. This was the example I started with to get pyxy3d working: There is also a lecturer on youtube whose videos really helped me get my head around it: In pyxy3d the bundle adjustment happens within the CaptureVolume class: The capture volume is composed of the camera position estimates and the 3d point estimates of the charuco corners taken during the multicamera calibration. Basically, you start with your initial estimates of where the cameras are and where the board is, then figure out where the point would be projected on the camera view if your estimate were 100% accurate (including estimates of lens distortion). This will differ from where the point actually shows up in the image. The difference between the "projected point" and the actual point is the "reprojection error". With the reprojection error defined as a function of the 3d point positions and the camera positional estimates, the optimization basically runs through some kind of gradient descent to get the best fit. It nudges the points and the cameras around and rechecks if the error improves. The thing that pyxy3d does that I'm proud of (and that results in a very fast, reliable convergence to an optimum) is that it is very careful with the initialization of the estimates. It basically follows these stages:
Unfortunately (and surprisingly) there is not a stock cv2 approach to this. I think you kinda have to roll your own... I realize that I'm throwing a lot at you at once...One thing I will say is that if you are going down this path to roll your own, prioritize a method for visualizing your current estimates because you want a way to quickly see when a small error has started to creep into your calculations (which often has a big impact and will yield weird results). Please feel free to keep questions coming! |
Beta Was this translation helpful? Give feedback.
-
You are correct regarding the Rodrigues. The rotation within each camera is the 3x1 version and the rotation stored within the stereo_pair entries is the 3x3 equivalent. This is just an arbitrary artifact of the way things are stored. cv2.rodrigues will convert between the two different forms of the rotation and during the matrix math the 3x3 version is used. To link together more than two cameras in a common frame of reference, you can use a single camera as the anchor and stereocalibrate all other cameras relative to that. This is self-limiting because you can't always get a good view between an anchor and all other cameras. So what to do? You can then bridge stereopairs to put things in a common frame of reference. That happens in the code here: It involves using the transformation matrix which is a merge of the rotation and translation matrices, so that's what you'll want to start googling. In the simplest case you can invert the transformation matrix to swap the "anchor" camera in a stereopair (at least if memory serves). I will say that you are walking down a topic where I found precious little relevant information online that I could interpret. Searching stack overflow for information about this seems to lead to many people with deep expertise in CV being....less than helpful. I kinda had to just mess around in conjunction with a good visualizer to make sure that I was understanding things correctly. So I'll underscore again: prioritize having a method to visualize your calculations in 3D before you start diving deep into doing the calculations. Pyqtgraph is an option. Python scripting in Blender may also be useful here as they have many camera /camera position features built in. I'm sure there are other high level 3d tools that can help with this, so probably worth poking around. |
Beta Was this translation helpful? Give feedback.
-
And on the topic of triangulating with 3 cameras, it remains fundamentally a least-squares problem where you are trying to minimize the reprojection error across all cameras. I employ the code solution developed by Lili Karashchuk (lambdaloop on github) within Anipose: This uses singular value decomposition (np.linalg.svd) for the least squares solution. And just an edit to mention that for initializing the point estimates for the bundle adjustment I think I just average the stereopair triangulations once I have all the cameras in a common frame of reference. |
Beta Was this translation helpful? Give feedback.
-
I just wanted to check back in to let you know that a significant refactor has largely been completed (v0.3) and the workflow now fits in with pre-recorded video. It does require synchronized video for the multicamera calibration and triangulation, so that synchronization would have to be done outside of pyxy3d. While I'm still tracking down little issues here and there, I'm hoping to start getting feedback from others on the functionality of the package, so thought I'd reach out in case you cared to take a look. My brain isn't yet ready to try to write up the documentation, but here are some video walk throughs of the process in case you are interested:
Mac |
Beta Was this translation helpful? Give feedback.
-
Hey, Mac, how was your Christmas day? I tested the new version and got some problems as below. |
Beta Was this translation helpful? Give feedback.
-
Hi, Mac, it's me. Recently I was learning about multi-view geometry for human pose estimation. I managed to calibrate 2 cameras using cv2 but did't know how to calibrate 3 cameras. I could not find tutorial fromgoogle or github. I tried to learn it from the source code of pyxy3d and failed. Could you give me some advice? Thanks!
The code for calibrating two cameras:
Sincerely
Murphy
Beta Was this translation helpful? Give feedback.
All reactions