
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "../../docs/source/_gallery/optimize_parameters.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_.._.._docs_source__gallery_optimize_parameters.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_.._.._docs_source__gallery_optimize_parameters.py:


.. _sphx_glr__gallery_optimize_parameters.py:

Optimizing distortion parameters with least squares
======================================================================================================

This example illustrate how to use the ``optimize_parameters_trf`` function to optimize the distortion parameters of a camera model, which includes the intrinsic and distortion transformations.

.. seealso::

    - :func:`pycvcam.optimize_parameters_trf`: Optimize the parameters of a transformation using Trust Region Reflective optimization.
    - :func:`pycvcam.optimize_camera_trf`: Optimize the parameters of a complete camera model using Trust Region Reflective optimization.

.. GENERATED FROM PYTHON SOURCE LINES 18-31

Optimizing Parameters to fit a Distortion model (Image Alignment)
-------------------------------------------------------------------
In this example, we consider a random image, an intrinsic matrix and a distortion model.
We distort the image by the distortion model and then add noise.

The objective is to optimize the distortion parameters of the distortion model to
fit the distorted image with noise.

To do this, we will compute the flow between the both images and then optimize the
distortion parameters to minimize the flow in the normalized image space.

First create the images and compute the real flow between the original and
distorted images.

.. GENERATED FROM PYTHON SOURCE LINES 31-110

.. code-block:: Python


    import numpy
    import pycvcam
    import cv2
    import matplotlib.pyplot as plt

    image = pycvcam.get_lena_image()
    image_height, image_width = image.shape[:2]
    print("Image shape:", image.shape)

    pixel_points = numpy.indices((image_height, image_width), dtype=numpy.float64)
    pixel_points = pixel_points.reshape(2, -1).T  # shape (H*W, 2) WARNING: [H, W -> Y, X]
    image_points = pixel_points[:, [1, 0]]  # Swap to [X, Y] format

    # Create an intrisic transformation
    intrinsic = pycvcam.Cv2Intrinsic.from_matrix(
        [[1000.0, 0.0, image_width / 2], [0.0, 1000.0, image_height / 2], [0.0, 0.0, 1.0]]
    )

    # Create a distortion transformation in the image space and convert it to the normalized image space
    distortion = pycvcam.ZernikeDistortion(
        parameters=[
            0.8541972545746392,
            -5.468596289790535,
            -5.974287819021697,
            14.292956075116104,
            2.1403205479372627,
            4.544169430137205,
            -0.10099732464199339,
            0.4363509204067417,
            -0.5106374355681896,
            -5.770087687650705,
            -0.39147505788710696,
            11.699411273002498,
        ]  # In pixels units, example values for a small distortion
    )
    distortion.center = ((image_width - 1) / 2, (image_height - 1) / 2)
    distortion.radius = numpy.sqrt(
        (distortion.center[0]) ** 2 + (distortion.center[1]) ** 2
    )
    distortion.parameters_x = distortion.parameters_x / intrinsic.fx
    distortion.parameters_y = distortion.parameters_y / intrinsic.fy
    distortion.radius_x = distortion.radius_x / intrinsic.fx
    distortion.radius_y = distortion.radius_y / intrinsic.fy
    distortion.center_x = (distortion.center_x - intrinsic.cx) / intrinsic.fx
    distortion.center_y = (distortion.center_y - intrinsic.cy) / intrinsic.fy

    true_distorted_points = pycvcam.distort_points(
        image_points, intrinsic, distortion, P=intrinsic
    )
    true_flow = true_distorted_points - image_points  # shape (H*W, 2)
    true_flow_magnitude = numpy.linalg.norm(true_flow, axis=1)

    print("True flow magnitude statistics:")
    print("  Min:", numpy.min(true_flow_magnitude))
    print("  Max:", numpy.max(true_flow_magnitude))
    print("  Mean:", numpy.mean(true_flow_magnitude))
    print("  Median:", numpy.median(true_flow_magnitude))
    print("  Std:", numpy.std(true_flow_magnitude))

    # Create the distorted image with noise (5% of noise in the GL units)
    distorted_image = pycvcam.distort_image(
        image, intrinsic, distortion, interpolation="spline3"
    )
    noise_GLpc = 5.0
    noise = numpy.random.normal(0, noise_GLpc / 100, distorted_image.shape)
    distorted_image = distorted_image * (1 + noise)  # Add multiplicative noise
    distorted_image = numpy.clip(distorted_image, 0, 255).astype(numpy.uint8)

    fig = plt.figure(figsize=(10, 5))
    ax1 = fig.add_subplot(1, 2, 1)
    ax1.imshow(image, cmap="gray")
    ax1.set_title("Original Image")
    ax1.axis("off")
    ax2 = fig.add_subplot(1, 2, 2)
    ax2.imshow(distorted_image, cmap="gray")
    ax2.set_title("Distorted Image with Noise")
    ax2.axis("off")




.. image-sg:: /_gallery/images/sphx_glr_optimize_parameters_001.png
   :alt: Original Image, Distorted Image with Noise
   :srcset: /_gallery/images/sphx_glr_optimize_parameters_001.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    Image shape: (474, 474)
    True flow magnitude statistics:
      Min: 0.012265189243667858
      Max: 24.30234213301494
      Mean: 6.324732682604791
      Median: 3.94728868310939
      Std: 5.5042902818601105

    (np.float64(-0.5), np.float64(473.5), np.float64(473.5), np.float64(-0.5))



.. GENERATED FROM PYTHON SOURCE LINES 111-113

Then compute the optical flow between both images using the ``compute_optical_flow``
function, which computes the dense optical flow between two images using the DIS algorithm.

.. GENERATED FROM PYTHON SOURCE LINES 113-168

.. code-block:: Python


    flow_x, flow_y = pycvcam.compute_optical_flow(
        image,
        distorted_image,
        disflow_params={
            "PatchSize": 15,
            "PatchStride": 1,
        },
    )
    flow_x = flow_x.reshape(-1, 1)  # shape (H*W, 1)
    flow_y = flow_y.reshape(-1, 1)  # shape (H*W, 1)

    flow = numpy.hstack((flow_x, flow_y))  # shape (H*W, 2)

    # Compare the computed flow with the true flow by visualizing the flow magnitude and
    # components for both the computed flow and the true flow to ensure consistency.

    fx = flow[:, 0].reshape(image_height, image_width)
    fy = flow[:, 1].reshape(image_height, image_width)
    F = numpy.sqrt(fx**2 + fy**2)
    tfx = true_flow[:, 0].reshape(image_height, image_width)
    tfy = true_flow[:, 1].reshape(image_height, image_width)
    tF = numpy.sqrt(tfx**2 + tfy**2)
    tF_max = numpy.max(tF)
    tfx_min, tfx_max = numpy.min(tfx), numpy.max(tfx)
    tfy_min, tfy_max = numpy.min(tfy), numpy.max(tfy)

    fig = plt.figure(figsize=(15, 10))
    ax1 = fig.add_subplot(2, 3, 1)
    ax1.imshow(F, cmap="inferno", vmin=0, vmax=tF_max)
    ax1.set_title("Flow Magnitude")
    ax1.axis("off")
    ax2 = fig.add_subplot(2, 3, 2)
    ax2.imshow(fx, cmap="inferno", vmin=tfx_min, vmax=tfx_max)
    ax2.set_title("Flow X Component")
    ax2.axis("off")
    ax3 = fig.add_subplot(2, 3, 3)
    ax3.imshow(fy, cmap="inferno", vmin=tfy_min, vmax=tfy_max)
    ax3.set_title("Flow Y Component")
    ax3.axis("off")
    ax4 = fig.add_subplot(2, 3, 4)
    ax4.imshow(tF, cmap="inferno", vmin=0, vmax=tF_max)
    ax4.set_title("True Flow Magnitude")
    ax4.axis("off")
    ax5 = fig.add_subplot(2, 3, 5)
    ax5.imshow(tfx, cmap="inferno", vmin=tfx_min, vmax=tfx_max)
    ax5.set_title("True Flow X Component")
    ax5.axis("off")
    ax6 = fig.add_subplot(2, 3, 6)
    ax6.imshow(tfy, cmap="inferno", vmin=tfy_min, vmax=tfy_max)
    ax6.set_title("True Flow Y Component")
    ax6.axis("off")
    # plt.show()





.. image-sg:: /_gallery/images/sphx_glr_optimize_parameters_002.png
   :alt: Flow Magnitude, Flow X Component, Flow Y Component, True Flow Magnitude, True Flow X Component, True Flow Y Component
   :srcset: /_gallery/images/sphx_glr_optimize_parameters_002.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    (np.float64(-0.5), np.float64(473.5), np.float64(473.5), np.float64(-0.5))



.. GENERATED FROM PYTHON SOURCE LINES 169-174

To finish, we optimize the distortion parameters to minimize the
flow in the normalized image space.

To avoid the border effects of the distortion and undistortion, we will consider
only the inner part of the image for the optimization by applying a mask to the points.

.. GENERATED FROM PYTHON SOURCE LINES 174-221

.. code-block:: Python


    images_mask = numpy.ones_like(image, dtype=bool)
    border_size = 50
    images_mask[0:border_size, :] = False
    images_mask[-border_size:, :] = False
    images_mask[:, 0:border_size] = False
    images_mask[:, -border_size:] = False

    distorted_points = image_points + flow  # shape (H*W, 2)
    normalized_points = intrinsic.inverse_transform(image_points).transformed_points
    distorted_points = intrinsic.inverse_transform(distorted_points).transformed_points
    normalized_points = normalized_points[images_mask.flatten()]
    distorted_points = distorted_points[images_mask.flatten()]

    initial_distortion = distortion.copy()
    initial_distortion.parameters = numpy.zeros_like(distortion.parameters)

    print("\n")
    parameters, result = pycvcam.optimize_parameters_trf(
        initial_distortion,
        normalized_points,
        distorted_points,
        auto=True,  # Set ftol, xtol and gtol to 1e-8
        return_result=True,
        verbose_level=3,
    )
    print("\n")

    optimize_distortion = initial_distortion.copy()
    optimize_distortion.parameters = parameters

    optimized_flow = (
        pycvcam.distort_points(image_points, intrinsic, optimize_distortion, P=intrinsic)
        - image_points
    )

    flow_error = numpy.linalg.norm(optimized_flow - true_flow, axis=1)  # shape (H*W,)
    rmse_flow = numpy.sqrt(numpy.mean(flow_error[images_mask.flatten()] ** 2))
    params_error = numpy.linalg.norm(parameters - distortion.parameters)
    params_rel_error = params_error / numpy.linalg.norm(distortion.parameters)

    print("Optimization success:", result.success)
    print("Optimization message:", result.message)
    print("Optimization cost:", result.cost)
    print("Flow RMSE:", rmse_flow)
    print("Parameters Error:", params_error, f"({params_rel_error:.2%})")





.. rst-class:: sphx-glr-script-out

 .. code-block:: none




    ==================================================

    --------------------------------------------------
    Initial Jacobian (Iter 0) analysis of the least squares problem
    --------------------------------------------------

    Jacobian shape: 279752 x 12 (equations x parameters)
    Overdetermined system (more residuals than parameters), the optimization is likely to converge to a unique solution.
    Density: 50.00%
    Singular values (max/min): 4.359e+02 / 4.929e+01
    Condition number: 8.843e+00

    Singular values and their contribution to the variance:
    |   Index    |  Singular Value λ  |     Var = 1/λ^2      |
    |     0      |     4.359e+02      |      5.263e-06       |
    |     1      |     4.359e+02      |      5.263e-06       |
    |     2      |     1.207e+02      |      6.861e-05       |
    |     3      |     1.207e+02      |      6.861e-05       |
    |     4      |     1.207e+02      |      6.861e-05       |
    |     5      |     1.207e+02      |      6.861e-05       |
    |     6      |     8.459e+01      |      1.398e-04       |
    |     7      |     8.459e+01      |      1.398e-04       |
    |     8      |     7.794e+01      |      1.646e-04       |
    |     9      |     7.794e+01      |      1.646e-04       |
    |     10     |     4.929e+01      |      4.115e-04       |
    |     11     |     4.929e+01      |      4.115e-04       |

    Higher and Smallers singular values directions vectors (V^T rows):
    | Parameter  |      Vt[0]      |      Vt[9]      |     Vt[10]      |     Vt[11]      | 
    |     0      |   -0.000e+00    |    0.000e+00    |   -0.000e+00    |    0.000e+00    | 
    |     1      |    8.519e-01    |   -9.145e-17    |    5.737e-16    |    3.896e-23    | 
    |     2      |   -3.123e-19    |    3.271e-17    |    1.068e-18    |   -1.110e-16    | 
    |     3      |    4.984e-17    |    4.192e-16    |   -1.350e-16    |    0.000e+00    | 
    |     4      |    2.094e-19    |    4.552e-17    |    1.487e-18    |   -5.551e-17    | 
    |     5      |   -2.220e-16    |    1.223e-14    |    3.287e-17    |   -2.303e-28    | 
    |     6      |    1.943e-18    |    2.273e-31    |   -2.246e-30    |    2.359e-16    | 
    |     7      |   -7.345e-19    |   -1.000e+00    |   -7.190e-16    |   -1.543e-33    | 
    |     8      |    0.000e+00    |    0.000e+00    |    0.000e+00    |   -3.864e-17    | 
    |     9      |   -5.236e-01    |   -1.474e-16    |    9.699e-16    |   -2.395e-23    | 
    |     10     |   -5.740e-20    |   -4.976e-32    |   -2.136e-32    |   -1.000e+00    | 
    |     11     |    1.909e-17    |   -8.749e-16    |    1.000e+00    |   -3.749e-32    | 

    Estimated variances of the parameters:
    | Parameter  |     Value P     | Var = σ^2 (J.T J)^-1 |  Ratio √V/|P|   |
    |     0      |    0.000e+00    |      8.018e-10       |    > 1000 %     |
    |     1      |    0.000e+00    |      8.018e-10       |    > 1000 %     |
    |     2      |    0.000e+00    |      1.305e-09       |    > 1000 %     |
    |     3      |    0.000e+00    |      1.305e-09       |    > 1000 %     |
    |     4      |    0.000e+00    |      1.305e-09       |    > 1000 %     |
    |     5      |    0.000e+00    |      1.305e-09       |    > 1000 %     |
    |     6      |    0.000e+00    |      3.132e-09       |    > 1000 %     |
    |     7      |    0.000e+00    |      3.132e-09       |    > 1000 %     |
    |     8      |    0.000e+00    |      1.957e-09       |    > 1000 %     |
    |     9      |    0.000e+00    |      1.957e-09       |    > 1000 %     |
    |     10     |    0.000e+00    |      7.830e-09       |    > 1000 %     |
    |     11     |    0.000e+00    |      7.830e-09       |    > 1000 %     |

    --------------------------------------------------
    Optimization in progress...
    --------------------------------------------------

       Iteration     Total nfev        Cost      Cost reduction    Step norm     Optimality   
           0              1         2.6611e+00                                    2.94e+02    
           1              2         1.8776e-03      2.66e+00       2.16e-02       1.35e-12    
    `gtol` termination condition is satisfied.
    Function evaluations 2, initial cost 2.6611e+00, final cost 1.8776e-03, first-order optimality 1.35e-12.

    --------------------------------------------------
    Jacobian analysis of the least squares problem (End of optimization)
    --------------------------------------------------

    Singular values (max/min): 4.359e+02 / 4.929e+01
    Condition number: 8.843e+00

    Singular values and their contribution to the variance:
    |   Index    |  Singular Value λ  |     Var = 1/λ^2      |
    |     0      |     4.359e+02      |      5.263e-06       |
    |     1      |     4.359e+02      |      5.263e-06       |
    |     2      |     1.207e+02      |      6.861e-05       |
    |     3      |     1.207e+02      |      6.861e-05       |
    |     4      |     1.207e+02      |      6.861e-05       |
    |     5      |     1.207e+02      |      6.861e-05       |
    |     6      |     8.459e+01      |      1.398e-04       |
    |     7      |     8.459e+01      |      1.398e-04       |
    |     8      |     7.794e+01      |      1.646e-04       |
    |     9      |     7.794e+01      |      1.646e-04       |
    |     10     |     4.929e+01      |      4.115e-04       |
    |     11     |     4.929e+01      |      4.115e-04       |

    Higher and Smallers singular values directions vectors (V^T rows):
    | Parameter  |      Vt[0]      |      Vt[9]      |     Vt[10]      |     Vt[11]      | 
    |     0      |   -0.000e+00    |    0.000e+00    |   -0.000e+00    |    0.000e+00    | 
    |     1      |    8.519e-01    |   -9.145e-17    |    5.737e-16    |    3.896e-23    | 
    |     2      |   -3.123e-19    |    3.271e-17    |    1.068e-18    |   -1.110e-16    | 
    |     3      |    4.984e-17    |    4.192e-16    |   -1.350e-16    |    0.000e+00    | 
    |     4      |    2.094e-19    |    4.552e-17    |    1.487e-18    |   -5.551e-17    | 
    |     5      |   -2.220e-16    |    1.223e-14    |    3.287e-17    |   -2.303e-28    | 
    |     6      |    1.943e-18    |    2.273e-31    |   -2.246e-30    |    2.359e-16    | 
    |     7      |   -7.345e-19    |   -1.000e+00    |   -7.190e-16    |   -1.543e-33    | 
    |     8      |    0.000e+00    |    0.000e+00    |    0.000e+00    |   -3.864e-17    | 
    |     9      |   -5.236e-01    |   -1.474e-16    |    9.699e-16    |   -2.395e-23    | 
    |     10     |   -5.740e-20    |   -4.976e-32    |   -2.136e-32    |   -1.000e+00    | 
    |     11     |    1.909e-17    |   -8.749e-16    |    1.000e+00    |   -3.749e-32    | 

    Estimated variances of the parameters:
    | Parameter  |     Value P     | Var = σ^2 (J.T J)^-1 |  Ratio √V/|P|   |
    |     0      |    8.603e-04    |      5.657e-13       |     0.087 %     |
    |     1      |   -5.457e-03    |      5.657e-13       |     0.014 %     |
    |     2      |   -5.975e-03    |      9.210e-13       |     0.016 %     |
    |     3      |    1.426e-02    |      9.210e-13       |     0.007 %     |
    |     4      |    2.144e-03    |      9.210e-13       |     0.045 %     |
    |     5      |    4.548e-03    |      9.210e-13       |     0.021 %     |
    |     6      |   -1.123e-04    |      2.210e-12       |     1.324 %     |
    |     7      |    4.313e-04    |      2.210e-12       |     0.345 %     |
    |     8      |   -5.012e-04    |      1.381e-12       |     0.234 %     |
    |     9      |   -5.747e-03    |      1.381e-12       |     0.020 %     |
    |     10     |   -4.067e-04    |      5.525e-12       |     0.578 %     |
    |     11     |    1.172e-02    |      5.525e-12       |     0.020 %     |

    ==================================================



    Optimization success: True
    Optimization message: `gtol` termination condition is satisfied.
    Optimization cost: 0.0018776472402509217
    Flow RMSE: 0.012279224855054716
    Parameters Error: 4.850344326962835e-05 (0.22%)




.. GENERATED FROM PYTHON SOURCE LINES 222-231

Optimizing Parameters of a complete Camera Model (PnP problem)
-----------------------------------------------------------------
In this example, we optimize the parameters of a complete camera model,
which includes the intrinsic, distortion and extrinsic transformations.
To do this, consider a PnP problem with a set of 3D points and their
corresponding 2D projections in the image.

For example, create a point cloud in a rectangle with bounds :math:`[-1, 1]` meters in the :math:`x` and :math:`y` directions and with a :math:`z` component in the range :math:`[4.5, 5.5]` meters.
Then place a camera near the origin with a small rotation and translation and project the 3D points to 2D image points using a pinhole camera model with Brown-Conrady distortion with a focal length of 1000 pixels and a principal point at (320, 240) pixels.

.. GENERATED FROM PYTHON SOURCE LINES 231-330

.. code-block:: Python


    print("\n\n\n")

    # Define the 3D points in the world coordinate system
    x = numpy.random.uniform(-1.0, 1.0, (100, 1))  # shape (100, 1)
    y = numpy.random.uniform(-1.0, 1.0, (100, 1))  # shape (100, 1)
    z = numpy.random.uniform(4.5, 5.5, (100, 1))  # shape (100, 1)
    world_points = numpy.hstack((x, y, z))  # shape (100, 3)

    # Define the Extrinsic transformation, example rotation vector and translation vector
    rvec = numpy.array([0.01, 0.02, 0.03])  # small rotation
    tvec = numpy.array([0.01, -0.05, 0.04])  # small translation
    extrinsic = pycvcam.Cv2Extrinsic.from_rt(rvec, tvec)

    # Define the Intrinsic transformation, example intrinsic camera matrix
    K = numpy.array([[1000.0, 0.0, 320.0], [0.0, 1000.0, 240.0], [0.0, 0.0, 1.0]])
    intrinsic = pycvcam.Cv2Intrinsic.from_matrix(K)

    # Define the Distortion transformation, example Brown-Conrady 5 parameters
    distortion = pycvcam.Cv2Distortion(parameters=[0.1, 0.05, 0.01, 0.01, 0.01])

    # Project the 3D points to 2D image points (without Jacobians)
    result = pycvcam.project_points(
        world_points,
        intrinsic=intrinsic,
        distortion=distortion,
        extrinsic=extrinsic,
    )  # pycvcam.TransformResult data class

    image_points = result.image_points  # shape (100, 2)

    # Optimize the camera parameters to fit the noisy image points
    initial_distortion = distortion.copy()
    initial_distortion.parameters = numpy.zeros_like(distortion.parameters)

    initial_extrinsic = extrinsic.copy()
    initial_extrinsic.parameters = numpy.zeros_like(extrinsic.parameters)

    distortion_bounds = (
        numpy.array([-0.1, -0.1, -0.1, -0.1, -0.1]),  # k1, k2, p1, p2, k3 lower bounds
        numpy.array([0.1, 0.1, 0.1, 0.1, 0.1]),  # k1, k2, p1, p2, k3 upper bounds
    )
    extrinsic_bounds = (  # rvec and tvec bounds
        numpy.array([-0.1, -0.1, -0.1, -0.1, -0.1, -0.1]),  # rvec and tvec lower bounds
        numpy.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]),  # rvec and tvec upper bounds
    )

    print("\n")
    params, result = pycvcam.optimize_camera_trf(
        intrinsic,
        initial_distortion,
        initial_extrinsic,
        world_points,
        image_points,
        mask_intrinsic=[False for _ in range(4)],  # Do not optimize intrinsic
        bounds_distortion=distortion_bounds,
        bounds_extrinsic=extrinsic_bounds,
        auto=True,  # Set ftol, xtol and gtol to 1e-8
        return_result=True,
        verbose_level=3,
    )
    print("\n")
    optimized_intrinsic_params, optimized_distortion_params, optimized_extrinsic_params = (
        params
    )
    print("Optimized Intrinsic Parameters:", optimized_intrinsic_params)
    print("Optimized Distortion Parameters:", optimized_distortion_params)
    print("Optimized Extrinsic Parameters:", optimized_extrinsic_params)

    optimized_distortion = initial_distortion.copy()
    optimized_distortion.parameters = optimized_distortion_params
    optimized_extrinsic = initial_extrinsic.copy()
    optimized_extrinsic.parameters = optimized_extrinsic_params

    optimized_image_points = pycvcam.project_points(
        world_points,
        intrinsic=intrinsic,
        distortion=optimized_distortion,
        extrinsic=optimized_extrinsic,
    ).image_points

    error_points = numpy.linalg.norm(optimized_image_points - image_points, axis=1)
    rmse_points = numpy.sqrt(numpy.mean(error_points**2))

    error_distortion = numpy.linalg.norm(
        optimized_distortion.parameters - distortion.parameters
    )
    error_extrinsic = numpy.linalg.norm(
        optimized_extrinsic.parameters - extrinsic.parameters
    )
    rel_error_distortion = error_distortion / numpy.linalg.norm(distortion.parameters)
    rel_error_extrinsic = error_extrinsic / numpy.linalg.norm(extrinsic.parameters)

    print("Optimization success:", result.success)
    print("Optimization message:", result.message)
    print("Optimization cost:", result.cost)
    print("RMSE Real Points:", rmse_points)
    print("Error Distortion:", error_distortion, f"({rel_error_distortion:.2%})")
    print("Error Extrinsic:", error_extrinsic, f"({rel_error_extrinsic:.2%})")




.. rst-class:: sphx-glr-script-out

 .. code-block:: none








    ==================================================

    --------------------------------------------------
    Initial Jacobian (Iter 0) analysis of the least squares problem
    --------------------------------------------------

    5 Distortion parameters to optimize - Parameters 0 to 4
    6 Extrinsic parameters to optimize - Parameters 5 to 10

    Jacobian shape: 200 x 11 (equations x parameters)
    Overdetermined system (more residuals than parameters), the optimization is likely to converge to a unique solution.
    Density: 90.91%
    Singular values (max/min): 1.036e+04 / 8.783e-03
    Condition number: 1.179e+06

    Singular values and their contribution to the variance:
    |   Index    |  Singular Value λ  |     Var = 1/λ^2      |
    |     0      |     1.036e+04      |      9.321e-09       |
    |     1      |     1.035e+04      |      9.338e-09       |
    |     2      |     1.656e+03      |      3.648e-07       |
    |     3      |     4.830e+02      |      4.287e-06       |
    |     4      |     4.615e+02      |      4.695e-06       |
    |     5      |     3.331e+02      |      9.012e-06       |
    |     6      |     1.182e+02      |      7.156e-05       |
    |     7      |     1.140e+02      |      7.688e-05       |
    |     8      |     2.512e+01      |      1.585e-03       |
    |     9      |     4.617e-01      |      4.691e+00       |
    |     10     |     8.783e-03      |      1.296e+04       |

    Higher and Smallers singular values directions vectors (V^T rows):
    | Parameter  |      Vt[0]      |      Vt[8]      |      Vt[9]      |     Vt[10]      | 
    |     0      |   -6.899e-04    |    9.794e-01    |    7.571e-02    |   -3.527e-03    | 
    |     1      |   -3.588e-05    |    7.538e-02    |   -9.910e-01    |    1.105e-01    | 
    |     2      |    5.368e-02    |    8.921e-03    |   -2.352e-05    |    2.647e-06    | 
    |     3      |   -1.316e-02    |   -1.078e-02    |    1.421e-04    |    1.406e-06    | 
    |     4      |   -2.000e-06    |    4.879e-03    |   -1.104e-01    |   -9.939e-01    | 
    |     5      |   -9.510e-01    |    1.158e-05    |   -9.443e-05    |    2.270e-06    | 
    |     6      |   -2.344e-01    |    1.467e-04    |    1.133e-04    |    8.689e-07    | 
    |     7      |   -3.343e-03    |   -4.625e-05    |   -8.993e-07    |    9.661e-09    | 
    |     8      |   -4.640e-02    |    1.236e-03    |   -5.921e-04    |   -4.767e-06    | 
    |     9      |    1.883e-01    |   -2.392e-03    |   -4.793e-04    |    1.082e-05    | 
    |     10     |    3.269e-03    |    1.868e-01    |    5.844e-03    |   -1.455e-04    | 

    Estimated variances of the parameters:
    | Parameter  |     Value P     | Var = σ^2 (J.T J)^-1 |  Ratio √V/|P|   |
    |     0      |    0.000e+00    |      9.472e+01       |    > 1000 %     |
    |     1      |    0.000e+00    |      8.136e+04       |    > 1000 %     |
    |     2      |    0.000e+00    |      2.431e-03       |    > 1000 %     |
    |     3      |    0.000e+00    |      2.577e-03       |    > 1000 %     |
    |     4      |    0.000e+00    |      6.396e+06       |    > 1000 %     |
    |     5      |    0.000e+00    |      1.495e-03       |    > 1000 %     |
    |     6      |    0.000e+00    |      1.473e-03       |    > 1000 %     |
    |     7      |    0.000e+00    |      1.826e-04       |    > 1000 %     |
    |     8      |    0.000e+00    |      3.649e-02       |    > 1000 %     |
    |     9      |    0.000e+00    |      3.689e-02       |    > 1000 %     |
    |     10     |    0.000e+00    |      2.489e-01       |    > 1000 %     |

    --------------------------------------------------
    Optimization in progress...
    --------------------------------------------------

       Iteration     Total nfev        Cost      Cost reduction    Step norm     Optimality   
           0              1         4.7197e+04                                    2.38e+05    
           1              2         1.1139e+03      4.61e+04       4.29e-02       2.93e+04    
           2              3         2.0450e+01      1.09e+03       2.10e-02       9.34e+02    
           3              4         4.2531e+00      1.62e+01       1.37e-01       3.40e+01    
           4              5         2.0365e-01      4.05e+00       2.43e-02       3.74e+00    
           5              6         4.6606e-03      1.99e-01       7.94e-03       2.94e-01    
           6              7         8.5220e-04      3.81e-03       2.27e-03       2.79e-03    
           7              8         5.1948e-04      3.33e-04       3.52e-02       2.22e-03    
           8              9         6.5978e-05      4.53e-04       5.04e-02       1.83e-03    
           9             10         1.0668e-05      5.53e-05       3.50e-02       2.02e-04    
          10             11         1.8076e-06      8.86e-06       2.38e-02       3.71e-05    
          11             12         5.3663e-07      1.27e-06       4.33e-03       7.24e-06    
          12             13         1.7281e-07      3.64e-07       2.20e-02       3.53e-07    
          13             14         3.9390e-08      1.33e-07       1.81e-02       3.64e-07    
          14             15         9.5500e-09      2.98e-08       8.17e-03       7.16e-08    
          15             16         2.3755e-09      7.17e-09       3.92e-03       1.61e-08    
          16             17         5.9364e-10      1.78e-09       1.95e-03       3.95e-09    
    `gtol` termination condition is satisfied.
    Function evaluations 17, initial cost 4.7197e+04, final cost 5.9364e-10, first-order optimality 3.95e-09.

    --------------------------------------------------
    Jacobian analysis of the least squares problem (End of optimization)
    --------------------------------------------------

    Singular values (max/min): 1.035e+04 / 1.594e-02
    Condition number: 6.497e+05

    Singular values and their contribution to the variance:
    |   Index    |  Singular Value λ  |     Var = 1/λ^2      |
    |     0      |     1.035e+04      |      9.330e-09       |
    |     1      |     1.032e+04      |      9.384e-09       |
    |     2      |     1.650e+03      |      3.672e-07       |
    |     3      |     5.728e+02      |      3.048e-06       |
    |     4      |     4.770e+02      |      4.395e-06       |
    |     5      |     2.787e+02      |      1.287e-05       |
    |     6      |     1.180e+02      |      7.186e-05       |
    |     7      |     1.136e+02      |      7.744e-05       |
    |     8      |     2.481e+01      |      1.624e-03       |
    |     9      |     6.169e-01      |      2.627e+00       |
    |     10     |     1.594e-02      |      3.938e+03       |

    Higher and Smallers singular values directions vectors (V^T rows):
    | Parameter  |      Vt[0]      |      Vt[8]      |      Vt[9]      |     Vt[10]      | 
    |     0      |    2.274e-03    |    9.810e-01    |   -8.399e-02    |    4.668e-03    | 
    |     1      |    1.387e-04    |    8.380e-02    |    9.883e-01    |   -1.269e-01    | 
    |     2      |   -3.249e-02    |    2.670e-02    |    1.187e-04    |   -4.404e-07    | 
    |     3      |    4.880e-02    |   -2.921e-02    |   -3.748e-04    |    4.770e-07    | 
    |     4      |    8.859e-06    |    6.068e-03    |    1.269e-01    |    9.919e-01    | 
    |     5      |    5.251e-01    |   -6.223e-05    |    1.069e-04    |   -6.618e-06    | 
    |     6      |    8.265e-01    |   -1.714e-04    |   -9.625e-05    |   -2.265e-06    | 
    |     7      |    1.217e-02    |    3.159e-05    |   -2.192e-06    |    3.107e-08    | 
    |     8      |    1.651e-01    |    6.281e-03    |    5.551e-04    |    1.212e-05    | 
    |     9      |   -1.013e-01    |   -5.751e-03    |    5.130e-04    |   -3.304e-05    | 
    |     10     |   -8.213e-03    |    1.700e-01    |   -7.148e-03    |    2.234e-04    | 

    Estimated variances of the parameters:
    | Parameter  |     Value P     | Var = σ^2 (J.T J)^-1 |  Ratio √V/|P|   |
    |     0      |    9.999e-02    |      6.652e-13       |     0.001 %     |
    |     1      |    5.027e-02    |      4.146e-10       |     0.041 %     |
    |     2      |    1.000e-02    |      3.631e-17       |     0.000 %     |
    |     3      |    1.000e-02    |      4.031e-17       |     0.000 %     |
    |     4      |    8.072e-03    |      2.434e-08       |     1.933 %     |
    |     5      |    1.000e-02    |      1.955e-17       |     0.000 %     |
    |     6      |    2.000e-02    |      1.842e-17       |     0.000 %     |
    |     7      |    3.000e-02    |      2.311e-18       |     0.000 %     |
    |     8      |    1.000e-02    |      4.563e-16       |     0.000 %     |
    |     9      |   -5.000e-02    |      4.840e-16       |     0.000 %     |
    |     10     |    4.000e-02    |      2.443e-15       |     0.000 %     |

    ==================================================



    Optimized Intrinsic Parameters: [1000. 1000.  320.  240.]
    Optimized Distortion Parameters: [0.09998879 0.05027011 0.01       0.01       0.00807235]
    Optimized Extrinsic Parameters: [ 0.01000002  0.02        0.03        0.00999999 -0.04999992  0.03999937]
    Optimization success: True
    Optimization message: `gtol` termination condition is satisfied.
    Optimization cost: 5.936428985593911e-10
    RMSE Real Points: 3.445701375799681e-06
    Error Distortion: 0.0019465171187084626 (1.72%)
    Error Extrinsic: 6.353683766795617e-07 (0.00%)





.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 14.539 seconds)


.. _sphx_glr_download_.._.._docs_source__gallery_optimize_parameters.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: optimize_parameters.ipynb <optimize_parameters.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: optimize_parameters.py <optimize_parameters.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: optimize_parameters.zip <optimize_parameters.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
