def volume_per_brain_region(input_file, include_labels=[], exclude_labels=[], label_names=[], save_table=False, output_table='', verbose=False): """ Compute volume per labeled region in a nibabel-readable image. Computing the volume per labeled region is very straightforward: this function simply multiplies the volume per voxel by the number of voxels per region. Note: Results are truncated at three decimal places because we found that volume label propagation led to differences in the third decimal place. Parameters ---------- input_file : string name of image file, consisting of index-labeled pixels/voxels include_labels : list of integers labels to include (if empty, use unique numbers in image volume file) exclude_labels : list of integers labels to be excluded label_names : list of strings label names corresponding to labels to include save_table : bool save output table file with labels and volume values? output_table : string name of output table file with labels and volume values verbose : bool print statements? Returns ------- unique_labels : list of integers unique label numbers (default -1) volumes : list of floats volume for each label (default -1) output_table : string name of output volume table file (if output_table not empty) Examples -------- >>> import os >>> import numpy as np >>> from mindboggle.mio.labels import DKTprotocol >>> from mindboggle.shapes.volume_shapes import volume_per_brain_region >>> from mindboggle.mio.fetch_data import prep_tests >>> urls, fetch_data = prep_tests() >>> input_file = fetch_data(urls['freesurfer_labels'], '', '.nii.gz') >>> dkt = DKTprotocol() >>> include_labels = dkt.label_numbers >>> exclude_labels = [] >>> label_names = dkt.label_names >>> save_table = True >>> output_table = 'volumes.csv' >>> verbose = False >>> unique_labels, volumes, table = volume_per_brain_region(input_file, ... include_labels, exclude_labels, label_names, save_table, ... output_table, verbose) >>> [np.float("{0:.{1}f}".format(x, 5)) ... for x in [y for y in volumes if y > 0][0:5]] [971.99797, 2413.99496, 2192.99543, 8328.98262, 2940.99386] >>> [np.float("{0:.{1}f}".format(x, 5)) ... for x in [y for y in volumes if y > 0][5:10]] [1997.99583, 10905.97725, 11318.97639, 10789.97749, 2700.99437] """ import os import numpy as np import nibabel as nb from io import open from mindboggle.guts.compute import count_per_label # Load labeled image volumes: img = nb.load(input_file) volume_per_voxel = np.product(img.header.get_zooms()) labels = img.get_data().ravel() unique_labels, counts = count_per_label(labels, include_labels, exclude_labels) volumes = [volume_per_voxel * x for x in counts] # Output table: if save_table: if output_table: output_table = os.path.join(os.getcwd(), output_table) else: output_table = os.path.join(os.getcwd(), 'volume_for_each_label.csv') fid = open(output_table, 'w', encoding='utf-8') if len(label_names) == len(unique_labels): fid.write("name, ID, volume\n") else: fid.write("ID, volume\n") # Loop through labels: for ilabel, label in enumerate(unique_labels): if volumes[ilabel]: if len(label_names) == len(unique_labels): if verbose: print('{0} ({1}) volume = {2:2.3f}mm^3\n'.format( label_names[ilabel], label, volumes[ilabel])) fid.write('{0}, {1}, {2:2.3f}\n'.format( label_names[ilabel], label, volumes[ilabel])) else: if verbose: print('{0} volume = {1:2.3f}mm^3\n'.format( label, volumes[ilabel])) fid.write('{0}, {1:2.3f}\n'.format(label, volumes[ilabel])) else: output_table = '' return unique_labels, volumes, output_table
def volume_per_brain_region(input_file, include_labels=[], exclude_labels=[], label_names=[], save_table=False, output_table='', verbose=False): """ Compute volume per labeled region in a nibabel-readable image. Note: Results are truncated at three decimal places because we found that volume label propagation led to differences in the third decimal place. Parameters ---------- input_file : string name of image file, consisting of index-labeled pixels/voxels include_labels : list of integers labels to include (if empty, use unique numbers in image volume file) exclude_labels : list of integers labels to be excluded label_names : list of strings label names corresponding to labels to include save_table : bool save output table file with labels and volume values? output_table : string name of output table file with labels and volume values verbose : bool print statements? Returns ------- unique_labels : list of integers unique label numbers (default -1) volumes : list of floats volume for each label (default -1) output_table : string name of output volume table file (if output_table not empty) Examples -------- >>> import os >>> import numpy as np >>> from mindboggle.mio.labels import DKTprotocol >>> from mindboggle.shapes.volume_shapes import volume_per_brain_region >>> from mindboggle.mio.fetch_data import prep_tests >>> urls, fetch_data = prep_tests() >>> input_file = fetch_data(urls['freesurfer_labels']) >>> dkt = DKTprotocol() >>> include_labels = dkt.label_numbers >>> exclude_labels = [] >>> label_names = dkt.label_names >>> save_table = True >>> output_table = 'volumes.csv' >>> verbose = False >>> unique_labels, volumes, table = volume_per_brain_region(input_file, ... include_labels, exclude_labels, label_names, save_table, ... output_table, verbose) >>> print(np.array_str(np.array(volumes[0:5]), ... precision=5, suppress_small=True)) [ 971.99797 2413.99496 2192.99543 8328.98262 2940.99386] >>> print(np.array_str(np.array(volumes[5:10]), ... precision=5, suppress_small=True)) [ 1997.99583 10905.97725 11318.97639 10789.97749 2700.99437] """ import os import numpy as np import nibabel as nb from io import open from mindboggle.guts.compute import count_per_label # Load labeled image volumes: img = nb.load(input_file) hdr = img.get_header() volume_per_voxel = np.product(hdr.get_zooms()) labels = img.get_data().ravel() unique_labels, counts = count_per_label(labels, include_labels, exclude_labels) volumes = [volume_per_voxel * x for x in counts] # Output table: if save_table: if output_table: output_table = os.path.join(os.getcwd(), output_table) else: output_table = os.path.join(os.getcwd(), 'volume_for_each_label.csv') fid = open(output_table, 'w') if len(label_names) == len(unique_labels): fid.write("name, ID, volume\n") else: fid.write("ID, volume\n") # Loop through labels: for ilabel, label in enumerate(unique_labels): if volumes[ilabel]: if len(label_names) == len(unique_labels): if verbose: print('{0} ({1}) volume = {2:2.3f}mm^3\n'.format( label_names[ilabel], label, volumes[ilabel])) fid.write('{0}, {1}, {2:2.3f}\n'.format( label_names[ilabel], label, volumes[ilabel])) else: if verbose: print('{0} volume = {1:2.3f}mm^3\n'.format( label, volumes[ilabel])) fid.write('{0}, {1:2.3f}\n'.format(label, volumes[ilabel])) else: output_table = '' return unique_labels, volumes, output_table
def volume_per_brain_region(input_file, include_labels=[], exclude_labels=[], label_names=[], save_table=False, output_table=''): """ Compute volume per labeled region in a nibabel-readable image. Note: Results are truncated at three decimal places because we found that volume label propagation led to differences in the third decimal place. Parameters ---------- input_file : string name of image file, consisting of index-labeled pixels/voxels include_labels : list of integers labels to include (if empty, use unique numbers in image volume file) exclude_labels : list of integers labels to be excluded label_names : list of strings label names corresponding to labels to include save_table : Boolean save output table file with labels and volume values? output_table : string name of output table file with labels and volume values Returns ------- unique_labels : list of integers unique label numbers (default -1) volumes : list of floats volume for each label (default -1) output_table : string name of output volume table file (if output_table not empty) Examples -------- >>> import os >>> from mindboggle.mio.labels import DKTprotocol >>> from mindboggle.shapes.volume_shapes import volume_per_brain_region >>> input_file = os.path.join(os.environ['HOME'], 'mindboggled', 'Twins-2-1old', 'labels', 'ants_filled_labels.nii.gz') >>> dkt = DKTprotocol() >>> include_labels = dkt.label_numbers >>> exclude_labels = [] >>> label_names = dkt.label_names >>> save_table = True >>> output_table = 'volumes.csv' >>> unique_labels, volumes, output_table = volume_per_brain_region(input_file, include_labels, exclude_labels, label_names, save_table, output_table) >>> print(volumes) """ import os import numpy as np import nibabel as nb from mindboggle.guts.compute import count_per_label # Load labeled image volumes: img = nb.load(input_file) hdr = img.get_header() volume_per_voxel = np.product(hdr.get_zooms()) labels = img.get_data().ravel() unique_labels, counts = count_per_label(labels, include_labels, exclude_labels) volumes = [volume_per_voxel * x for x in counts] # Output table: if save_table: if output_table: output_table = os.path.join(os.getcwd(), output_table) else: output_table = os.path.join(os.getcwd(), 'volume_for_each_label.csv') fid = open(output_table, 'w') if len(label_names) == len(unique_labels): fid.write("name, ID, volume\n") else: fid.write("ID, volume\n") # Loop through labels: for ilabel, label in enumerate(unique_labels): if len(label_names) == len(unique_labels): fid.write('{0}, {1}, {2:2.3f}\n'.format( label_names[ilabel], label, volumes[ilabel])) else: fid.write('{0}, {1:2.3f}\n'.format(label, volumes[ilabel])) else: output_table = '' return unique_labels, volumes, output_table