示例#1
0
def main():
    (
        output_data_path,
        post_processing_data_path,
        post_composition_data_path,
        reduced_model_data_path,
    ) = get_data_paths_from_args(inputs=3)

    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(post_composition_data_path / "tree.graphml")
    gen_split_obj(output_data_path / "splits_no_post_processing.obj",
                  graph,
                  rot_mat=rot_mat,
                  model_shape=model.shape)

    graph = nx.read_graphml(post_processing_data_path / "tree.graphml")
    gen_split_obj(output_data_path / "splits.obj",
                  graph,
                  rot_mat=rot_mat,
                  model_shape=model.shape)
示例#2
0
def get_input():
    output_data_path, tree_input_path = get_data_paths_from_args()
    classification_config = parse_classification_config()
    trees: List[nx.Graph] = []
    for tree_path in Path(tree_input_path).glob("*/tree.graphml"):
        trees.append(nx.read_graphml(tree_path))
    return output_data_path, trees, 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)
示例#4
0
def get_input():
    output_data_path, tree_input_path = get_data_paths_from_args(inputs=1)
    classification_config = parse_classification_config()
    trees: List[nx.Graph] = []
    ignored_patients = get_ignored_patients()
    print(ignored_patients)
    for tree_path in Path(tree_input_path).glob("*/tree.graphml"):
        if tree_path.parent.name not in ignored_patients:
            trees.append(nx.read_graphml(tree_path))
    return output_data_path, trees, classification_config
示例#5
0
def get_input():
    output_data_path, tree_input_path = get_data_paths_from_args()
    trees: List[List[nx.Graph]] = []
    for tree_path in Path(tree_input_path).glob("*"):
        pair = []
        for name in ["tree.graphml", "tree_gt.graphml"]:
            if (tree_path / name).exists():
                pair.append(nx.read_graphml(tree_path / name))
        trees.append(pair)
    classification_config = parse_classification_config()
    return output_data_path, trees, classification_config
示例#6
0
def get_input():
    output_data_path, tree_input_path, render_path = get_data_paths_from_args(
        inputs=2)
    classification_config = parse_classification_config()
    for cc_dict in classification_config.values():
        if "clustering_endnode" not in cc_dict:
            cc_dict["clustering_endnode"] = False
    trees: List[nx.Graph] = []
    ignored_patients = get_ignored_patients()
    for tree_path in Path(tree_input_path).glob("*/tree.graphml"):
        if tree_path.parent.name not in ignored_patients:
            trees.append(nx.read_graphml(tree_path))
    return output_data_path, trees, classification_config, render_path
示例#7
0
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(
            f"ERROR: either {tree_input_data_path} or {output_data_path} do not exist!"
        )

    if not reduced_model_data_path.exists():
        print(reduced_model_data_path)
        sys.exit("ERROR: stage-02 needed")

    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=patient_id)
    # compose graphs
    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")
示例#8
0
def main():
    output_data_path, reduced_model_data_path, tree_data_path = get_data_paths_from_args(
        inputs=2)
    model = np.zeros(
        np.load(reduced_model_data_path / "reduced_model.npz")["arr_0"].shape)
    tree = nx.read_graphml(tree_data_path / "tree.graphml")
    for parent_id, child_ids in nx.bfs_successors(tree, "0"):
        parent_node = tree.nodes[parent_id]
        parent_point = get_point(parent_node)
        for child_id in child_ids:
            child_point = get_point(tree.nodes[child_id])
            fill_line(model, parent_point, child_point,
                      max(2, parent_node["group_size"] / 2))

    print(*zip(*np.unique(model, return_counts=True)))
    np.savez_compressed(output_data_path / "model.npz", model)
示例#9
0
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"]
    tree = nx.read_graphml(tree_path / f"tree.graphml")

    def should_color_func(
            condition: Callable[[nx.Graph, int], bool]) -> Callable:
        return lambda s: s in get_first_matching_ids(tree, condition)

    print(get_first_matching_ids(tree, is_lobe))
    print(get_first_matching_ids(tree, is_segment))

    for func, filename in [
        (lambda _: True, "bronchus_color_mask.npz"),
        (should_color_func(is_segment), "segments.npz"),
        (should_color_func(is_lobe), "lobes.npz"),
    ]:
        color_mask = np.full(model.shape, 0)
        nodes_visit_order, color_hex_codes = get_nodes_visit_order(
            tree, distance_mask, func)
        print(color_hex_codes)

        fill_color_with_priority_queue(nodes_visit_order, model, distance_mask,
                                       color_mask)

        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 / filename,
                            color_mask=color_mask,
                            color_codes=np.array(color_hex_codes))
示例#10
0
import math
import queue
from typing import Tuple, Dict

import numpy as np
from skimage.morphology import skeletonize

from airway.util.helper_functions import adjacent
from airway.util.util import get_data_paths_from_args

Coordinate = Tuple[int, int, int]

output_data_path, input_data_path = get_data_paths_from_args()

patient_data_file = input_data_path / "reduced_model.npz"

distance_to_coords_file = output_data_path / "map_distance_to_coords"
coord_to_distance_file = output_data_path / "map_coord_to_distance.txt"
coord_to_previous_file = output_data_path / "map_coord_to_previous.txt"
coord_to_next_count_file = output_data_path / "map_coord_to_next_count.txt"
distance_mask_path = output_data_path / "distance_mask"


def find_first_voxel(model):
    """Find first (highest) voxel in the lung"""
    for layer in range(len(model)):
        possible_coords = []
        found = False
        for line in range(len(model[layer])):
            for voxel in range(len(model[layer][line])):
                if model[layer][line][voxel] == 1:
示例#11
0
from airway.util.util import get_data_paths_from_args

plt.rcParams.update({"font.size": 7})

# |>--><-><-><-><-><->-<|
# |>- 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 -<|
# |>-<-><-><-><-><-><->-<|
示例#12
0
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")
示例#13
0
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 airway.util.helper_functions import adjacent, find_radius_via_sphere
from airway.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)

示例#14
0
def main():
    output_data_path, input_data_path, distance_mask_path, color_mask_path = get_data_paths_from_args(
        inputs=3)

    original_color_tuples = {
        index: color_hex_to_floats(color)
        for index, color in enumerate([
            "ffffff", "bee6be", "fa87f5", "fa4646", "41d741", "6478fa",
            "e6ff50", "5870ff", "ff5c64"
        ])
    }

    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}")

    try:
        color_mask_npz = np.load(color_mask_path / "bronchus_color_mask.npz")
        bronchus_color_mask = color_mask_npz["color_mask"]
        bronchus_color_codes = color_mask_npz["color_codes"]
        print(bronchus_color_codes)
        print(f"Loaded color mask with shape {bronchus_color_mask.shape}")
        color_codes = {i: code for i, code in enumerate(bronchus_color_codes)}
        print(color_codes)
    except FileNotFoundError:
        print("WARNING: Color mask not found, using white for all voxels!")
        bronchus_color_mask = None
        color_codes = {0: (1, 1, 1)}

    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,
    )
    generate_obj(output_data_path / "distance_mask.obj", {1},
                 model,
                 color_mask=distance_mask,
                 rot_mat=rot_mat)
    generate_obj(output_data_path / "veins.obj", {7},
                 model,
                 color_to_rgb_tuple={0: (0, 0, 1)},
                 rot_mat=rot_mat)
    generate_obj(output_data_path / "arteries.obj", {8},
                 model,
                 color_to_rgb_tuple={0: (1, 0, 0)},
                 rot_mat=rot_mat)