def zernike_moments(V,F) : pl = Pipeline() num_vertices = 3 num_facets = pl.size(F,0) N = 20 # original MATLAB code claims it will only work up to order 20 G = pl.geometric_moments_orig(V,F,N,num_facets,num_vertices) Z = pl.zernike(G,N) Descriptors = pl.feature_extraction(Z,N) return Descriptors
def zernike_moments(points, faces, n_moments=20): """ Compute the Zernike moments of a surface patch of points and faces. Parameters ---------- points : list of lists of 3 floats x,y,z coordinates for each vertex faces : list of lists of 3 integers each list contains indices to vertices that form a triangle on a mesh n_moments : integer number of moments to compute Returns ------- moments : numpy matrix Zernike moments Examples -------- >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> from mindboggle.utils.io_vtk import read_vtk >>> vtk_file = '/drop/MB/data/arno/features/folds.vtk' >>> faces, u1,u2, points, u3,u4,u5,u6 = read_vtk(vtk_file) >>> #points = [[0,0,0], [1,0,0], [0,0,1], [0,1,1], [1,0,1], [0,1,0], [1,1,1], [1,1,0]] >>> #faces = [[0,2,4], [0,1,4], [2,3,4], [3,4,5], [3,5,6], [0,1,7]] >>> n_moments = 20 >>> zernike_moments(points, faces, n_moments) """ import numpy as np from mindboggle.shapes.zernike.multiproc import MultiprocPipeline # Arguments should be numpy arrays: if isinstance(points, list): points = np.array(points) if isinstance(faces, list): faces = np.array(faces) pl = MultiprocPipeline() n_points = np.size(points) n_faces = np.size(faces) G = pl.geometric_moments_orig(points, faces, n_moments, n_faces, n_points) Z = pl.zernike(G, n_points) moments = pl.feature_extraction(Z, n_points) return moments
def zernike_moments(points, faces, order=10, scale_input=True, decimate_fraction=0, decimate_smooth=0): """ Compute the Zernike moments of a surface patch of points and faces. Optionally decimate the input mesh. Note:: Decimation sometimes leads to an error of "Segmentation fault: 11" (Twins-2-1 left label 14 gives such an error only when decimated.) Parameters ---------- points : list of lists of 3 floats x,y,z coordinates for each vertex faces : list of lists of 3 integers each list contains indices to vertices that form a triangle on a mesh order : integer order of the moments being calculated scale_input : Boolean translate and scale each object so it is bounded by a unit sphere? (this is the expected input to zernike_moments()) decimate_fraction : float fraction of mesh faces to remove for decimation (0 for no decimation) decimate_smooth : integer number of smoothing steps for decimation Returns ------- descriptors : list of floats Zernike descriptors Examples -------- >>> # Example 1: simple cube (decimation results in a Segmentation Fault): >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> points = [[0,0,0], [1,0,0], [0,0,1], [0,1,1], [1,0,1], [0,1,0], [1,1,1], [1,1,0]] >>> faces = [[0,2,4], [0,1,4], [2,3,4], [3,4,5], [3,5,6], [0,1,7]] >>> order = 3 >>> scale_input = True >>> zernike_moments(points, faces, order, scale_input) [0.0918881492369654, 0.09357431096617608, 0.04309029164656885, 0.06466432586854755, 0.03820155248327533, 0.04138011726544602] >>> # Example 2: simple cube (with inner diagonal plane): >>> # (decimation doesn't have any effect) >>> import os >>> from mindboggle.utils.io_vtk import read_vtk >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> path = os.environ['MINDBOGGLE_DATA'] >>> vtk_file = os.path.join(path, 'cube.vtk') >>> faces, u1,u2, points, u3,u4,u5,u6 = read_vtk(vtk_file) >>> order = 3 >>> scale_input = True >>> zernike_moments(points, faces, order, scale_input) [0.0, 1.5444366221695725e-21, 0.0, 2.081366518964347e-21, 5.735003646768394e-05, 2.433866250546253e-21] Arthur Mikhno's result: 0 0 0.2831 10.6997 2.1352 11.8542 >>> # Example 2.5: Parallelepiped.vtk: >>> import os >>> from mindboggle.utils.io_vtk import read_vtk >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> path = os.environ['MINDBOGGLE_DATA'] >>> vtk_file = os.path.join(path, 'Parallelepiped.vtk') >>> faces, u1,u2, points, u3,u4,u5,u6 = read_vtk(vtk_file) >>> order = 3 >>> scale_input = True >>> zernike_moments(points, faces, order, scale_input) [0.2652000150907399, 0.27006648207389017, 6.902814314591948e-09, 7.901431343883835e-09, 0.12685697496878662, 5.560135951999606e-09] Arthur Mikhno's result: 0.0251 0.0310 0.0255 0.0451 0.0189 0.0133 >>> # Example 3: Twins-2-1 left postcentral pial surface -- NO decimation: >>> # (zernike_moments took 142 seconds for order = 3 with no decimation) >>> import os >>> from mindboggle.utils.io_vtk import read_vtk >>> from mindboggle.utils.mesh import remove_faces >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> path = os.environ['MINDBOGGLE_DATA'] >>> label_file = os.path.join(path, 'arno', 'labels', 'lh.labels.DKT31.manual.vtk') >>> faces, u1,u2, points, u3, labels, u4,u5 = read_vtk(label_file) >>> I22 = [i for i,x in enumerate(labels) if x==22] # postcentral >>> faces = remove_faces(faces, I22) >>> order = 3 >>> scale_input = True >>> zernike_moments(points, faces, order, scale_input) [0.005558794553842859, 0.009838755429501177, 0.003512500896236744, 0.00899042745665395, 0.001672289910738449, 0.000919469614081582] >>> # Example 5: left postcentral + pars triangularis pial surfaces: >>> import os >>> from mindboggle.utils.io_vtk import read_vtk, write_vtk >>> from mindboggle.utils.mesh import remove_faces >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> path = os.environ['MINDBOGGLE_DATA'] >>> label_file = os.path.join(path, 'arno', 'labels', 'lh.labels.DKT31.manual.vtk') >>> faces, u1,u2, points, u3, labels, u4,u5 = read_vtk(label_file) >>> I20 = [i for i,x in enumerate(labels) if x==20] # pars triangularis >>> I22 = [i for i,x in enumerate(labels) if x==22] # postcentral >>> I22.extend(I20) >>> faces = remove_faces(faces, I22) >>> order = 3 >>> scale_input = True >>> zernike_moments(points, faces, order, scale_input) [0.006591540793309832, 0.010749937070447451, 0.0034900573103799214, 0.008972460360983864, 0.0018220183025464518, 0.0016893113500293917] >>> # View both segments: >>> from mindboggle.utils.plots import plot_surfaces >>> scalars = -1*np.ones(np.shape(labels)) >>> scalars[I22] = 1 >>> vtk_file = 'test_two_labels.vtk' >>> write_vtk(vtk_file, points, [],[], faces, scalars, scalar_names='scalars', scalar_type='int') >>> plot_surfaces(vtk_file) """ import numpy as np from mindboggle.utils.mesh import reindex_faces_0to1 from mindboggle.shapes.zernike.multiproc import MultiprocPipeline from mindboggle.utils.mesh import decimate #------------------------------------------------------------------------- # Convert 0-indices (Python) to 1-indices (Matlab) for all face indices: #------------------------------------------------------------------------- index1 = True if index1: faces = reindex_faces_0to1(faces) # Convert lists to numpy arrays: if isinstance(points, list): points = np.array(points) if isinstance(faces, list): faces = np.array(faces) #------------------------------------------------------------------------- # Translate all points so that they are centered at their mean, # and scale them so that they are bounded by a unit sphere: #------------------------------------------------------------------------- if scale_input: center = np.mean(points, axis=0) points = points - center maxd = np.max(np.sqrt(np.sum(points**2, axis=1))) points = points / maxd #------------------------------------------------------------------------- # Decimate surface: #------------------------------------------------------------------------- if 0 < decimate_fraction < 1: points, faces, u1,u2 = decimate(points, faces, decimate_fraction, decimate_smooth, [], save_vtk=False) # Convert lists to numpy arrays: points = np.array(points) faces = np.array(faces) #------------------------------------------------------------------------- # Multiprocessor pipeline: #------------------------------------------------------------------------- pl = MultiprocPipeline() n_V = 3 n_faces = pl.size(faces, 0) #------------------------------------------------------------------------- # Geometric moments: #------------------------------------------------------------------------- G = pl.geometric_moments_orig(points, faces, order, n_faces, n_V) # Z = pl.zernike(G, order) #------------------------------------------------------------------------- # Extract Zernike descriptors: #------------------------------------------------------------------------- descriptors = pl.feature_extraction(Z, order).tolist() return descriptors
def zernike_moments(points, faces, order=20, index1=True): """ Compute the Zernike moments of a surface patch of points and faces. Parameters ---------- points : list of lists of 3 floats x,y,z coordinates for each vertex faces : list of lists of 3 integers each list contains indices to vertices that form a triangle on a mesh order : integer order of the moments being calculated index1 : Boolean Convert 0-indices (Python) to 1-indices (Matlab) for all face indices? Returns ------- descriptors : list of floats Zernike descriptors Examples -------- >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> points = [[0,0,0], [1,0,0], [0,0,1], [0,1,1], [1,0,1], [0,1,0], [1,1,1], [1,1,0]] >>> faces = [[0,2,4], [0,1,4], [2,3,4], [3,4,5], [3,5,6], [0,1,7]] >>> order = 3 >>> index1 = True >>> zernike_moments(points, faces, order, index1) [0.03978873577297383, 0.07597287228593756, 0.08322411181893402, 0.20233902300388348, 0.117303689366221, 0.1457966728239256] >>> # Moments for label 22 (postcentral) in Twins-2-1 >>> # (after running explode_scalars() with reindex=True): >>> import os >>> from mindboggle.utils.io_vtk import read_vtk >>> from mindboggle.shapes.zernike.zernike import zernike_moments >>> path = os.environ['MINDBOGGLE_DATA'] >>> #vtk_file = os.path.join(path, 'arno', 'labels', 'lh.labels.DKT25.manual.vtk') >>> vtk_file = '/drop/MB/data/arno/labels/exploded_labels/label22.vtk' >>> faces, u1,u2, points, u3,u4,u5,u6 = read_vtk(vtk_file) >>> order = 3 >>> index1 = True >>> zernike_moments(points, faces, order, index1) [7562.751480397972, 143262239.5171249, 1107670.7893994227, 28487908892.820065, 112922387.17238183, 10250734140.30357] """ import numpy as np from mindboggle.utils.mesh import reindex_faces_0to1 from mindboggle.shapes.zernike.multiproc import MultiprocPipeline # Convert 0-indices to 1-indices for all face indices: if index1: faces = reindex_faces_0to1(faces) # Convert lists to numpy arrays: if isinstance(points, list): points = np.array(points) if isinstance(faces, list): faces = np.array(faces) # Multiprocessor pipeline: pl = MultiprocPipeline() n_V = 3 n_faces = pl.size(faces, 0) # Geometric moments: G = pl.geometric_moments_orig(points, faces, order, n_faces, n_V) # Z = pl.zernike(G, order) # Extract Zernike descriptors: descriptors = pl.feature_extraction(Z, order).tolist() return descriptors