def test_error_drop_curvature_quadric(self): """ Asserts the error drops when the mesh resolution is increased""" out = [] for j in range(3): K = [1, 1] # Increase of the number of points quadric = sgps.generate_quadric(K, nstep=[20 + 10 * j, 20 + 10 * j], ax=3, ay=1, random_sampling=False, ratio=0.3, random_distribution_type='gamma') # Computation of estimated curvatures p_curv, d1, d2 = scurv.curvatures_and_derivatives(quadric) k1_estim, k2_estim = p_curv[0, :], p_curv[1, :] # k_gauss_estim = k1_estim * k2_estim k_mean_estim = .5 * (k1_estim + k2_estim) # Computation of analytical curvatures k_mean_analytic = sgps.quadric_curv_mean(K)(np.array( quadric.vertices[:, 0]), np.array(quadric.vertices[:, 1])) k_gauss_analytic = sgps.quadric_curv_gauss(K)(np.array( quadric.vertices[:, 0]), np.array(quadric.vertices[:, 1])) k1_analytic = np.zeros((len(k_mean_analytic))) k2_analytic = np.zeros((len(k_mean_analytic))) for i in range(len(k_mean_analytic)): a, b = np.roots( (1, -2 * k_mean_analytic[i], k_gauss_analytic[i])) k1_analytic[i] = min(a, b) k2_analytic[i] = max(a, b) # /// STATS # k_mean_relative_change = abs( # (k_mean_analytic - k_mean_estim) / k_mean_analytic) k_mean_absolute_change = abs((k_mean_analytic - k_mean_estim)) # k1_relative_change = abs((k1_analytic - k1_estim) / k1_analytic) # k1_absolute_change = abs((k1_analytic - k1_estim)) out += [np.round(np.mean(k_mean_absolute_change), 6)] # Assert the absolute mean error decreases as we increase the number of # points assert (sorted(out, reverse=True) == out)
def test_basic(self): mesh_a = self.sphere_A.copy() mesh_a_save = self.sphere_A.copy() cur, d1, d2 = scurv.curvatures_and_derivatives(mesh_a) # Non modification assert (mesh_a.vertices == mesh_a_save.vertices).all() assert (mesh_a.faces == mesh_a_save.faces).all()
def test_correctness_direction_quadric(self): # Generate a paraboloid K = [1, 0] # Increase of the number of points quadric = sgps.generate_quadric(K, nstep=[20, 20], ax=3, ay=3, random_sampling=False, ratio=0.3, random_distribution_type='gamma', equilateral=True) # ESTIMATED Principal curvature, Direction1, Direction2 p_curv_estim, d1_estim, d2_estim = scurv.curvatures_and_derivatives( quadric) # ANALYTICAL directions analytical_directions = sgps.compute_all_principal_directions_3D( K, quadric.vertices) estimated_directions = np.zeros(analytical_directions.shape) estimated_directions[:, :, 0] = d1_estim estimated_directions[:, :, 1] = d2_estim angular_error_0, dotprods = ut.compare_analytic_estimated_directions( analytical_directions[:, :, 0], estimated_directions) angular_error_0 = 180 * angular_error_0 / np.pi # CORRECTNESS DIRECTION 1 # Number of vertices where the angular error is lower than 20 degrees n_low_error = np.sum(angular_error_0 < 15) # Percentage of vertices where the angular error is lower than 20 # degrees percentage_low_error = (n_low_error / angular_error_0.shape[0]) assert (percentage_low_error > .75) # CORRECTNESS DIRECTION 2 angular_error_1, dotprods = ut.compare_analytic_estimated_directions( analytical_directions[:, :, 1], estimated_directions) angular_error_1 = 180 * angular_error_1 / np.pi # Number of vertices where the angular error is lower than 20 degrees n_low_error = np.sum(angular_error_1 < 15) # Percentage of vertices where the angular error is lower than 20 # degrees percentage_low_error = (n_low_error / angular_error_1.shape[0]) assert (percentage_low_error > .75)
def maxAbsCurvature(mesh): ''' function that returns the maximum of the absolute value of the two principal curvatures. :param mesh: the input surface :return: texture ''' PrincipalCurvatures, PrincipalDir1, PrincipalDir2 = scurv.curvatures_and_derivatives(mesh) maxCurv = np.max(np.absolute(PrincipalCurvatures), axis=0) return maxCurv
def test_error_drop_curvature_sphere(self): out = [] for j in range(3): mesh_a = trimesh.creation.icosphere(subdivisions=j + 1, radius=2) p_curv, d1, d2 = scurv.curvatures_and_derivatives(mesh_a) k1_estim, k2_estim = p_curv k_mean_estim = (k1_estim + k2_estim) * .5 # k_gauss_estim = (k1_estim * k2_estim) out += [np.round(np.mean(k_mean_estim), 6)] assert (sorted(out, reverse=True) == out)
def test_correctness_curvature_sphere(self): # Iterations on radius for i in [1, 2, 4]: precision_A = .000001 precision_B = .000001 with self.subTest(i): # Sphere of radius i mesh_a = trimesh.creation.icosphere(subdivisions=1, radius=float(i)) curv, d1, d2 = scurv.curvatures_and_derivatives(mesh_a) mean_curv = 0.5 * (curv[0, :] + curv[1, :]) gauss_curv = (curv[0, :] * curv[1, :]) shape = mean_curv.shape # The mean curvature in every point is 1/radius analytical_mean = np.full(shape, 1 / i) # The gaussian curvature in every point is 1/radius**2 analytical_gauss = np.full(shape, 1 / i**2) assert (np.isclose(mean_curv, analytical_mean, precision_A).all()) assert (np.isclose(gauss_curv, analytical_gauss, precision_B).all()) # Iterations on subdivisions for i in [1, 2, 3]: precision_A = .000001 precision_B = .000001 with self.subTest(i): # Sphere of radius 2, i subdivisions mesh_a = trimesh.creation.icosphere(subdivisions=i, radius=2) curv, d1, d2 = scurv.curvatures_and_derivatives(mesh_a) mean_curv = 0.5 * (curv[0, :] + curv[1, :]) gauss_curv = (curv[0, :] * curv[1, :]) shape = mean_curv.shape # The curvature in every point is 1/radius analytical_mean = np.full(shape, 1 / 2) # The curvature in every point is 1/radius**2 analytical_gauss = np.full(shape, 1 / 4) assert (np.isclose(mean_curv, analytical_mean, precision_A).all()) assert (np.isclose(analytical_gauss, analytical_gauss, precision_B).all())
def test_correctness_curvature_quadric(self): K = [1, 1] quadric = sgps.generate_quadric(K, nstep=[20, 20], ax=3, ay=1, random_sampling=True, ratio=0.3, random_distribution_type='gamma') # Computation of estimated curvatures p_curv, d1, d2 = scurv.curvatures_and_derivatives(quadric) k1_estim, k2_estim = p_curv[0, :], p_curv[1, :] # k_gauss_estim = k1_estim * k2_estim k_mean_estim = .5 * (k1_estim + k2_estim) # Computation of analytical curvatures k_mean_analytic = sgps.quadric_curv_mean(K)(np.array( quadric.vertices[:, 0]), np.array(quadric.vertices[:, 1])) k_gauss_analytic = sgps.quadric_curv_gauss(K)(np.array( quadric.vertices[:, 0]), np.array(quadric.vertices[:, 1])) k1_analytic = np.zeros((len(k_mean_analytic))) k2_analytic = np.zeros((len(k_mean_analytic))) for i in range(len(k_mean_analytic)): a, b = np.roots((1, -2 * k_mean_analytic[i], k_gauss_analytic[i])) k1_analytic[i] = min(a, b) k2_analytic[i] = max(a, b) # /// STATS k_mean_relative_change = abs( (k_mean_analytic - k_mean_estim) / k_mean_analytic) k_mean_absolute_change = abs((k_mean_analytic - k_mean_estim)) k1_relative_change = abs((k1_analytic - k1_estim) / k1_analytic) # k1_absolute_change = abs((k1_analytic - k1_estim)) a = [] a += [ [ "K_MEAN", "mean", "relative change", np.mean(k_mean_relative_change * 100), "%" ], ("K_MEAN", "std", "relative change", np.std(k_mean_relative_change * 100), "%"), ("K_MEAN", "max", "relative change", np.max(k_mean_relative_change * 100), "%"), [ "K_MEAN", "mean", "absolute change", np.mean(k_mean_absolute_change) ], [ "K_MEAN", "std", "absolute change", np.std(k_mean_absolute_change) ], [ "K_MEAN", "max", "absolute change", np.max(k_mean_absolute_change) ], (" K1", "mean", "relative change", np.mean(k1_relative_change * 100), "%"), (" K1", "std", "relative change", np.std(k1_relative_change * 100), "%"), (" K1", "max", "relative change", np.max(k1_relative_change * 100), "%"), (" K1", "mean", "absolute change", np.mean(k_mean_absolute_change)), (" K1", "std", "absolute change", np.std(k_mean_absolute_change)), (" K1", "max", "absolute change", np.max(k_mean_absolute_change)), ] # PRINT STATS print("----------------------------------------") for i, v in enumerate(a): numeric_value = np.round(v[3], decimals=3) if i == 6: print("----------------------------------------") if len(v) > 4: print('{0:10} {1:5} {2:16} {3:2} {4} {5}'.format( v[0], v[1], v[2], "=", numeric_value, v[4])) else: print('{0:10} {1:5} {2:16} {3:2} {4}'.format( v[0], v[1], v[2], "=", numeric_value)) print("----------------------------------------")
############################################################################### # importation of slam modules import slam.io as sio import slam.plot as splt import slam.curvature as scurv ############################################################################### # loading an examplar mesh mesh_file = '../examples/data/example_mesh.gii' mesh = sio.load_mesh(mesh_file) ############################################################################### # Comptue estimations of principal curvatures PrincipalCurvatures, PrincipalDir1, PrincipalDir2 = \ scurv.curvatures_and_derivatives(mesh) ############################################################################### # Comptue Gauss curvature from principal curvatures gaussian_curv = PrincipalCurvatures[0, :] * PrincipalCurvatures[1, :] ############################################################################### # Comptue mean curvature from principal curvatures mean_curv = 0.5 * (PrincipalCurvatures[0, :] + PrincipalCurvatures[1, :]) ############################################################################### # Plot mean curvature visb_sc = splt.visbrain_plot(mesh=mesh, tex=mean_curv, caption='mean curvature', cblabel='mean curvature')
=================================== example of hinge shaped surface =================================== """ # Authors: Julien Lefevre <*****@*****.**> # License: BSD (3-clause) # sphinx_gallery_thumbnail_number = 2 ############################################################################### # importation of slam modules import slam.plot as splt import slam.curvature as scurv import slam.generate_parametric_surfaces as sgps ############################################################################### # Creating an examplar 3-4-...n hinge mesh hinge_mesh = sgps.generate_hinge(n_hinge=4) mesh_curvatures = scurv.curvatures_and_derivatives(hinge_mesh) mean_curvature = 1 / 2 * mesh_curvatures[0].sum(axis=0) visb_sc = splt.visbrain_plot(mesh=hinge_mesh, tex=mean_curvature, caption='hinge', cblabel='mean curvature') visb_sc.preview()
ay = 1 nstep = 50 mesh = boucher_surface(params, ax, ay, nstep) ########################################################################## # Visualization of the mesh visb_sc = splt.visbrain_plot(mesh=mesh, caption='Boucher mesh', bgcolor=[0.3, 0.5, 0.7]) visb_sc visb_sc.preview() ################################## # Compute dpf for various alpha res = sc.curvatures_and_derivatives(mesh) mean_curvature = res[0].sum(axis=0) alphas = [0.001, 0.01, 0.1, 1, 10, 100] dpfs = sdg.depth_potential_function(mesh, curvature=mean_curvature, alphas=alphas) amplitude_center = [] amplitude_peak = [] index_peak_pos = np.argmax(mesh.vertices[:, 2]) index_peak_neg = np.argmin(mesh.vertices[:, 2]) for i in range(len(dpfs)): amplitude_center.append(dpfs[i][index_peak_neg]) amplitude_peak.append(dpfs[i][index_peak_pos]) plt.semilogx(alphas, amplitude_center)
return fig ############################################################################### # Create quadric mesh nstep = 20 equilateral = True K = [1, 0.5] quadric_mesh = sgps.generate_quadric(K, nstep=[int(nstep), int(nstep)], equilateral=equilateral, ax=1, ay=1, random_sampling=False, ratio=0.2, random_distribution_type='gaussian') ############################################################################### # Compute principal directions of curvature PrincipalCurvatures, PrincipalDir1, PrincipalDir2 = scurv.curvatures_and_derivatives( quadric_mesh) ############################################################################### # Visualization visualize(quadric_mesh, PrincipalDir1) plt.show()
import slam.utils as ut import numpy as np import slam.generate_parametric_surfaces as sgps import slam.io as sio import slam.plot as splt import slam.curvature as scurv ############################################################################### # loading an examplar mesh mesh_file = '../examples/data/example_mesh.gii' mesh = sio.load_mesh(mesh_file) ############################################################################### # Comptue estimations of principal curvatures PrincipalCurvatures, PrincipalDir1, PrincipalDir2 = \ scurv.curvatures_and_derivatives(mesh) ############################################################################### # Comptue Gauss curvature from principal curvatures gaussian_curv = PrincipalCurvatures[0, :] * PrincipalCurvatures[1, :] ############################################################################### # Comptue mean curvature from principal curvatures mean_curv = 0.5 * (PrincipalCurvatures[0, :] + PrincipalCurvatures[1, :]) ############################################################################### # Plot mean curvature visb_sc = splt.visbrain_plot(mesh=mesh, tex=mean_curv, caption='mean curvature', cblabel='mean curvature')