def main(): """ Executes all methods given above in the correct order """ # |>-<-><-><-><-><-><-><-<| # |>- Process arguments -<| # |>-<-><-><-><-><-><-><-<| output_data_path, input_data_path = get_data_paths_from_args() patient = input_data_path.name print(f"\nstage-07 current patient: {patient}\n") # |>-<-><-><-><->-<| # |>- Load graph -<| # |>-<-><-><-><->-<| graph = load_graph(input_data_path / "tree.graphml") # |>-<-><-><-><-><-<| # |>- Write lobes -<| # |>-<-><-><-><-><-<| if not output_data_path.exists(): output_data_path.mkdir(parents=True) nx.write_graphml(graph, output_data_path / "tree.graphml") # Store subtrees and connection statistics create_subtrees(graph, patient, output_data_path)
def get_inputs(): output_data_path, tree_input_path = get_data_paths_from_args(inputs=1) config_path = Path("configs") / "classification.yaml" with open(config_path) as config_file: classification_config = yaml.load(config_file, yaml.FullLoader) tree = nx.read_graphml(tree_input_path / "tree.graphml") output_path = output_data_path / "tree.graphml" return output_path, tree, classification_config
def main(): """ Executes procedures in right order """ output_data_path, input_data_path = get_data_paths_from_args() lobe_graph_dict = build_connection_matrix(input_data_path) plot_connection_status(output_data_path / 'connection-status.png', lobe_graph_dict)
def main(): output_data_path, input_data_path = get_data_paths_from_args() data = read_metadata(input_data_path) formatted_data = reformat_data(data) first_row = True for patient in formatted_data: print('| ', ' | '.join(patient), ' |', sep='') if first_row: print("|:----" * len(patient), end='|\n') first_row = False write_table(output_data_path, formatted_data)
def main(): output_data_path, reduced_model_path, distance_mask_path, tree_path, = get_data_paths_from_args( inputs=3) model = np.load(reduced_model_path / "reduced_model.npz")['arr_0'] distance_mask = np.load(distance_mask_path / "distance_mask.npz")['arr_0'] # np_dist = np.full(model.shape, 0) # for (x, y, z), val in distances.items(): # np_dist[x, y, z] = val # lu_lobe = nx.read_graphml(tree_path / f"lobe-3-{tree_path.name}.graphml") tree = nx.read_graphml(tree_path / f"tree.graphml") # lu_traversing = nx.bfs_successors(lu_lobe, "5") color_mask = np.full(model.shape, 0) color_hex_codes = [color_hex_to_floats('ffffff')] map_node_id_to_color = {} nodes_visit_order = [] first_node = list(tree.nodes)[0] for curr_color, (node_index, successors) in enumerate(nx.bfs_successors( tree, first_node), start=1): node = tree.nodes[node_index] # point = find_legal_point(node, distances, node["group"]) point = (round(node['x']), round(node['y']), round(node['z'])) radius = node['group_size'] / 2 nodes_visit_order.append((node, point, curr_color, radius)) if 'color' in node: color_hex_codes.append(color_hex_to_floats(node['color'])) elif node_index in map_node_id_to_color: color_hex_codes.append( get_color_variation(map_node_id_to_color[node_index])) else: color_hex_codes.append(color_hex_to_floats("ffffff")) for s in successors: map_node_id_to_color[s] = get_color_variation(color_hex_codes[-1]) # fill_sphere_around_point(radius, point, model, color_mask, curr_color) # fill_color_mask_with_bfs(point, color_mask, curr_color, model, distance_mask) print(color_hex_codes) for node, point, curr_color, radius in reversed(nodes_visit_order): fill_color_mask_with_bfs(point, color_mask, curr_color, model, distance_mask, radius) print("Colors:") for color, occ in zip(*np.unique(color_mask, return_counts=True)): print(f"Color {color} appears {occ:,} times in color mask") np.savez_compressed(output_data_path / "bronchus_color_mask.npz", color_mask=color_mask, color_codes=np.array(color_hex_codes))
def main(): output_data_path, tree_input_data_path, reduced_model_data_path = get_data_paths_from_args( inputs=2) patient_id = tree_input_data_path.parts[-1] if tree_input_data_path.is_dir and output_data_path.is_dir: coord_file_path = tree_input_data_path / "final_coords.npz" edges_file_path = tree_input_data_path / "final_edges.npz" coord_attributes_file_path = tree_input_data_path / "coord_attributes.npz" edge_attributes_file_path = tree_input_data_path / "edge_attributes.npz" else: sys.exit(1) if not reduced_model_data_path.exists(): print("ERROR: stage-02 needed") print(reduced_model_data_path) sys.exit(-1) reduced_model = np.load(reduced_model_data_path / "reduced_model.npz")['arr_0'] print(np.unique(reduced_model)) reduced_model[reduced_model >= 7] = 0 # Remove all voxels 7, 8 and 9 since these are veins/arteries and not useful in classification print(np.unique(reduced_model)) np_coord = np.load(coord_file_path)['arr_0'] np_edges = np.load(edges_file_path)['arr_0'] np_coord_attributes = np.load(coord_attributes_file_path, allow_pickle=True)['arr_0'] np_edges_attributes = np.load(edge_attributes_file_path, allow_pickle=True)['arr_0'] # create empty graphs graph = nx.Graph(patient=int(patient_id)) # compose graphs # assert False, "Crashes not here" dic_coords = create_nodes(graph, np_coord, np_coord_attributes, reduced_model) dic_edges = create_edges(graph, np_edges, dic_coords, np_edges_attributes) # set levels to the graph graph = set_level(graph) # level 2 does not belong to a lobe graph = set_attribute_to_node(graph, ('level', 2), ('lobe', 0)) show_stats(graph, patient_id) nx.write_graphml(graph, output_data_path / "tree.graphml")
def main(): output_data_path, input_data_path, reduced_model_data_path = get_data_paths_from_args( inputs=2) rot_mat = np.array([[0, 0, -1], [-1, 0, 0], [0, 1, 0]]) model = np.load(reduced_model_data_path / 'reduced_model.npz')['arr_0'] if not output_data_path.exists(): output_data_path.mkdir(parents=True, exist_ok=True) graph = nx.read_graphml(input_data_path / "tree.graphml") gen_split_obj(output_data_path / "splits.obj", graph, rot_mat=rot_mat, model_shape=model.shape)
def main(): output_data_path, input_data_path, distance_mask_path, color_mask_path = get_data_paths_from_args( inputs=3) model = np.load(input_data_path / "reduced_model.npz")['arr_0'] print(f"Loaded model with shape {model.shape}") distance_mask = np.load(distance_mask_path / "distance_mask.npz")['arr_0'] print(f"Loaded color mask with shape {distance_mask.shape}") bronchus_color_mask = np.load(color_mask_path / "bronchus_color_mask.npz")['color_mask'] bronchus_color_codes = np.load(color_mask_path / "bronchus_color_mask.npz")['color_codes'] color_codes = {i: code for i, code in enumerate(bronchus_color_codes)} print(color_codes) print(f"Loaded color mask with shape {bronchus_color_mask.shape}") if not output_data_path.exists(): output_data_path.mkdir(parents=True, exist_ok=True) rot_mat = np.array([[0, 0, -1], [-1, 0, 0], [0, 1, 0]]) print("Running skeletonize on model") # Remove lobe coordinates from model by clipping everything # between 0 and 2, then modulo everything by 2 to remove 2s skeleton = skeletonize(np.clip(model, 0, 2) % 2) generate_obj(output_data_path / "skeleton.obj", set(), skeleton, rot_mat=rot_mat) # generate_obj(output_data_path / "bav.obj", {1, 7, 8}, model) generate_obj(output_data_path / "bronchus.obj", {1}, model, color_mask=bronchus_color_mask, color_to_rgb_tuple=color_codes, rot_mat=rot_mat)
from util.util import get_data_paths_from_args plt.rcParams.update({'font.size': 4}) # |>--><-><-><-><-><->-<| # |>- Parse arguments -<| # |>--><-><-><-><-><->-<| ( output_data_path, bronchus_shell_data_path, map_coord_to_dist_data_path, final_coords_data_path, pre_post_processing_data_path, post_post_processing_data_path, ) = get_data_paths_from_args(inputs=5) try: show_plot = sys.argv[7].lower() == "true" except IndexError: show_plot = True try: show_bronchus = sys.argv[8].lower() == "true" except IndexError: show_bronchus = False # |>-<-><-><-><-><-><->-<| # |>- Define color map -<| # |>-<-><-><-><-><-><->-<|
""" Converts images to booleans, then saves them as numpy array """ import os import numpy as np import pydicom from util.util import get_data_paths_from_args # Process arguments supplied output_data_path, input_data_path = get_data_paths_from_args() dir_names_to_id = { "Bronchus": 1, "LeftLowerLobe": 2, "LeftUpperLobe": 3, "RightLowerLobe": 4, "RightMiddleLobe": 5, "RightUpperLobe": 6, "Vein": 7, "Artery": 8, } def save_images_as_npz(raw_data_path, processed_data_path): """Saves a 3D numpy matrix of the model to $processed_data_path The matrix has 0 for empty space and dir_names_to_id for each type given. """
this script now checks whenever a group splits in 2 (there is no path between them), whenever this happens it marks this as a split and saves it later on. After doing that it backtracks all nodes and creates all the edges. """ import queue import math from typing import Tuple, Set import numpy as np from util.helper_functions import adjacent, find_radius_via_sphere from util.util import get_data_paths_from_args output_data_path, input_data_path, reduced_model_data_path = get_data_paths_from_args( inputs=2) REDUCED_MODEL = reduced_model_data_path / "reduced_model.npz" DISTANCE_TO_COORDS_FILE = input_data_path / "map_distance_to_coords.npz" MAP_COORD_TO_PREVIOUS_FILE = input_data_path / "map_coord_to_previous.txt" MAP_COORD_TO_NEXT_COUNT_FILE = input_data_path / "map_coord_to_next_count.txt" FINAL_COORDS_FILE = output_data_path / "final_coords" FINAL_EDGES_FILE = output_data_path / "final_edges" EDGE_ATTRIBUTES_FILE = output_data_path / "edge_attributes" COORD_ATTRIBUTES_FILE = output_data_path / "coord_attributes" model = np.load(REDUCED_MODEL)['arr_0'] print(model.shape)
def main(): """ Executes all methods given above in the correct order """ # |>-<-><-><-><-><-><-><-<| # |>- Process arguments -<| # |>-<-><-><-><-><-><-><-<| output_data_path, input_data_path = get_data_paths_from_args() # |>-<-><-><-><->-<| # |>- Load graph -<| # |>-<-><-><-><->-<| graph = load_graph(input_data_path / "tree.graphml") assert nx.is_tree(graph), "ERROR: Graph is not a tree!" # |>-><-><-><-><-><-<| # |>- Process tree -<| # |>-><-><-><-><-><-<| print(f"===== Node Removal =====") # Run each of these multiple times since they do something on each # iteration. Quit when nothing changes iteration = 0 while True: node_count = graph.number_of_nodes() print(f"=== Iteration {iteration} ===") remove_minor_edges(graph) straighten_edges(graph) merge_close_nodes(graph) remove_children_without_children(graph) iteration += 1 if node_count == graph.number_of_nodes(): break # |>--><-><-><-><-><-><-><-><-><-><-><-><-><--<| # |>- Reset attributes from the other script -<| # |>--><-><-><-><-><-><-><-><-><-><-><-><-><--<| assign_children_count(graph) graph = set_level(graph) graph = set_attribute_to_node(graph, ('level', 2), ('lobe', 0)) graph = set_attribute_to_node(graph, ('level', 3), ('lobe', 0)) assert nx.is_tree(graph), "ERROR: Graph is no longer a tree!" # |>-<-><-><-><-><-><-><-><->-<| # |>- Write pre-colored tree -<| # |>-<-><-><-><-><-><-><-><->-<| print(f"===== Recoloring =====") if not output_data_path.exists(): output_data_path.mkdir(parents=True, exist_ok=True) nx.write_graphml(graph, output_data_path / "pre-recoloring.graphml") # |>-<-><-><-><->-<| # |>- Recoloring -<| # |>-<-><-><-><->-<| for _ in range(5): recolor_if_all_adjacent_have_different_color(graph) recolor_if_successors_all_different_color(graph) recolor_entire_subtree_to_majority_at_level_4_or_5(graph) possibly_make_neutral_above_level_4(graph) add_new_parent_for_lobe(graph) # |>-<-><-><-><->-<| # |>- Write tree -<| # |>-<-><-><-><->-<| nx.write_graphml(graph, output_data_path / "tree.graphml")