OpenCV Q&A Forum - RSS feedhttp://answers.opencv.org/questions/OpenCV answersenCopyright <a href="http://www.opencv.org">OpenCV foundation</a>, 2012-2018.Wed, 19 Aug 2020 02:25:23 -0500Fundamental matrix and epipolar lines from known camera parametershttp://answers.opencv.org/question/233891/fundamental-matrix-and-epipolar-lines-from-known-camera-parameters/I want to visualize epipolar lines in a given 3-D scene with two cameras. I have code that works when the two cameras are only offset along the X axis. If the cameras are offset along the Y or Z axis or if they are rotated in any way, the epipolar lines are very far off. I assume that this is because I am missing a conversion of units and that the special case with only an offset in the X direction works because the epipolar lines are horizontal, i.e., they have a slope of 0, regardless of a conversion.
My starting point are two `Viz3d` instances where the cameras are offset relative to one another, e.g., by 0.1 units. I compute the essential matrix from their rotation and translation (extrinsic camera parameters) using the `sfm` module like this:
const auto left_camera_pose = left_visualization.getViewerPose();
const auto right_camera_pose = right_visualization.getViewerPose();
Mat essential_matrix;
essentialFromRt(left_camera_pose.rotation(), left_camera_pose.translation(), right_camera_pose.rotation(), right_camera_pose.translation(), essential_matrix);
From the essential matrix I compute the fundamental matrix using the two cameras' intrisic camera parameters like this:
const auto left_camera = left_visualization.getCamera();
const auto left_camera_matrix = GetIntrinsicCameraMatrix(left_camera);
const auto right_camera = right_visualization.getCamera();
const auto right_camera_matrix = GetIntrinsicCameraMatrix(right_camera);
Mat fundamental_matrix;
fundamentalFromEssential(essential_matrix, left_camera_matrix, right_camera_matrix, fundamental_matrix);
The intrinsic camera parameters I construct from the cameras' focal lengths and principal point coordinates like this:
static Matx33d GetIntrinsicCameraMatrix(const Camera &camera)
{
const auto focal_length = camera.getFocalLength();
const auto principal_point = camera.getPrincipalPoint();
const Matx33d intrinsics(focal_length[0], 0, principal_point[0], 0, focal_length[1], principal_point[1], 0, 0, 1);
return intrinsics;
}
With the fundamental matrix and a given point in the left camera image, I compute the epipolar line parameters using `computeCorrespondEpilines` (The full source code of is available [here](https://github.com/dustsigns/lecture-demos/blob/master/fundamentals_of_stereoscopy/epipolar_lines.cpp) with some additional documentation [here](https://github.com/dustsigns/lecture-demos/blob/master/fundamentals_of_stereoscopy/epipolar_lines_readme.md))
. When both cameras are only offset in the X direction, the result appears to be correct when visualized, but it is totally off when offsetting the cameras in the Y or Z direction or when rotating them with respect to each other.
As stated above, I think that this is related to the units of the matrices and that one or multiple conversions is/are required. Unfortunately, I cannot find any documentation in the `viz` or `sfm` modules which state whether world coordinates, relative coordinates or any other types of coordinates are used by the individual functions. I already tried `normalizeFundamental` from the `sfm` module, but, although it does change the fundamental matrix, it does not make the result look any more plausible.
Am I missing any conversion here? Is there any documentation about the units of the respective input and output matrices of the functions above so that I can build some custom conversion functions? Any hint is appreciated.dustsignsWed, 19 Aug 2020 02:25:23 -0500http://answers.opencv.org/question/233891/