def searching_for_ring(vol, sampling, center_point, global_direction, \ look_for_bifurcation, average_radius, alpha, ring): """ Given a center point and a direction, the algorithm will start by searching for points in a certain stent ring using the global direction. By connecting points it will come to a set of nodes. After a certain amount of nodes are found, the algorithm will flip the direction and will search for points in the other direction until the stent ring is defined. The radius is used when searching for the bifurcation. """ #Initially, the bifurcation is not found found_bifurcation = False #First the initial center point and direction has to be stored in order to #flip the direction later stored_center_point = center_point flipped_global_direction = -1 * global_direction #Create pointsets to store points node_points_ring = Pointset(5) #(z,y,x,ring,direction) stent_points_ring = Pointset(3) center_points_ring = Pointset(3) #Expected amount of nodes and returns initial filtered points expected_amount_of_nodes, initial_points_in_slice = amount_of_nodes(vol, sampling, \ center_point, global_direction, look_for_bifurcation) #set direction: 1 for along the direction of the stent, -1 for the opposite \ #direction direction = 1 #Find and connect points center_points, stent_points, node_points, global_direction, found_bifurcation, new_starting_positions, \ ring = connecting_stent_points(vol, sampling, center_point, global_direction, look_for_bifurcation, \ average_radius, direction, expected_amount_of_nodes, initial_points_in_slice, found_bifurcation, alpha, ring) #Store starting positions, because the direction -1 will remove otherwise. if found_bifurcation: store_starting_positions = new_starting_positions #Add found points to pointsets node_points_ring.Extend(node_points) stent_points_ring.Extend(stent_points) center_points_ring.Extend(center_points) #Store last center point to use as 'jumping' site if len(center_points_ring): jump_location = center_points_ring[len(center_points_ring) - 1] else: jump_location = stored_center_point jump_direction = global_direction #Flip direction direction = -1 #Find and connect points for other direction center_points, stent_points, node_points, global_direction, found_bifurcation, new_starting_positions, \ ring = connecting_stent_points(vol, sampling, stored_center_point, flipped_global_direction, \ look_for_bifurcation, average_radius, direction, expected_amount_of_nodes, \ initial_points_in_slice, found_bifurcation, alpha, ring) if found_bifurcation: new_starting_positions = store_starting_positions #Add found points to pointsets node_points_ring.Extend(node_points) stent_points_ring.Extend(stent_points) center_points_ring.Extend(center_points) ring = ring + 1 return node_points_ring, stent_points_ring, center_points_ring, \ jump_location, jump_direction, found_bifurcation, new_starting_positions, ring
def stent_detection(vol, sampling, origin, seed_points): """ This is the function that will be called in order to extract the stent from the CT data. """ #Point set where the final points will be stored. In node, the 4th number #indicates the ring number, the 5th indicates the direction where it is found node_points_stent = Pointset(5) center_points_stent = Pointset(3) stent_points_stent = Pointset(3) #Initially, the bifurcation is not found found_bifurcation = False average_radius = [] #start with ring 1 ring = 1 #Weighting factor alpha alpha = ssdf._stent_tracking_params.weighting_factor distance = ssdf._stent_tracking_params.distance #From seed point to seed point except for the last seed point, where the #bifurcation needs to be found. for i in range(len(seed_points) - 2): round = 0 #Don't look for the bifurcation when not connecting points in the last #part of the stent look_for_bifurcation = False #Get initial center point and direction using the seed points center_point, global_direction = initial_center_point( vol, seed_points[i], seed_points[i + 1], sampling, origin, alpha) #While the center point has not passed the seed point while center_point[0] < seed_points[i + 1][0] and round < 10: #Find stent, node and center points for a certain stent ring node_points_ring, stent_points_ring, center_points_ring, \ jump_location, jump_direction, found_bifurcation, new_starting_positions, \ ring = searching_for_ring(vol, sampling, center_point, global_direction,\ look_for_bifurcation, average_radius, alpha, ring) #Set new starting center point inside the new ring center_point = jump_location + distance * Point( jump_direction[2], jump_direction[1], jump_direction[0]) global_direction = jump_direction #Add points to point sets node_points_stent.Extend(node_points_ring) center_points_stent.Extend(center_points_ring) stent_points_stent.Extend(stent_points_ring) round = round + 1 #For the last part of the stent where the bifurcation needs to be found for i in range(len(seed_points) - 2, len(seed_points) - 1): #Reset round to zero round = 0 look_for_bifurcation = True center_point, global_direction = initial_center_point(vol, seed_points[i],\ seed_points[i+1], sampling, origin, alpha) #While the bifurcation is not found while found_bifurcation == False and round < 10: node_points_ring, stent_points_ring, center_points_ring, \ jump_location, jump_direction, found_bifurcation, new_starting_positions, \ ring = searching_for_ring(vol, sampling, center_point, global_direction, \ look_for_bifurcation, average_radius, alpha, ring) center_point = jump_location + distance * Point( jump_direction[2], jump_direction[1], jump_direction[0]) global_direction = jump_direction #Add points to point sets node_points_stent.Extend(node_points_ring) center_points_stent.Extend(center_points_ring) stent_points_stent.Extend(stent_points_ring) round = round + 1 #Store new starting positions in another poitset, because algorithm will #return [] as new_starting_positions. starting_positions = Pointset(3) #For the case where there is no bifurcation present try: starting_positions.Append( new_starting_positions[0] ) # + distance * Point(jump_direction[2],jump_direction[1],jump_direction[0])) starting_positions.Append( new_starting_positions[1] ) # + distance * Point(jump_direction[2],jump_direction[1],jump_direction[0])) except IndexError: [] alpha = ssdf._stent_tracking_params.weighting_factor_bif #Now points after the bifurcation will be found for i in range(len(starting_positions)): center_point = starting_positions[i] look_for_bifurcation = False round = 0 while round < 4: node_points_ring, stent_points_ring, center_points_ring, \ jump_location, jump_direction, found_bifurcation, new_starting_positions, \ ring = searching_for_ring(vol, sampling, center_point, global_direction, \ look_for_bifurcation, average_radius, alpha, ring) center_point = jump_location + distance * Point( jump_direction[2], jump_direction[1], jump_direction[0]) global_direction = jump_direction if 255 < center_point[0]: break #Add points to point sets node_points_stent.Extend(node_points_ring) center_points_stent.Extend(center_points_ring) stent_points_stent.Extend(stent_points_ring) round = round + 1 return node_points_stent, center_points_stent, stent_points_stent
def connecting_stent_points(vol, sampling, center_point, global_direction, look_for_bifurcation, \ average_radius, direction, expected_amount_of_nodes, points_in_slice, found_bifurcation, alpha, ring): """ This algorithm uses the earlier stated functions in order to connect points and define nodes. """ #Nodes that are found for the current direction node_points_direction = Pointset(3) #Other pointsets to store points center_points = Pointset(3) stent_points = Pointset(3) node_points = Pointset(5) #Set round to 0 for the case that the amount of nodes criterion is not met. round = 0 #Initial new_starting_positions = [] #connecting points while len(node_points_direction) < expected_amount_of_nodes and round < 12: #Get slice slice, center_point, global_direction, rotation_point, vec1, vec2, \ center_point_3d_with_radius = centerline_tracking.get_slice(vol, sampling, \ center_point, global_direction, look_for_bifurcation, alpha) #If looking for the bifurcation, check radius if look_for_bifurcation and direction == 1: if not found_bifurcation: average_radius, found_bifurcation, new_starting_positions \ = check_for_possible_bifurcation(average_radius, center_point_3d_with_radius, \ rotation_point, found_bifurcation, global_direction) else: new_starting_positions = [] #Find points points_in_next_slice = stentPoints2d.detect_points(slice) #Find connecting points. Change not connecting points into virtual points connecting_points, virtual_points = find_connecting_points(points_in_slice, \ points_in_next_slice) #Check if virtual points should be converted into connecting points connecting_points, temp_slice = check_virtual_points(virtual_points, \ connecting_points, center_point, vol, sampling, global_direction, alpha) #Check for nodes point_nodes_2d, point_remove = check_for_nodes(connecting_points, temp_slice) #If nodes are found, these points should be deleted from the connecting points list connecting_points = delete_nodes_from_list(connecting_points, point_remove) #Convert 2d points into 3d points connecting_points_3d = convert_2d_point_to_3d_point(center_point, vec1,\ vec2, connecting_points) point_nodes_3d = convert_2d_point_to_3d_point(center_point, vec1, vec2,\ point_nodes_2d) #Add 3d points to their list center_points.Append(rotation_point) stent_points.Extend(connecting_points_3d) node_points_direction.Extend(point_nodes_3d) for i in range(len(point_nodes_3d)): node_points.Append( Point(point_nodes_3d[i][0], point_nodes_3d[i][1], point_nodes_3d[i][2], ring, direction)) #Set connecting points as new base points points_in_slice = connecting_points #Next round round = round + 1 #If there are three nodes found, do first one more run. if len(node_points_direction) > 2: diff = 10 - round if diff > 0: round = round + diff if round == 12: new_nodes = additional_nodes(connecting_points_3d) for i in range(len(new_nodes)): node_points.Append( Point(new_nodes[i][0], new_nodes[i][1], new_nodes[i][2], ring, direction)) return center_points, stent_points, node_points, global_direction, found_bifurcation, new_starting_positions, ring