.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/transform/plot_fundamental_matrix.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_transform_plot_fundamental_matrix.py: ============================= Fundamental matrix estimation ============================= This example demonstrates how to robustly estimate `epipolar geometry ` (the geometry of stereo vision) between two views using sparse ORB feature correspondences. The `fundamental matrix `_ relates corresponding points between a pair of uncalibrated images. The matrix transforms homogeneous image points in one image to epipolar lines in the other image. Uncalibrated means that the intrinsic calibration (focal lengths, pixel skew, principal point) of the two cameras is not known. The fundamental matrix thus enables projective 3D reconstruction of the captured scene. If the calibration is known, estimating the essential matrix enables metric 3D reconstruction of the captured scene. .. GENERATED FROM PYTHON SOURCE LINES 22-98 .. image-sg:: /auto_examples/transform/images/sphx_glr_plot_fundamental_matrix_001.png :alt: Inlier correspondences, Histogram of disparity errors :srcset: /auto_examples/transform/images/sphx_glr_plot_fundamental_matrix_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none Number of matches: 223 Number of inliers: 162 /home/runner/work/scikit-image/scikit-image/doc/examples/transform/plot_fundamental_matrix.py:82: FutureWarning: `plot_matches` is deprecated since version 0.23 and will be removed in version 0.25. Use `skimage.feature.plot_matched_features` instead. | .. code-block:: Python import numpy as np from skimage import data from skimage.color import rgb2gray from skimage.feature import match_descriptors, ORB, plot_matches from skimage.measure import ransac from skimage.transform import FundamentalMatrixTransform import matplotlib.pyplot as plt img_left, img_right, groundtruth_disp = data.stereo_motorcycle() img_left, img_right = map(rgb2gray, (img_left, img_right)) # Find sparse feature correspondences between left and right image. descriptor_extractor = ORB() descriptor_extractor.detect_and_extract(img_left) keypoints_left = descriptor_extractor.keypoints descriptors_left = descriptor_extractor.descriptors descriptor_extractor.detect_and_extract(img_right) keypoints_right = descriptor_extractor.keypoints descriptors_right = descriptor_extractor.descriptors matches = match_descriptors(descriptors_left, descriptors_right, cross_check=True) print(f'Number of matches: {matches.shape[0]}') # Estimate the epipolar geometry between the left and right image. random_seed = 9 rng = np.random.default_rng(random_seed) model, inliers = ransac( (keypoints_left[matches[:, 0]], keypoints_right[matches[:, 1]]), FundamentalMatrixTransform, min_samples=8, residual_threshold=1, max_trials=5000, rng=rng, ) inlier_keypoints_left = keypoints_left[matches[inliers, 0]] inlier_keypoints_right = keypoints_right[matches[inliers, 1]] print(f'Number of inliers: {inliers.sum()}') # Compare estimated sparse disparities to the dense ground-truth disparities. disp = inlier_keypoints_left[:, 1] - inlier_keypoints_right[:, 1] disp_coords = np.round(inlier_keypoints_left).astype(np.int64) disp_idxs = np.ravel_multi_index(disp_coords.T, groundtruth_disp.shape) disp_error = np.abs(groundtruth_disp.ravel()[disp_idxs] - disp) disp_error = disp_error[np.isfinite(disp_error)] # Visualize the results. fig, ax = plt.subplots(nrows=2, ncols=1) plt.gray() plot_matches( ax[0], img_left, img_right, keypoints_left, keypoints_right, matches[inliers], only_matches=True, ) ax[0].axis("off") ax[0].set_title("Inlier correspondences") ax[1].hist(disp_error) ax[1].set_title("Histogram of disparity errors") plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.227 seconds) .. _sphx_glr_download_auto_examples_transform_plot_fundamental_matrix.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/scikit-image/scikit-image/v0.23.2?filepath=notebooks/auto_examples/transform/plot_fundamental_matrix.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_fundamental_matrix.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_fundamental_matrix.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_