def save_analyse_regions(viewer): ensure_directory_exists(paths.regions_directory) delete_directory_contents(str(paths.regions_directory)) if volumes: annotations = load_any(paths.annotations) hemispheres = load_any(paths.hemispheres) structures_reference_df = load_structures_as_df( get_structures_path()) print( f"\nSaving summary volumes to: {paths.regions_directory}") for label_layer in label_layers: analyse_region_brain_areas( label_layer, paths.regions_directory, annotations, hemispheres, structures_reference_df, ) print(f"\nSaving regions to: {paths.regions_directory}") for label_layer in label_layers: save_regions_to_file( label_layer, paths.regions_directory, paths.downsampled_image, ) close_viewer(viewer)
def test_pseudo_flatfield(): despeckled = brainio.load_any(despeckled_path) flatfield_validation = brainio.load_any(flatfield_path) flatfield_test = img_tools.pseudo_flatfield(despeckled) flatfield_test = general.scale_and_convert_to_16_bits(flatfield_test) assert (flatfield_validation == flatfield_test).all()
def region_analysis( label_layers, structures_df, regions_directory, annotations_path, hemispheres_path, output_csv_file=None, volumes=True, summarise=True, ): if volumes: print("Calculating region volume distribution") annotations = load_any(annotations_path) hemispheres = load_any(hemispheres_path) print(f"Saving summary volumes to: {regions_directory}") for label_layer in label_layers: analyse_region_brain_areas( label_layer, regions_directory, annotations, hemispheres, structures_df, ) if summarise: if output_csv_file is not None: print("Summarising regions") summarise_brain_regions(label_layers, output_csv_file) print("Finished!\n")
def analysis_run(args, file_name="summary_cell_counts.csv"): args = prep_atlas_conf(args) # if args.structures_file_path is None: # args.structures_file_path = get_structures_path() atlas = brainio.load_any(args.paths.registered_atlas_path) hemisphere = brainio.load_any(args.paths.hemispheres_atlas_path) cells = get_cells_data( args.paths.classification_out_file, cells_only=args.cells_only, ) max_coords = get_max_coords(cells) # Useful for debugging dimensions # structures_reference_df = load_structures_as_df(args.structures_file_path) structures_reference_df = load_structures_as_df(get_structures_path()) atlas_pixel_sizes = get_atlas_pixel_sizes(args.atlas_config) sample_pixel_sizes = args.x_pixel_um, args.y_pixel_um, args.z_pixel_um scales = get_scales( sample_pixel_sizes, atlas_pixel_sizes, args.scale_cell_coordinates ) structures_with_cells = set() for i, cell in enumerate(tqdm(cells)): transform_cell_coords(atlas, cell, scales) structure_id = get_structure_from_coordinates( atlas, cell, max_coords, order=args.coordinates_order, structures_reference_df=structures_reference_df, ) if structure_id is not None: cell.structure_id = structure_id structures_with_cells.add(structure_id) else: continue cell.hemisphere = get_structure_from_coordinates( hemisphere, cell, max_coords, order=args.coordinates_order ) sorted_cell_numbers = get_cells_nbs_df( cells, structures_reference_df, structures_with_cells ) combined_hemispheres = combine_df_hemispheres(sorted_cell_numbers) df = calculate_densities(combined_hemispheres, args.paths.volume_csv_path) df = sanitise_df(df) if not os.path.exists(args.output_dir): os.makedirs(args.output_dir) output_file = os.path.join(args.output_dir, file_name) df.to_csv(output_file, index=False)
def load_cubes_in_dir(directory): cube_list = os.listdir(directory) cubes = [] for file in cube_list: file_path = os.path.join(directory, file) cubes.append(brainio.load_any(file_path)) return cubes
def load_labelled_volume(data, vmin=0, alpha=1, **kwargs): """ Load volume image from .nrrd file. It assume that voxels with value = 0 are empty while voxels with values > 0 are labelles (e.g. to indicate the location of a brain region in a reference atlas) :param data: str, path to file with volume data or 3d numpy array :param vmin: float, values below this numner will be assigned an alpha=0 and not be visualized :param **kwargs: kwargs to pass to the Volume class from vtkplotter :param alpha: float in range [0, 1], transparency [for the part of volume with value > vmin] """ # Load/check volumetric data if isinstance(data, str): # load from file if not os.path.isfile(data): raise FileNotFoundError(f'Volume data file {data} not found') try: data = brainio.load_any(data) except: raise ValueError(f"Could not load volume data from file: {data}") elif not isinstance(data, np.ndarray): raise ValueError( f"Data should be a filepath or np array, not: {data.__type__}") # Create volume and set transparency range vol = Volume(data, alpha=alpha, **kwargs) otf = vol.GetProperty().GetScalarOpacity() otf.RemoveAllPoints() otf.AddPoint(vmin, 0) # set to transparent otf.AddPoint(vmin + .1, alpha) # set to opaque otf.AddPoint(data.max(), alpha) return vol
def get_registered_image(nii_path, registration_dir, overwrite=False): # get file paths basedir = os.path.split(nii_path)[0] output_filename = os.path.join( basedir, "{}_transformed.nii".format(os.path.split(nii_path)[1].split(".")[0]), ) if os.path.isfile(output_filename) and not overwrite: logging.info("Skipping registration as output file already exists") else: destination_image = os.path.join(registration_dir, default_atlas_name) control_point_file = os.path.join(registration_dir, INVERSE_CONTROL_POINT) log_file_path = os.path.join(basedir, "registration_log.txt") error_file_path = os.path.join(basedir, "registration_err.txt") logging.info("Running registration") run_transform( nii_path, output_filename, destination_image, control_point_file, log_file_path, error_file_path, ) return brainio.load_any(output_filename)
def render_all_subregions( atlas_id, out_dir, atlas_path, structures_csv_path, smooth_threshold=0.4, smooth_sigma=10, ): """ renders all children structures of a given id :param atlas_id: :param out_dir: :param atlas_path: :param structures_csv_path: :return: """ df = load_atlas_structures_csv(structures_csv_path) atlas_ids = get_all_structure_children(df, atlas_id) atlas = brainio.load_any(atlas_path) for idx in atlas_ids: region_mask = atlas == idx smoothed_region = smooth_structure(region_mask, threshold=smooth_threshold, sigma=smooth_sigma) brainrender_tools.volume_to_vector_array_to_obj_file( smoothed_region, f"{out_dir}/{idx}.obj")
def __init__( self, atlas, target_brain_path, output_folder, x_pix_um, y_pix_um, z_pix_um, original_orientation="coronal", load_parallel=False, sort_input_file=False, load_atlas=True, n_free_cpus=2, scaling_rounding_decimals=5, ): """ :param str target_brain_path: The path to the brain to be processed (image file, paths file or folder) :param str output_folder: The folder where to store the results :param float x_pix_um: The pixel spacing in the x dimension. It is used to scale the brain to the atlas. :param float y_pix_um: The pixel spacing in the x dimension. It is used to scale the brain to the atlas. :param float z_pix_um: The pixel spacing in the x dimension. It is used to scale the brain to the atlas. :param str original_orientation: :param bool load_parallel: Load planes in parallel using multiprocessing for faster data loading :param bool sort_input_file: If set to true and the input is a filepaths file, it will be naturally sorted """ self.target_brain_path = target_brain_path self.atlas = atlas atlas_pixel_sizes = self.atlas.pix_sizes x_scaling = round(x_pix_um / atlas_pixel_sizes["x"], scaling_rounding_decimals) y_scaling = round(y_pix_um / atlas_pixel_sizes["y"], scaling_rounding_decimals) z_scaling = round(z_pix_um / atlas_pixel_sizes["z"], scaling_rounding_decimals) self.original_orientation = original_orientation logging.info("Loading raw image data") self.target_brain = brainio.load_any( self.target_brain_path, x_scaling, y_scaling, z_scaling, load_parallel=load_parallel, sort_input_file=sort_input_file, n_free_cpus=n_free_cpus, ) self.swap_numpy_to_image_axis() self.output_folder = output_folder if load_atlas: self.atlas.load_all()
def image_to_surface(image_path, obj_file_path, voxel_size=1.0, threshold=0, invert_axes=None, orientation="saggital", step_size=1): """[Saves the surface of an image as an .obj file] Arguments: image_path {[str]} -- [Path of image file] output_file {[obj_file_path]} -- [File to write to] voxel_size {[float]} -- [Voxel size of the image (in um). Only isotropic voxels supported currently] (default: {1}) threshold {[float]} -- [Image threshold to define the surface] (default: {0}) invert_axes {[tuple]} -- [Tuple of axes to invert (if not in the same orientation as the atlas] (default: {None}) """ image = brainio.load_any(image_path) image = reorient_image(image, invert_axes=invert_axes, orientation=orientation) verts, faces, normals, values = \ measure.marching_cubes_lewiner(image, threshold, step_size=step_size) # Scale to atlas spacing if voxel_size is not 1: verts = verts * voxel_size faces = faces + 1 marching_cubes_to_obj((verts, faces, normals, values), obj_file_path)
def get_lesion( reg_dir, allen_structure_id=672, erosion_selem=np.ones((5, 5, 5)), lesion_threshold=0.5, sigma=5, minimum_object_size=8000, otsu_scale_factor=2, transformed_brain_file_fname="registered_downsampled_channel_0.nii", atlas_fname="annotations.nii", output_fname="lesion_mask.nii", ): """ :param atlas_fname: :param otsu_scale_factor: :param transformed_brain_file_fname: :param minimum_object_size: any blobs below this size will be ignored :param sigma: sigma for gaussian filtering :param lesion_threshold: :param reg_dir: directory containing cellfinder/amap registration output files :param allen_structure_id: the id of the structure that contains the lesion :param erosion_selem: :return: """ reg_dir = pathlib.Path(reg_dir) annotations_path = reg_dir / atlas_fname source_image_path = reg_dir / transformed_brain_file_fname if not os.path.isfile(str(source_image_path)): print("channel not in std space... gotta transform") transform_all_channels_to_standard_space(reg_dir) brain_mask = brainio.load_any(str(annotations_path)) == allen_structure_id brain = brainio.load_any(str(source_image_path)) brain_otsu_thresh = threshold_otsu(brain) brain = brain < (brain_otsu_thresh / otsu_scale_factor) brain = brain * brain_mask brain = gaussian(brain, sigma) > lesion_threshold brain = binary_erosion(brain, selem=erosion_selem) brain = skimage.morphology.label(brain) biggest = skimage.morphology.remove_small_objects( brain, min_size=minimum_object_size) save_brain(biggest, annotations_path, reg_dir / output_fname)
def get_region(atlas_ids, atlas_path, smooth=True): atlas = brainio.load_any(atlas_path) all_regions = np.zeros_like(atlas) for id in atlas_ids: region_mask = atlas == id all_regions = np.logical_or(region_mask, all_regions) if smooth: all_regions = smooth_structure(all_regions) return all_regions
def get_fiber_tract_in_standard_space(reg_dir): transform_background_channel_to_standard_space(reg_dir) run_track_viewer(reg_dir) reg_dir = pathlib.Path(reg_dir) segmented_files = glob(str(reg_dir) + "/registered_track*.nii") for segmented_file in segmented_files: brain = brainio.load_any(segmented_file) volume_to_vector_array_to_obj_file( brain, segmented_file.replace(".nii", ".obj"))
def get_lateralised_atlas( atlas_path, hemispheres_path, left_hemisphere_value=2, right_hemisphere_value=1, ): atlas = brainio.load_any(atlas_path) hemispheres = brainio.load_any(hemispheres_path) atlas_left, atlas_right = lateralise_atlas( atlas, hemispheres, left_hemisphere_value=left_hemisphere_value, right_hemisphere_value=right_hemisphere_value, ) unique_vals_left, counts_left = np.unique(atlas_left, return_counts=True) unique_vals_right, counts_right = np.unique(atlas_right, return_counts=True) return unique_vals_left, unique_vals_right, counts_left, counts_right
def prepare_load_nii(nii_path, memory=False): """ Transforms a nii file into the same coordinate space as the raw data :param nii_path: Path to the nii file :param memory: Load data into memory :return: Numpy array in the correct coordinate space """ nii_path = str(nii_path) image = brainio.load_any(nii_path, as_numpy=memory) image = np.swapaxes(image, 2, 0) return image
def get_fiber_track( registered_atlas_path, source_image_path, seed_point, output_path=None, normalising_factor=4, erosion_diameter=5, ): """ gets segmentation image of optical fibers using the background channel and a seed-point, tested on 200um and 400um fibers :param erosion_selem: :param normalising_factor: :param output_path: :param registered_atlas_path: :param source_image_path: :param seed_point: :return: """ brain_mask = brainio.load_any(str(registered_atlas_path)) != 0 brain = brainio.load_any(str(source_image_path)) brain_median_filtered = median(brain) otsu_threshold = threshold_multiotsu(brain_median_filtered)[0] brain_segmentation = (brain_median_filtered < otsu_threshold / normalising_factor) * brain_mask segmentation_eroded = binary_erosion(brain_segmentation, selem=ball(erosion_diameter)) segmentation_eroded_dilated = binary_dilation(segmentation_eroded) fiber_track_image = flood(segmentation_eroded_dilated.astype(np.int16), seed_point) if output_path is not None: save_brain(fiber_track_image, source_image_path, output_path) else: return fiber_track_image
def load_volume_file(filepath): """ Load a volume file (e.g., .nii) and returns the data :param filepath: path to file :param **kwargs: """ try: volume = brainio.load_any(filepath) except Exception as e: raise ValueError(f"Could not load volume data: {filepath}:\n {e}") else: return volume
def load_volume_file(filepath): """ Load a volume file (e.g., .nii) and returns the data :param filepath: path to file :param **kwargs: """ if not os.path.isfile(filepath): raise FileNotFoundError(filepath) try: volume = brainio.load_any(filepath) except: raise ValueError(f"Could not load volume data: {filepath}") else: return volume
def get_arbitrary_structure_mask_from_custom_atlas(atlas_ids, atlas_path, sigma, smoothing_threshold): """ uses id numbers from custom atlas to generate a smoothed mask of those ids combined :param atlas_ids: :param atlas_path: :param sigma: :param smoothing_threshold: :return: """ atlas = brainio.load_any(atlas_path) all_regions = np.zeros_like(atlas) for id in atlas_ids: region_mask = atlas == id all_regions = np.logical_or(region_mask, all_regions) all_regions = smooth_structure(all_regions, threshold=smoothing_threshold, sigma=sigma) return all_regions
def get_registered_image(nii_path, registration_dir, logging, overwrite=False): # get binaries nifty_reg_binaries_folder = source_files.get_niftyreg_binaries() program_path = get_binary(nifty_reg_binaries_folder, PROGRAM_NAME) # get file paths basedir = os.path.split(nii_path)[0] output_filename = os.path.join( basedir, "{}_transformed.nii".format(os.path.split(nii_path)[1].split(".")[0]), ) if os.path.isfile(output_filename) and not overwrite: run = False else: run = True if run: destination_image = os.path.join(registration_dir, default_atlas_name) control_point_file = os.path.join(registration_dir, DEFAULT_CONTROL_POINT_FILE) log_file_path = os.path.join(basedir, "registration_log.txt") error_file_path = os.path.join(basedir, "registration_err.txt") reg_cmd = prepare_segmentation_cmd( program_path, nii_path, output_filename, destination_image, control_point_file, ) logging.info("Running registration") try: safe_execute_command(reg_cmd, log_file_path, error_file_path) except SafeExecuteCommandError as err: raise RegistrationError("Registration failed; {}".format(err)) else: logging.info("Skipping registration as output file already exists") return brainio.load_any(output_filename)
def image_to_surface(image_path, obj_file_path, voxel_size=1.0, threshold=0, invert_axes=None, orientation="saggital", step_size=1): """ Saves the surface of an image as an .obj file :param image_path: str :param output_file: obj_file_path :param voxel_size: float (Default value = 1.0) :param threshold: float (Default value = 0) :param invert_axes: tuple (Default value = None) :param obj_file_path: :param orientation: (Default value = "saggital") :param step_size: (Default value = 1) """ image = brainio.load_any(image_path) image = reorient_image(image, invert_axes=invert_axes, orientation=orientation) verts, faces, normals, values = \ measure.marching_cubes_lewiner(image, threshold, step_size=step_size) # Scale to atlas spacing if voxel_size is not 1: verts = verts * voxel_size faces = faces + 1 marching_cubes_to_obj((verts, faces, normals, values), obj_file_path)
def main(): args = parser_3d_view().parse_args() data = brainio.load_any(args.image, load_parallel=args.parallel) with napari.gui_qt(): v = napari.Viewer(title="Cellfinder 3D viewer", ndisplay=3) v.add_image(data)
def xml_crop(args, df_query="name"): args = prep_atlas_conf(args) if args.structures_file_path is None: args.structures_file_path = get_structures_path() reference_struct_df = pd.read_csv(get_structures_path()) curate_struct_df = pd.read_csv(args.structures_file_path) curate_struct_df = reference_struct_df[ reference_struct_df[df_query].isin(curate_struct_df[df_query]) ] curated_ids = list(curate_struct_df["structure_id_path"]) atlas = brainio.load_any(args.registered_atlas_path) hemisphere = brainio.load_any(args.hemispheres_atlas_path) structures_reference_df = load_structures_as_df(get_structures_path()) atlas_pixel_sizes = get_atlas_pixel_sizes(args.atlas_config) sample_pixel_sizes = args.x_pixel_um, args.y_pixel_um, args.z_pixel_um scales = cells_regions.get_scales(sample_pixel_sizes, atlas_pixel_sizes) destination_folder = os.path.join(args.xml_dir, "xml_crop") if not os.path.exists(destination_folder): os.makedirs(destination_folder) xml_names = [f for f in os.listdir(args.xml_dir) if f.endswith(".xml")] xml_paths = [os.path.join(args.xml_dir, f) for f in xml_names] for idx, xml_path in enumerate(xml_paths): print("Curating file: {}".format(xml_names[idx])) cells = cells_regions.get_cells_data( xml_path, cells_only=args.cells_only, ) max_coords = cells_regions.get_max_coords(cells) curated_cells = [] for i, cell in enumerate(cells): cells_regions.transform_cell_coords(atlas, cell, scales) structure_id = cells_regions.get_structure_from_coordinates( atlas, cell, max_coords, order=args.coordinates_order, structures_reference_df=structures_reference_df, ) if structure_id in curated_ids: if args.hemisphere_query in [1, 2]: hemisphere = cells_regions.get_structure_from_coordinates( hemisphere, cell, max_coords, order=args.coordinates_order, ) if hemisphere is args.hemisphere_query: curated_cells.append(cell) else: curated_cells.append(cell) cells_to_xml( curated_cells, os.path.join(destination_folder, xml_names[idx]), artifact_keep=True, ) print("Done!")
def transform_rois( roi_file, source_image_filename, destination_image_filename, control_point_file, output_filename, temp_output_filename, log_file_path, error_file_path, roi_reference_image=None, selem_size=15, nii_scale=None, transformation_matrix=None, debug=False, print_value_round_decimals=2, z_filter_padding=2, ): """ Using a source image (e.g. downsampled stack), transform an ImageJ zipped collection of ROIs into the coordinate space of a destination image (e.g. an atlas), using the inverse control point file from an existing niftyreg registration :param roi_file: .zip collection of ImageJ ROIs :param source_image_filename: Image that the ROIs are defined in :param destination_image_filename: Image in the destination coordinate space :param control_point_file: Transformation from source to destination :param output_filename: output filename for the resulting nifti file :param temp_output_filename: Temporary file for registration :param log_file_path: Path to save niftyreg logs :param error_file_path: Path to save niftyreg errors :param roi_reference_image: Image on which the ROIs are defined (if not the downsampled image in the registration directory) :param selem_size: Structure element size for closing :param nii_scale: Scaling to correctly save the temporary nifti image :param transformation_matrix: Affine transform for the temporary nifti image :param print_value_round_decimals: How many decimal places to round values printed to console. :param z_filter_padding: Size of the filter in z when correcting for unlabled slices. :param debug: If True, don't delete temporary files """ print("Loading ROIs") rois = read_roi_zip(roi_file) number_rois = len(rois) print(f"{number_rois} rois found") x = [] y = [] z = [] for key in rois: for position in range(0, len(rois[key]["x"])): x.append(rois[key]["x"][position]) y.append(rois[key]["y"][position]) z.append(rois[key]["position"]) print("Loading downsampled image image") downsampled_source_image = brainio.load_any(str(source_image_filename)) print(f"Source image size: " f"x:{downsampled_source_image.shape[0]}, " f"y:{downsampled_source_image.shape[1]}, " f"y:{downsampled_source_image.shape[2]}") downsampled_source_image[:] = 0 if roi_reference_image is not None: print("Reference image flag used. Loading reference image") reference_image_shape = brainio.get_size_image_from_file_paths( roi_reference_image) print(f"Reference image shape is " f"x:{reference_image_shape['x']}, " f"y:{reference_image_shape['y']}, " f"z:{reference_image_shape['z']}") x_downsample_factor = (reference_image_shape["x"] / downsampled_source_image.shape[0]) y_downsample_factor = (reference_image_shape["y"] / downsampled_source_image.shape[1]) z_downsample_factor = (reference_image_shape["z"] / downsampled_source_image.shape[2]) print(f"ROIs will be downsampled by a factor of " f"x:{round(x_downsample_factor, print_value_round_decimals)}, " f"y:{round(y_downsample_factor, print_value_round_decimals)}, " f"z:{round(z_downsample_factor, print_value_round_decimals)}") # TODO: optimise this print("Creating temporary ROI image") for position in range(0, len(x)): if roi_reference_image is None: downsampled_source_image[x[position], y[position], z[position]] = 1 else: x_scale = int(round(x[position] / x_downsample_factor)) y_scale = int(round(y[position] / y_downsample_factor)) z_scale = int(round(z[position] / z_downsample_factor)) downsampled_source_image[x_scale, y_scale, z_scale] = 1 print("Cleaning up ROI image") # TODO speed this up - parallelise? selem = morphology.selem.square(selem_size) for plane in tqdm(range(0, downsampled_source_image.shape[2])): tmp = morphology.binary.binary_closing(downsampled_source_image[:, :, plane], selem=selem) tmp = morphology.convex_hull_object(tmp) downsampled_source_image[:, :, plane] = morphology.binary.binary_closing( tmp, selem=selem) if roi_reference_image is not None: if z_downsample_factor < 1: print("ROI was defined at a lower z-resolution than the atlas. " "Correcting with a maximum filter") z_filter_size = int(round(1 / z_scale)) + z_filter_padding downsampled_source_image = maximum_filter1d( downsampled_source_image, z_filter_size, axis=2) print(f"Saving temporary ROI image at: {temp_output_filename}") brainio.to_nii( downsampled_source_image, str(temp_output_filename), scale=nii_scale, affine_transform=transformation_matrix, ) print("Preparing ROI registration") nifty_reg_binaries_folder = get_niftyreg_binaries() program_path = get_binary(nifty_reg_binaries_folder, PROGRAM_NAME) reg_cmd = prepare_segmentation_cmd( program_path, temp_output_filename, output_filename, destination_image_filename, control_point_file, ) print("Running ROI registration") try: safe_execute_command(reg_cmd, log_file_path, error_file_path) except SafeExecuteCommandError as err: raise RegistrationError("ROI registration failed; {}".format(err)) print(f"Registered ROI image can be found at {output_filename}") if not debug: print("Deleting temporary files") remove(temp_output_filename) remove(log_file_path) remove(error_file_path)
left_hemisphere_value = 2 right_hemisphere_value = 1 properties_to_fetch = ["area", "bbox", "centroid"] structures_reference_df = load_structures_as_df(get_structures_path()) region_value = int(structures_reference_df[structures_reference_df["acronym"] == region_acronym]["id"]) region_search_string = "/" + str(region_value) + "/" sub_regions = structures_reference_df[structures_reference_df[ "structure_id_path"].str.contains(region_search_string)] amap_output_dir = Path(amap_output_dir) annotations_image = load_any(amap_output_dir / reg_paths.ANNOTATIONS) midpoint = int(annotations_image.shape[0] // 2) hemispheres_image = load_any(amap_output_dir / reg_paths.HEMISPHERES) sub_region_values = list(sub_regions["id"]) region_mask = np.isin(annotations_image, sub_region_values) left_region_mask = region_mask * (hemispheres_image == left_hemisphere_value) right_region_mask = region_mask * (hemispheres_image == right_hemisphere_value) left_region_summary = regionprops(left_region_mask.astype(np.int8))[0] right_region_summary = regionprops(right_region_mask.astype(np.int8))[0] atlas_pixel_sizes = get_atlas_pixel_sizes(source_custom_config_amap())
def test_despeckle_by_opening(): img_test = brainio.load_any(raw_img_path) despeckled = brainio.load_any(despeckled_path) assert (despeckled == img_tools.despeckle_by_opening(img_test)).all()
def get_lesion_sizes(reg_dir): reg_dir = pathlib.Path(reg_dir) labels = brainio.load_any(str(reg_dir / "lesion_mask.nii")) all_structures_ids = np.unique(labels) return [np.count_nonzero(labels == idx) for idx in all_structures_ids]
def add_single_image(self, file): image = brainio.load_any(file, as_numpy=memory) # This should be generalised image = np.swapaxes(image, 2, 0) image = np.rot90(image, axes=(1, 2), k=3) self.viewer.add_image(image, name=file.stem)