SimpleStereo
SimpleStereo copied to clipboard
Added support for fisheye (and mixed fisheye/pinhole) stereo rigs
I added fisheye calibration to my fork of SimpleStereo (master), following notes here and also here.
In 'chessboardStereo' there are two new calling parameters which allow you to call the method with one or two fisheye cameras:
fisheye1, fisheye2 : bool Set to true if one or both of the stereo cameras have fisheye lenses For fisheye cameras, the number of distortion coefficients is 4 instead of 5.
For a stereo rig where one camera has a fisheye lens and the other has a regular lens, we initialize and pass intrinsic parameters (cameraMatrix, distCoeffs) obtained via ‘cv2 .fisheye.calibrate’ for the fisheye lens, while for the regular camera we continue to use ‘cv2.calibrateCamera’, which seems designed to accommodate different camera models and distortions as long as the appropriate intrinsic parameters (cameraMatrix, distCoeffs) are provided for each camera.
rig = ss.calibration.chessboardStereo(images, chessboardSize=(7,6), squareSize=52.0, fisheye1=1, fisheye2=0)
v.
rig = ss.calibration.chessboardStereo(images, chessboardSize=(7,6), squareSize=52.0, fisheye1=0, fisheye2=0)
We carry the same handling to the ‘undistortImages’ class in order to handle both fisheye and pinhole camera models. When undistorting images from a fisheye lens, we call ‘cv2.fisheye.initUndistortRectifyMap’ function to compute the undistortion and rectification transformation maps, then apply these maps to the input image using ‘cv2.remap’.
The reprojection results are 2.6 pixels from a small group of (15) chessboard pairs, which you can download here with 'BuildStereoRig.py' to run the calibration, and 'display_images.py' to display results, and the SimpleStereo rigs run with and without fisheye handling.
Since our images don’t adequately cover the field of view, the distortion correction for the area outside the chessboard degrades rapidly. The framing of the chessboard shown is necessary for this reason: one camera tilts away from the other, reducing the overlap between the two cameras as described here.
The results here are identical with or without the fisheye handling, which may be because the normal cv methods work with these images (in the small local region of the frame where we have the chessboard), or there is an implementation problem I'm not seeing.
Note that if you have mixed fisheye and pinhole camera images, choosing to set both as fisheye causes arcane errors in 'cv2.fisheye.stereoCalibrate'.
Here is a sample stereo pair with input on the left and output on the right: