def zernike_moments_per_label(vtk_file, order=10, exclude_labels=[-1], scale_input=True, decimate_fraction=0, decimate_smooth=25, verbose=False): """ Compute the Zernike moments per labeled region in a file. Optionally decimate the input mesh. Parameters ---------- vtk_file : string name of VTK surface mesh file containing index scalars (labels) order : integer number of moments to compute exclude_labels : list of integers labels to be excluded scale_input : bool 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 (1 for no decimation) decimate_smooth : integer number of smoothing steps for decimation verbose : bool print statements? Returns ------- descriptors_lists : list of lists of floats Zernike descriptors per label label_list : list of integers list of unique labels for which moments are computed Examples -------- >>> # Zernike moments per label of a FreeSurfer-labeled left cortex. >>> # Uncomment "if label==22:" below to run example >>> # for left postcentral (22) pial surface: >>> import numpy as np >>> from mindboggle.shapes.zernike.zernike import zernike_moments_per_label >>> from mindboggle.mio.fetch_data import prep_tests >>> urls, fetch_data = prep_tests() >>> vtk_file = fetch_data(urls['left_freesurfer_labels'], '', '.vtk') >>> order = 3 >>> exclude_labels = [-1] >>> scale_input = True >>> verbose = False >>> descriptors_lists, label_list = zernike_moments_per_label(vtk_file, ... order, exclude_labels, scale_input, verbose) >>> label_list[0:10] [999, 1001, 1002, 1003, 1005, 1006, 1007, 1008, 1009, 1010] >>> print(np.array_str(np.array(descriptors_lists[0]), ... precision=5, suppress_small=True)) [ 0.00587 0.01143 0.0031 0.00881 0.00107 0.00041] >>> print(np.array_str(np.array(descriptors_lists[1]), ... precision=5, suppress_small=True)) [ 0.00004 0.00009 0.00003 0.00009 0.00002 0.00001] >>> print(np.array_str(np.array(descriptors_lists[2]), ... precision=5, suppress_small=True)) [ 0.00144 0.00232 0.00128 0.00304 0.00084 0.00051] >>> print(np.array_str(np.array(descriptors_lists[3]), ... precision=5, suppress_small=True)) [ 0.00393 0.006 0.00371 0.00852 0.00251 0.00153] >>> print(np.array_str(np.array(descriptors_lists[4]), ... precision=5, suppress_small=True)) [ 0.00043 0.0003 0.00095 0.00051 0.00115 0.00116] """ import numpy as np from mindboggle.mio.vtks import read_vtk from mindboggle.guts.mesh import keep_faces from mindboggle.shapes.zernike.zernike import zernike_moments min_points_faces = 4 # ------------------------------------------------------------------------ # Read VTK surface mesh file: # ------------------------------------------------------------------------ points, indices, lines, faces, labels, scalar_names, npoints, \ input_vtk = read_vtk(vtk_file) # ------------------------------------------------------------------------ # Loop through labeled regions: # ------------------------------------------------------------------------ ulabels = [x for x in np.unique(labels) if x not in exclude_labels] label_list = [] descriptors_lists = [] for label in ulabels: #if label == 1022: # 22: # print("DEBUG: COMPUTE FOR ONLY ONE LABEL") # -------------------------------------------------------------------- # Determine the indices per label: # -------------------------------------------------------------------- Ilabel = [i for i, x in enumerate(labels) if x == label] if verbose: print(' {0} vertices for label {1}'.format(len(Ilabel), label)) if len(Ilabel) > min_points_faces: # ---------------------------------------------------------------- # Remove background faces: # ---------------------------------------------------------------- pick_faces = keep_faces(faces, Ilabel) if len(pick_faces) > min_points_faces: # ------------------------------------------------------------ # Compute Zernike moments for the label: # ------------------------------------------------------------ descriptors = zernike_moments(points, pick_faces, order, scale_input, decimate_fraction, decimate_smooth, verbose) # ------------------------------------------------------------ # Append to a list of lists of spectra: # ------------------------------------------------------------ descriptors_lists.append(descriptors) label_list.append(label) return descriptors_lists, label_list
def zernike_moments_per_label(vtk_file, order=10, exclude_labels=[-1], scale_input=True, decimate_fraction=0, decimate_smooth=25): """ Compute the Zernike moments per labeled region in a file. Optionally decimate the input mesh. Parameters ---------- vtk_file : string name of VTK surface mesh file containing index scalars (labels) order : integer number of moments to compute exclude_labels : list of integers labels to be excluded 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 (1 for no decimation) decimate_smooth : integer number of smoothing steps for decimation Returns ------- descriptors_lists : list of lists of floats Zernike descriptors per label label_list : list of integers list of unique labels for which moments are computed Examples -------- >>> # Uncomment "if label==22:" below to run example: >>> # Twins-2-1 left postcentral (22) pial surface: >>> import os >>> from mindboggle.shapes.zernike.zernike import zernike_moments_per_label >>> path = os.path.join(os.environ['HOME'], 'mindboggled', 'OASIS-TRT-20-1') >>> vtk_file = os.path.join(path, 'labels', 'left_surface', 'relabeled_classifier.vtk') >>> order = 3 >>> exclude_labels = [-1, 0] >>> scale_input = True >>> zernike_moments_per_label(vtk_file, order, exclude_labels, scale_input) ([[0.00528486237819844, 0.009571754617699853, 0.0033489494903015944, 0.00875603468268444, 0.0015879536633349918, 0.0008080165707033097]], [22]) ([[0.0018758013185778298, 0.001757973693050823, 0.002352403177686726, 0.0032281044369938286, 0.002215900343702539, 0.0019646380916703856]], [14.0]) Arthur Mikhno's result: 1.0e+07 * 0.0000 0.0179 0.0008 4.2547 0.0534 4.4043 """ import numpy as np from mindboggle.utils.io_vtk import read_vtk from mindboggle.utils.mesh import remove_faces from mindboggle.shapes.zernike.zernike import zernike_moments min_points_faces = 4 #------------------------------------------------------------------------- # Read VTK surface mesh file: #------------------------------------------------------------------------- faces, u1, u2, points, u3, labels, u4, u5 = read_vtk(vtk_file) #------------------------------------------------------------------------- # Loop through labeled regions: #------------------------------------------------------------------------- ulabels = [x for x in np.unique(labels) if x not in exclude_labels] label_list = [] descriptors_lists = [] for label in ulabels: #if label == 1022: # 22: # print("DEBUG: COMPUTE FOR ONLY ONE LABEL") #--------------------------------------------------------------------- # Determine the indices per label: #--------------------------------------------------------------------- Ilabel = [i for i, x in enumerate(labels) if x == label] print(' {0} vertices for label {1}'.format(len(Ilabel), label)) if len(Ilabel) > min_points_faces: #----------------------------------------------------------------- # Remove background faces: #----------------------------------------------------------------- pick_faces = remove_faces(faces, Ilabel) if len(pick_faces) > min_points_faces: #------------------------------------------------------------- # Compute Zernike moments for the label: #------------------------------------------------------------- descriptors = zernike_moments(points, pick_faces, order, scale_input, decimate_fraction, decimate_smooth) #------------------------------------------------------------- # Append to a list of lists of spectra: #------------------------------------------------------------- descriptors_lists.append(descriptors) label_list.append(label) return descriptors_lists, label_list
def zernike_moments_per_label(vtk_file, order=10, exclude_labels=[-1], scale_input=True, decimate_fraction=0, decimate_smooth=25): """ Compute the Zernike moments per labeled region in a file. Optionally decimate the input mesh. Parameters ---------- vtk_file : string name of VTK surface mesh file containing index scalars (labels) order : integer number of moments to compute exclude_labels : list of integers labels to be excluded 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 (1 for no decimation) decimate_smooth : integer number of smoothing steps for decimation Returns ------- descriptors_lists : list of lists of floats Zernike descriptors per label label_list : list of integers list of unique labels for which moments are computed Examples -------- >>> # Uncomment "if label==22:" below to run example: >>> # Twins-2-1 left postcentral (22) pial surface: >>> import os >>> from mindboggle.shapes.zernike.zernike import zernike_moments_per_label >>> path = os.environ['MINDBOGGLE_DATA'] >>> vtk_file = os.path.join(path, 'arno', 'labels', 'lh.labels.DKT25.manual.vtk') >>> order = 3 >>> exclude_labels = [0] >>> scale_input = True >>> zernike_moments_per_label(vtk_file, order, exclude_labels, scale_input) ([[0.00528486237819844, 0.009571754617699853, 0.0033489494903015944, 0.00875603468268444, 0.0015879536633349918, 0.0008080165707033097]], [22]) ([[0.0018758013185778298, 0.001757973693050823, 0.002352403177686726, 0.0032281044369938286, 0.002215900343702539, 0.0019646380916703856]], [14.0]) Arthur Mikhno's result: 1.0e+07 * 0.0000 0.0179 0.0008 4.2547 0.0534 4.4043 """ import numpy as np from mindboggle.utils.io_vtk import read_vtk from mindboggle.utils.mesh import remove_faces from mindboggle.shapes.zernike.zernike import zernike_moments min_points_faces = 4 #------------------------------------------------------------------------- # Read VTK surface mesh file: #------------------------------------------------------------------------- faces, u1,u2, points, u3, labels, u4,u5 = read_vtk(vtk_file) #------------------------------------------------------------------------- # Loop through labeled regions: #------------------------------------------------------------------------- ulabels = [x for x in np.unique(labels) if x not in exclude_labels] label_list = [] descriptors_lists = [] for label in ulabels: #if label == 22: # print("DEBUG: COMPUTE FOR ONLY ONE LABEL") if label == 14: #--------------------------------------------------------------------- # Determine the indices per label: #--------------------------------------------------------------------- Ilabel = [i for i,x in enumerate(labels) if x == label] print(' {0} vertices for label {1}'.format(len(Ilabel), label)) if len(Ilabel) > min_points_faces: #----------------------------------------------------------------- # Remove background faces: #----------------------------------------------------------------- pick_faces = remove_faces(faces, Ilabel) if len(pick_faces) > min_points_faces: #------------------------------------------------------------- # Compute Zernike moments for the label: #------------------------------------------------------------- descriptors = zernike_moments(points, pick_faces, order, scale_input, decimate_fraction, decimate_smooth) #------------------------------------------------------------- # Append to a list of lists of spectra: #------------------------------------------------------------- descriptors_lists.append(descriptors) label_list.append(label) return descriptors_lists, label_list
def zernike_moments_per_label(vtk_file, order=10, exclude_labels=[-1], scale_input=True, decimate_fraction=0, decimate_smooth=25, verbose=False): """ Compute the Zernike moments per labeled region in a file. Optionally decimate the input mesh. Parameters ---------- vtk_file : string name of VTK surface mesh file containing index scalars (labels) order : integer number of moments to compute exclude_labels : list of integers labels to be excluded scale_input : bool 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 (1 for no decimation) decimate_smooth : integer number of smoothing steps for decimation verbose : bool print statements? Returns ------- descriptors_lists : list of lists of floats Zernike descriptors per label label_list : list of integers list of unique labels for which moments are computed Examples -------- >>> # Zernike moments per label of a FreeSurfer-labeled left cortex. >>> # Uncomment "if label==22:" below to run example >>> # for left postcentral (22) pial surface: >>> import numpy as np >>> from mindboggle.shapes.zernike.zernike import zernike_moments_per_label >>> from mindboggle.mio.fetch_data import prep_tests >>> urls, fetch_data = prep_tests() >>> vtk_file = fetch_data(urls['left_freesurfer_labels']) >>> order = 3 >>> exclude_labels = [-1] >>> scale_input = True >>> verbose = False >>> descriptors_lists, label_list = zernike_moments_per_label(vtk_file, ... order, exclude_labels, scale_input, verbose) >>> label_list[0:10] [999, 1001, 1002, 1003, 1005, 1006, 1007, 1008, 1009, 1010] >>> print(np.array_str(np.array(descriptors_lists[0]), ... precision=5, suppress_small=True)) [ 0.00587 0.01143 0.0031 0.00881 0.00107 0.00041] >>> print(np.array_str(np.array(descriptors_lists[1]), ... precision=5, suppress_small=True)) [ 0.00004 0.00009 0.00003 0.00009 0.00002 0.00001] >>> print(np.array_str(np.array(descriptors_lists[2]), ... precision=5, suppress_small=True)) [ 0.00144 0.00232 0.00128 0.00304 0.00084 0.00051] >>> print(np.array_str(np.array(descriptors_lists[3]), ... precision=5, suppress_small=True)) [ 0.00393 0.006 0.00371 0.00852 0.00251 0.00153] >>> print(np.array_str(np.array(descriptors_lists[4]), ... precision=5, suppress_small=True)) [ 0.00043 0.0003 0.00095 0.00051 0.00115 0.00116] """ import numpy as np from mindboggle.mio.vtks import read_vtk from mindboggle.guts.mesh import keep_faces from mindboggle.shapes.zernike.zernike import zernike_moments min_points_faces = 4 #------------------------------------------------------------------------- # Read VTK surface mesh file: #------------------------------------------------------------------------- points, indices, lines, faces, labels, scalar_names, npoints, \ input_vtk = read_vtk(vtk_file) #------------------------------------------------------------------------- # Loop through labeled regions: #------------------------------------------------------------------------- ulabels = [x for x in np.unique(labels) if x not in exclude_labels] label_list = [] descriptors_lists = [] for label in ulabels: #if label == 1022: # 22: # print("DEBUG: COMPUTE FOR ONLY ONE LABEL") #--------------------------------------------------------------------- # Determine the indices per label: #--------------------------------------------------------------------- Ilabel = [i for i,x in enumerate(labels) if x == label] if verbose: print(' {0} vertices for label {1}'.format(len(Ilabel), label)) if len(Ilabel) > min_points_faces: #----------------------------------------------------------------- # Remove background faces: #----------------------------------------------------------------- pick_faces = keep_faces(faces, Ilabel) if len(pick_faces) > min_points_faces: #------------------------------------------------------------- # Compute Zernike moments for the label: #------------------------------------------------------------- descriptors = zernike_moments(points, pick_faces, order, scale_input, decimate_fraction, decimate_smooth, verbose) #------------------------------------------------------------- # Append to a list of lists of spectra: #------------------------------------------------------------- descriptors_lists.append(descriptors) label_list.append(label) return descriptors_lists, label_list
def zernike_moments_per_label(vtk_file, n_moments, exclude_labels=[-1]): """ Compute the Zernike moments per labeled region in a file. Parameters ---------- vtk_file : string name of VTK surface mesh file containing index scalars (labels) n_moments : integer number of moments to compute exclude_labels : list of integers labels to be excluded Returns ------- moments : numpy matrix Zernike moments label_list : list of integers list of unique labels for which moments are obtained Examples -------- >>> import os >>> from mindboggle.shapes.laplace_beltrami import laplacian_per_label >>> path = os.environ['MINDBOGGLE_DATA'] >>> vtk_file = os.path.join(path, 'arno', 'labels', 'lh.labels.DKT25.manual.vtk') >>> n_moments = 20 >>> zernike_moments_per_label(vtk_file, n_moments, exclude_labels=[-1] """ from mindboggle.utils.io_vtk import read_vtk from mindboggle.utils.mesh import remove_faces from mindboggle.shapes.zernike.zernike import zernike_moments # Read VTK surface mesh file: faces, u1,u2, points, u4, labels, u5,u6 = read_vtk(vtk_file) # Loop through labeled regions: ulabels = [] [ulabels.append(int(x)) for x in labels if x not in ulabels if x not in exclude_labels] label_list = [] moments_lists = [] for label in ulabels: #if label==22: # Determine the indices per label: label_indices = [i for i,x in enumerate(labels) if x == label] print('{0} vertices for label {1}'.format(len(label_indices), label)) # Remove background faces: select_faces = remove_faces(faces, label_indices) # Compute Zernike moments for the label: moments = zernike_moments(points, select_faces, n_moments) # Append to a list of lists of spectra: moments_lists.append(moments) label_list.append(label) return moments_lists, label_list
def zernike_moments_per_label(vtk_file, order=20, exclude_labels=[-1], area_file="", largest_segment=True): """ Compute the Zernike moments per labeled region in a file. Parameters ---------- vtk_file : string name of VTK surface mesh file containing index scalars (labels) order : integer number of moments to compute exclude_labels : list of integers labels to be excluded area_file : string name of VTK file with surface area scalar values largest_segment : Boolean compute moments only for largest segment with a given label? Returns ------- descriptors_lists : list of lists of floats Zernike descriptors per label label_list : list of integers list of unique labels for which moments are computed Examples -------- >>> # Moments for label 22 (postcentral) in Twins-2-1: >>> import os >>> from mindboggle.shapes.zernike.zernike import zernike_moments_per_label >>> path = os.environ['MINDBOGGLE_DATA'] >>> vtk_file = os.path.join(path, 'arno', 'labels', 'lh.labels.DKT25.manual.vtk') >>> area_file = os.path.join(path, 'arno', 'shapes', 'lh.pial.area.vtk') >>> order = 3 >>> exclude_labels = [0] >>> largest_segment = True >>> zernike_moments_per_label(vtk_file, order, exclude_labels, area_file, >>> largest_segment) ([[7562.751480397972, 143262239.5171249, 1107670.7893994227, 28487908892.820065, 112922387.17238183, 10250734140.30357]], [22]) >>> order = 10 >>> zernike_moments_per_label(vtk_file, order, exclude_labels, area_file, >>> largest_segment) ([[7562.751480397972, 143262239.5171249, 3308874674202.293, 8.485211965384958e+16, 2.3330162566631947e+21, 6.743205749389719e+25, 1107670.7893994227, 28487908892.820065, 750581458956752.5, 2.08268406178679e+19, 6.041241636463012e+23, 112922387.17238183, 3771094165018.0186, 1.1436534456761454e+17, 3.475222918728238e+21, 1.0745294340540639e+26, 10250734140.30357, 429344737184365.75, 1.4944306620454633e+19, 4.98685998888202e+23, 889109957039.494, 4.5419095219797416e+16, 1.798809048329269e+21, 6.5720455808877056e+25, 76646448525991.2, 4.648745223427816e+18, 2.067942924550439e+23, 6705825311489244.0, 4.701251187236028e+20, 2.3147665646780795e+25, 5.969381989053711e+17, 4.728007168783364e+22, 5.360784767352255e+19, 4.7214146910478664e+24, 4.813773883638603e+21, 4.3049570618844856e+23]], [22]) """ from mindboggle.utils.io_vtk import read_vtk, read_scalars from mindboggle.utils.mesh import remove_faces from mindboggle.shapes.zernike.zernike import zernike_moments, zernike_moments_of_largest # Read VTK surface mesh file: faces, u1, u2, points, u4, labels, u5, u6 = read_vtk(vtk_file) # Area file: if area_file: areas, u1 = read_scalars(area_file) else: areas = None # Loop through labeled regions: ulabels = [] [ulabels.append(int(x)) for x in labels if x not in ulabels if x not in exclude_labels] label_list = [] descriptors_lists = [] for label in ulabels: # if label==22: # print("DEBUG: COMPUTE FOR ONLY ONE LABEL") # Determine the indices per label: label_indices = [i for i, x in enumerate(labels) if x == label] print("{0} vertices for label {1}".format(len(label_indices), label)) # Remove background faces: select_faces = remove_faces(faces, label_indices) # Compute Zernike moments for the label: if largest_segment: exclude_labels_inner = [-1] descriptors = zernike_moments_of_largest(points, select_faces, order, exclude_labels_inner, areas) else: descriptors = zernike_moments(points, select_faces, order) # Append to a list of lists of spectra: descriptors_lists.append(descriptors) label_list.append(label) return descriptors_lists, label_list
def zernike_moments_of_largest(points, faces, order=20, exclude_labels=[-1], areas=None): """ Compute the Zernike moments on largest connected segment. In case a surface patch is fragmented, we select the largest fragment, remove extraneous triangular faces, and reindex indices. Parameters ---------- points : list of lists of 3 floats x,y,z coordinates for each vertex of the structure faces : list of lists of 3 integers 3 indices to vertices that form a triangle on the mesh order : integer number of moments to compute exclude_labels : list of integers labels to be excluded areas : numpy array or list of floats (or None) surface area scalar values for all vertices Returns ------- descriptors : list of floats Zernike descriptors of largest connected segment Examples -------- >>> # Zernike moments for one label (artificial composite), two fragments: >>> import os >>> import numpy as np >>> from mindboggle.utils.io_vtk import read_scalars, read_vtk, write_vtk >>> from mindboggle.utils.mesh import remove_faces >>> from mindboggle.shapes.zernike.zernike import zernike_moments_of_largest >>> path = os.environ['MINDBOGGLE_DATA'] >>> area_file = os.path.join(path, 'arno', 'shapes', 'lh.pial.area.vtk') >>> label_file = os.path.join(path, 'arno', 'labels', 'lh.labels.DKT31.manual.vtk') >>> order = 3 >>> exclude_labels = [-1] >>> faces, lines, indices, points, u1, labels, u2,u3 = read_vtk(label_file, >>> return_first=True, return_array=True) >>> I19 = [i for i,x in enumerate(labels) if x==19] # pars orbitalis >>> I22 = [i for i,x in enumerate(labels) if x==22] # postcentral >>> I19.extend(I22) >>> faces = remove_faces(faces, I19) >>> areas, u1 = read_scalars(area_file, True, True) >>> # >>> zernike_moments_of_largest(points, faces, order, exclude_labels, areas) [7562.751480397972, 143262239.5171249, 1107670.7893994227, 28487908892.820065, 112922387.17238183, 10250734140.30357] >>> # View two fragments: >>> from mindboggle.utils.plots import plot_vtk >>> scalars = np.zeros(np.shape(labels)) >>> scalars[I19] = 1 >>> vtk_file = 'test_two_labels.vtk' >>> write_vtk(vtk_file, points, indices, lines, faces, >>> scalars, scalar_names='scalars') >>> plot_vtk(vtk_file) """ import numpy as np from mindboggle.utils.segment import select_largest from mindboggle.shapes.zernike.zernike import zernike_moments if isinstance(areas, list): areas = np.array(areas) # Check to see if there are enough points: min_npoints = order npoints = len(points) if npoints < min_npoints or len(faces) < min_npoints: print("The input size {0} ({1} faces) should be larger " "than order {2}".format(npoints, len(faces), order)) return None else: # --------------------------------------------------------------------- # Select the largest segment (connected set of indices): # --------------------------------------------------------------------- points, faces = select_largest(points, faces, exclude_labels, areas, reindex=True) # Alert if the number of indices is small: if len(points) < min_npoints: print("The input size {0} is too small.".format(len(points))) return None elif faces: # ----------------------------------------------------------------- # Compute Zernike moments: # ----------------------------------------------------------------- descriptors = zernike_moments(points, faces, order) return descriptors else: return None