Search code examples
pythonopencvcomputer-visionfundamental-matrix

Estimating Camera Focal Length for Epipolar based Pose Recovery


The title is a bit of a mouthful but basically I have two photographs (I am initializing a scene graph) and I want to recover the relative pose of the second photo. I know how to recover the pose from the Essential Matrix but this requires knowledge about the focal length (in pixels) and the origin. The origin is simple but how do I go about the focal length. Do I estimate it and leave it there? Can I just use the Fundamental Matrix instead of the Essential? or do I start with an estimate of the f and perform a loop until the rays from the two cameras through the key points converge or their distance minimizes?

TLDR; Not sure how to find F for pose recovery from epipolar geo, any help is appreciated

Here is some of the code:

pts_l_norm = cv2.undistortPoints(np.expand_dims(pts_l, axis=1), cameraMatrix=K_l, distCoeffs=None)
pts_r_norm = cv2.undistortPoints(np.expand_dims(pts_r, axis=1), cameraMatrix=K_r, distCoeffs=None)

E, mask = cv2.findEssentialMat(pts_l, pts_r, focal=1.0, pp=(0., 0.), method=cv2.RANSAC, prob=0.999, threshold=3.0)
points, R, t, mask = cv2.recoverPose(E, pts_l, pts_r)
print(R,t)

Where K_l is the intrinsics matrix and pts_l and r are the key points found with SIFT


Solution

  • So the way in which I estimated the intrinsic Matrix was to use the camera EXIF data. That data will include the focal length and its 35mm equivalent, in mm. And will include the size of the photo, useful for estimation of the origin.

    Then you will have to use the camera model number to look up the sensor size and conduct the conversion using the equation f_X = F_X * width_in_pixels/width_in_mm, where F_X is in mm.

    This was the best method I could find, unfortunately EXIF data doesnt always include the CCD width, if it does you could use that.