def erode(indices, nedges, neighbor_lists): """ Erode region on a surface mesh. Parameters ---------- indices : list of integers indices of vertices to erode nedges : integer number of edges to erode across neighbor_lists : list of lists of integers each list contains indices to neighboring vertices for each vertex Returns ------- eroded_indices : list of integers indices of original vertices without eroded vertices Examples -------- >>> import os >>> import numpy as np >>> from mindboggle.utils.mesh import find_neighbors_from_file >>> from mindboggle.utils.morph import erode >>> from mindboggle.utils.io_vtk import read_scalars, rewrite_scalars >>> from mindboggle.utils.plots import plot_surfaces >>> path = os.environ['MINDBOGGLE_DATA'] >>> vtk_file = os.path.join(path, 'arno', 'freesurfer', 'lh.pial.vtk') >>> neighbor_lists = find_neighbors_from_file(vtk_file) >>> nedges = 3 >>> # Select a single fold: >>> folds_file = os.path.join(path, 'arno', 'features', 'folds.vtk') >>> folds, name = read_scalars(folds_file, True, True) >>> fold_number = 11 #11 >>> indices = [i for i,x in enumerate(folds) if x == fold_number] >>> # >>> eroded_indices = erode(indices, nedges, neighbor_lists) >>> # >>> # Write results to vtk file and view: >>> IDs = -1 * np.ones(len(folds)) >>> IDs[indices] = 1 >>> IDs[eroded_indices] = 2 >>> rewrite_scalars(vtk_file, 'erode.vtk', IDs, 'eroded_fold', IDs) >>> plot_surfaces('erode.vtk') """ from mindboggle.utils.mesh import find_neighborhood N1 = find_neighborhood(neighbor_lists, indices, nedges=1) N2 = find_neighborhood(neighbor_lists, N1, nedges) eroded_indices = list(frozenset(indices).difference(N2)) return eroded_indices
def rescale_by_neighborhood(input_vtk, indices=[], nedges=10, p=99, set_max_to_1=True, save_file=False, output_filestring='rescaled_scalars', background_value=-1): """ Rescale the scalar values of a VTK file by a percentile value in each vertex's surface mesh neighborhood. Parameters ---------- input_vtk : string name of VTK file with a scalar value for each vertex indices : list of integers (optional) indices of scalars to normalize nedges : integer number or edges from vertex, defining the size of its neighborhood p : float in range of [0,100] percentile used to normalize each scalar set_max_to_1 : Boolean set all rescaled values greater than 1 to 1.0? save_file : Boolean save output VTK file? output_filestring : string (if save_file) name of output file background_value : integer background value Returns ------- rescaled_scalars : list of floats rescaled scalar values rescaled_scalars_file : string (if save_file) name of output VTK file with rescaled scalar values Examples -------- >>> import os >>> from mindboggle.utils.mesh import rescale_by_neighborhood >>> from mindboggle.utils.io_vtk import read_scalars, rewrite_scalars >>> from mindboggle.utils.plots import plot_surfaces >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'shapes', 'lh.pial.travel_depth.vtk') >>> indices = [] >>> nedges = 10 >>> p = 99 >>> set_max_to_1 = True >>> save_file = True >>> output_filestring = 'rescaled_scalars' >>> background_value = -1 >>> # >>> rescaled_scalars, rescaled_scalars_file = rescale_by_neighborhood(input_vtk, >>> indices, nedges, p, set_max_to_1, save_file, output_filestring, background_value) >>> # >>> # View rescaled scalar values per fold: >>> folds_file = os.path.join(path, 'arno', 'features', 'folds.vtk') >>> folds, name = read_scalars(folds_file) >>> # >>> rewrite_scalars(rescaled_scalars_file, rescaled_scalars_file, >>> rescaled_scalars, 'rescaled_depths', folds) >>> plot_surfaces(rescaled_scalars_file) """ import os import numpy as np from mindboggle.utils.io_vtk import read_scalars, rewrite_scalars from mindboggle.utils.mesh import find_neighbors_from_file, find_neighborhood # Load scalars and vertex neighbor lists: scalars, name = read_scalars(input_vtk, True, True) if not indices: indices = [i for i,x in enumerate(scalars) if x != background_value] print(" Rescaling {0} scalar values by neighborhood...".format(len(indices))) neighbor_lists = find_neighbors_from_file(input_vtk) # Loop through vertices: rescaled_scalars = scalars.copy() for index in indices: # Determine the scalars in the vertex's neighborhood: neighborhood = find_neighborhood(neighbor_lists, [index], nedges) # Compute a high neighborhood percentile to normalize vertex's value: normalization_factor = np.percentile(scalars[neighborhood], p) rescaled_scalar = scalars[index] / normalization_factor rescaled_scalars[index] = rescaled_scalar # Make any rescaled value greater than 1 equal to 1: if set_max_to_1: rescaled_scalars[[x for x in indices if rescaled_scalars[x] > 1.0]] = 1 rescaled_scalars = rescaled_scalars.tolist() #------------------------------------------------------------------------- # Return rescaled scalars and file name #------------------------------------------------------------------------- if save_file: rescaled_scalars_file = os.path.join(os.getcwd(), output_filestring + '.vtk') rewrite_scalars(input_vtk, rescaled_scalars_file, rescaled_scalars, 'rescaled_scalars') if not os.path.exists(rescaled_scalars_file): raise(IOError(rescaled_scalars_file + " not found")) else: rescaled_scalars_file = None return rescaled_scalars, rescaled_scalars_file
def rescale_by_neighborhood(input_vtk, indices=[], nedges=10, p=99, set_max_to_1=True, save_file=False, output_filestring='rescaled_scalars', background_value=-1): """ Rescale the scalar values of a VTK file by a percentile value in each vertex's surface mesh neighborhood. Parameters ---------- input_vtk : string name of VTK file with a scalar value for each vertex indices : list of integers (optional) indices of scalars to normalize nedges : integer number or edges from vertex, defining the size of its neighborhood p : float in range of [0,100] percentile used to normalize each scalar set_max_to_1 : Boolean set all rescaled values greater than 1 to 1.0? save_file : Boolean save output VTK file? output_filestring : string (if save_file) name of output file background_value : integer background value Returns ------- rescaled_scalars : list of floats rescaled scalar values rescaled_scalars_file : string (if save_file) name of output VTK file with rescaled scalar values Examples -------- >>> import os >>> from mindboggle.utils.mesh import rescale_by_neighborhood >>> from mindboggle.utils.io_vtk import read_scalars, rewrite_scalars >>> from mindboggle.utils.plots import plot_surfaces >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'shapes', 'lh.pial.travel_depth.vtk') >>> indices = [] >>> nedges = 10 >>> p = 99 >>> set_max_to_1 = True >>> save_file = True >>> output_filestring = 'rescaled_scalars' >>> background_value = -1 >>> # >>> rescaled_scalars, rescaled_scalars_file = rescale_by_neighborhood(input_vtk, >>> indices, nedges, p, set_max_to_1, save_file, output_filestring, background_value) >>> # >>> # View rescaled scalar values per fold: >>> folds_file = os.path.join(path, 'arno', 'features', 'folds.vtk') >>> folds, name = read_scalars(folds_file) >>> # >>> rewrite_scalars(rescaled_scalars_file, rescaled_scalars_file, >>> rescaled_scalars, 'rescaled_depths', folds) >>> plot_surfaces(rescaled_scalars_file) """ import os import numpy as np from mindboggle.utils.io_vtk import read_scalars, rewrite_scalars from mindboggle.utils.mesh import find_neighbors_from_file, find_neighborhood # Load scalars and vertex neighbor lists: scalars, name = read_scalars(input_vtk, True, True) if not indices: indices = [i for i, x in enumerate(scalars) if x != background_value] print(" Rescaling {0} scalar values by neighborhood...".format( len(indices))) neighbor_lists = find_neighbors_from_file(input_vtk) # Loop through vertices: rescaled_scalars = scalars.copy() for index in indices: # Determine the scalars in the vertex's neighborhood: neighborhood = find_neighborhood(neighbor_lists, [index], nedges) # Compute a high neighborhood percentile to normalize vertex's value: normalization_factor = np.percentile(scalars[neighborhood], p) rescaled_scalar = scalars[index] / normalization_factor rescaled_scalars[index] = rescaled_scalar # Make any rescaled value greater than 1 equal to 1: if set_max_to_1: rescaled_scalars[[x for x in indices if rescaled_scalars[x] > 1.0]] = 1 rescaled_scalars = rescaled_scalars.tolist() #------------------------------------------------------------------------- # Return rescaled scalars and file name #------------------------------------------------------------------------- if save_file: rescaled_scalars_file = os.path.join(os.getcwd(), output_filestring + '.vtk') rewrite_scalars(input_vtk, rescaled_scalars_file, rescaled_scalars, 'rescaled_scalars') if not os.path.exists(rescaled_scalars_file): raise (IOError(rescaled_scalars_file + " not found")) else: rescaled_scalars_file = None return rescaled_scalars, rescaled_scalars_file