.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_auto_tutorials/plot_matching.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr__auto_tutorials_plot_matching.py: Unstructured Shape Matching =========================== In this tutorial, we register two curves with IMODAL without deformation prior. To achieve this, a local translation deformation module is used. .. GENERATED FROM PYTHON SOURCE LINES 10-15 Initialization -------------- Import relevant Python modules. .. GENERATED FROM PYTHON SOURCE LINES 15-30 .. code-block:: default import sys sys.path.append("../") import math import copy import torch import matplotlib.pyplot as plt import imodal imodal.Utilities.set_compute_backend('torch') .. GENERATED FROM PYTHON SOURCE LINES 31-33 First, we generate the **source** (circle) and the **target** (square) and plot them. .. GENERATED FROM PYTHON SOURCE LINES 33-59 .. code-block:: default # nb_points_source = 50 # radius = 1. # source = radius*imodal.Utilities.generate_unit_circle(nb_points_source) nb_points_square_side = 12 source = imodal.Utilities.generate_unit_square(nb_points_square_side) source = imodal.Utilities.linear_transform(source, imodal.Utilities.rot2d(-math.pi/14.)) nb_points_square_side = 4 target = 0.7*imodal.Utilities.generate_unit_square(nb_points_square_side) target = imodal.Utilities.linear_transform(target, imodal.Utilities.rot2d(math.pi/18.)) plt.figure(figsize=[4., 4.]) imodal.Utilities.plot_closed_shape(source, color='black') imodal.Utilities.plot_closed_shape(target, color='red') plt.axis('equal') plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1) plt.show() .. image:: /_auto_tutorials/images/sphx_glr_plot_matching_001.png :alt: plot matching :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 60-63 From these objects, **DeformablePoints** are created to be used for the registration. This is a sub class of **Deformables** which represents geometrical objects that can be deformed by the framework. .. GENERATED FROM PYTHON SOURCE LINES 63-68 .. code-block:: default source_deformable = imodal.Models.DeformablePoints(source) target_deformable = imodal.Models.DeformablePoints(target) .. GENERATED FROM PYTHON SOURCE LINES 69-72 We define the local translation module **translation**: we need to specify the gaussian kernel scale (**sigma_translation**). We initialize its geometrical descriptor (**gd**) with the source points. .. GENERATED FROM PYTHON SOURCE LINES 72-81 .. code-block:: default sigma_translation = 1. # sigma_translation1 = 0.1 # sigma_translation2 = 0.2 translation = imodal.DeformationModules.ImplicitModule0(2, source.shape[0], sigma_translation, nu=1e-4, gd=source) # translation1 = imodal.DeformationModules.ImplicitModule0(2, source.shape[0], sigma_translation1, gd=source, nu=0.1) # translation2 = imodal.DeformationModules.ImplicitModule0(2, source.shape[0], sigma_translation2, gd=source, nu=0.1) .. GENERATED FROM PYTHON SOURCE LINES 82-86 The distance between the deformed source and the target is measured using the varifold framework, which does not require point correspondance. The spatial kernel is a scalar gaussian kernel for which we specify the scale **sigma_varifold**. .. GENERATED FROM PYTHON SOURCE LINES 86-90 .. code-block:: default sigma_varifold = [0.5] attachment = imodal.Attachment.VarifoldAttachment(2, sigma_varifold, backend='torch') .. GENERATED FROM PYTHON SOURCE LINES 91-97 Registration ------------ We create the registration model. The **lam** parameter is the weight of the attachment term of the total energy to minimize. .. GENERATED FROM PYTHON SOURCE LINES 97-101 .. code-block:: default model = imodal.Models.RegistrationModel(source_deformable, [translation], attachment, lam=100.) .. GENERATED FROM PYTHON SOURCE LINES 102-107 We launch the energy minimization using the **Fitter** class. We specify the ODE solver algorithm **shoot_solver** and the number of iteration steps **shoot_it** used to integrate the shooting equation. The optimizer can be manually selected. Here, we select Pytorch's LBFGS algorithm with strong Wolfe termination conditions. **max_iter** defines the maximum number of iteration for the optimization. .. GENERATED FROM PYTHON SOURCE LINES 107-117 .. code-block:: default shoot_solver = 'euler' shoot_it = 10 fitter = imodal.Models.Fitter(model, optimizer='torch_lbfgs') max_iter = 10 fitter.fit(target_deformable, max_iter, options={'line_search_fn': 'strong_wolfe', 'shoot_solver': shoot_solver, 'shoot_it': shoot_it}) .. rst-class:: sphx-glr-script-out Out: .. code-block:: none Starting optimization with method torch LBFGS, using solver euler with 10 iterations. Initial cost={'deformation': 0.0, 'attach': 54.57539367675781} 1e-10 Evaluated model with costs=54.57539367675781 Evaluated model with costs=19.14338093996048 Evaluated model with costs=6.4000039249658585 Evaluated model with costs=3.1447209417819977 Evaluated model with costs=1.5842044353485107 Evaluated model with costs=9.115530669689178 Evaluated model with costs=1.26090669631958 Evaluated model with costs=0.8082702159881592 Evaluated model with costs=0.602929562330246 Evaluated model with costs=0.4900495111942291 Evaluated model with costs=0.479810893535614 Evaluated model with costs=0.48361146450042725 Evaluated model with costs=0.4796399474143982 Evaluated model with costs=0.47953301668167114 Evaluated model with costs=0.47956109046936035 Evaluated model with costs=0.4795800745487213 Evaluated model with costs=0.4795333743095398 Evaluated model with costs=0.4795810580253601 ================================================================================ Time: 2.8076504664495587 Iteration: 0 Costs deformation=0.3482601046562195 attach=0.13132095336914062 Total cost=0.4795810580253601 1e-10 Evaluated model with costs=0.47953301668167114 Evaluated model with costs=0.47956109046936035 Evaluated model with costs=0.4795800745487213 Evaluated model with costs=0.4795333743095398 Evaluated model with costs=0.4795810580253601 ================================================================================ Time: 3.6211067866533995 Iteration: 1 Costs deformation=0.3482601046562195 attach=0.13132095336914062 Total cost=0.4795810580253601 ================================================================================ Optimisation process exited with message: Convergence achieved. Final cost=0.4795810580253601 Model evaluation count=23 Time elapsed = 3.6212978567928076 .. GENERATED FROM PYTHON SOURCE LINES 118-123 Displaying results ------------------ We compute the optimized deformation. .. GENERATED FROM PYTHON SOURCE LINES 123-129 .. code-block:: default intermediates = {} with torch.autograd.no_grad(): deformed = model.compute_deformed(shoot_solver, shoot_it, intermediates=intermediates)[0][0] .. GENERATED FROM PYTHON SOURCE LINES 130-132 We display the result. .. GENERATED FROM PYTHON SOURCE LINES 132-151 .. code-block:: default display_index = [0, 3, 7, 10] plt.figure(figsize=[3.*len(display_index), 3.]) for count, i in enumerate(display_index): plt.subplot(1, len(display_index), 1+count).set_title("t={}".format(i/10.)) deformed_i = intermediates['states'][i][0].gd imodal.Utilities.plot_closed_shape(source, color='black') imodal.Utilities.plot_closed_shape(target, color='red') imodal.Utilities.plot_closed_shape(deformed_i, color='blue') plt.axis('equal') plt.axis('off') plt.subplots_adjust(left=0., right=1., top=1., bottom=0.) plt.show() .. image:: /_auto_tutorials/images/sphx_glr_plot_matching_002.png :alt: t=0.0, t=0.3, t=0.7, t=1.0 :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 152-155 In order to visualize the deformation, we will compute the grid deformation. We first retrieve the modules and initialize their manifolds (with initial values of geometrical descriptor and momentum). .. GENERATED FROM PYTHON SOURCE LINES 155-159 .. code-block:: default modules = imodal.DeformationModules.CompoundModule(copy.copy(model.modules)) modules.manifold.fill(model.init_manifold.clone()) .. GENERATED FROM PYTHON SOURCE LINES 160-165 We initialize a grid built from a bounding box and a grid resolution. We create a bounding box **aabb** around the source, scaled with a 1.3 factor to enhance the visualization of the deformation. Then, we define the grid resolution **grid_resolution** from the size of each grid gap **square_size**. Finally, we create a silent deformation module **deformation_grid** whose geometrical descriptor is made of the grid points. .. GENERATED FROM PYTHON SOURCE LINES 165-174 .. code-block:: default aabb = imodal.Utilities.AABB.build_from_points(source).scale(1.3) square_size = 0.05 grid_resolution = [math.floor(aabb.width/square_size), math.floor(aabb.height/square_size)] deformation_grid = imodal.DeformationModules.DeformationGrid(aabb, grid_resolution) .. GENERATED FROM PYTHON SOURCE LINES 175-179 We inject the newly created deformation module **deformation_grid** into the list of deformation modules **modules_grid**. We create the hamiltonian structure **hamiltonian** allowing us to integrate the shooting equation. We then recompute the deformation, now tracking the grid deformation. .. GENERATED FROM PYTHON SOURCE LINES 179-187 .. code-block:: default modules_grid = [*modules, deformation_grid] hamiltonian = imodal.HamiltonianDynamic.Hamiltonian(modules_grid) intermediates_grid = {} with torch.autograd.no_grad(): imodal.HamiltonianDynamic.shoot(hamiltonian, shoot_solver, shoot_it, intermediates=intermediates_grid) .. GENERATED FROM PYTHON SOURCE LINES 188-190 We display the result along with the deformation grid. .. GENERATED FROM PYTHON SOURCE LINES 190-215 .. code-block:: default display_index = [0, 3, 7, 10] plt.figure(figsize=[3.*len(display_index), 3.]) for count, i in enumerate(display_index): ax = plt.subplot(1, len(display_index), 1+count) # ax.set_title("t={}".format(i/10.)) deformed_i = intermediates_grid['states'][i][0].gd deformation_grid.manifold.fill_gd(intermediates_grid['states'][i][-1].gd) grid_x, grid_y = deformation_grid.togrid() imodal.Utilities.plot_grid(ax, grid_x, grid_y, color='xkcd:light blue') imodal.Utilities.plot_closed_shape(source, color='black') imodal.Utilities.plot_closed_shape(target, color='red') imodal.Utilities.plot_closed_shape(deformed_i, color='blue') plt.axis('equal') plt.axis('off') plt.subplots_adjust(left=0., right=1., top=1., bottom=0.) plt.show() .. image:: /_auto_tutorials/images/sphx_glr_plot_matching_003.png :alt: plot matching :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 5.546 seconds) .. _sphx_glr_download__auto_tutorials_plot_matching.py: .. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_matching.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_matching.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_