def check_virtual_points(virtual_points, connecting_points, center_point, vol, sampling, global_direction, alpha): """ Given a set of virtual points, the algorithm will check in the next two slices for connecting points. If there is a connecting point, the virtual point will change the virtual point into a connecting point. Otherwise the virtual point will be removed. """ look_for_bifurcation = False #Create two temporary slices slice_i_plus_1, center_point_i_plus_1, global_direction_i_plus_1, unused, unused, \ unused, unused = centerline_tracking.get_slice(vol, sampling, center_point,global_direction,look_for_bifurcation, alpha) slice_i_plus_2, unused, unused, unused, unused, unused, unused = \ centerline_tracking.get_slice(vol, sampling, center_point_i_plus_1, global_direction_i_plus_1, look_for_bifurcation, alpha) #Find points in this slice pointset_slice_i_plus_1 = stentPoints2d.detect_points(slice_i_plus_1) pointset_slice_i_plus_2 = stentPoints2d.detect_points(slice_i_plus_2) #Check whether the virtual points return connecting points. new_connecting_points_1, still_virtual_points = find_connecting_points( \ virtual_points, pointset_slice_i_plus_1) new_connecting_points_2, removed_virtual_points = find_connecting_points( \ still_virtual_points, pointset_slice_i_plus_2) #Add the new connecting points to the existing list of connection points connecting_points.Extend(new_connecting_points_1) connecting_points.Extend(new_connecting_points_2) return connecting_points, slice_i_plus_1
def amount_of_nodes(vol, sampling, center_point, global_direction, look_for_bifurcation): """ Given a center point and direction the algorithm will create a slice and filter the found points. Based on the filtered points, the amount of expected nodes are calculated """ look_for_bifurcation = False alpha = 1 #create the slice slice, unused, unused, unused, unused, unused, unused = \ centerline_tracking.get_slice(vol, sampling, center_point, global_direction, \ look_for_bifurcation, alpha) #detect points points_in_slice = stentPoints2d.detect_points(slice) #filter points try: filtered_points = stentPoints2d.cluster_points(points_in_slice, Point(128, 128)) except AssertionError: filtered_points = points_in_slice #if filtering was succesful if filtered_points: expected_amount_of_nodes = len(filtered_points) / 2 else: expected_amount_of_nodes = len(points_in_slice) / 2 return expected_amount_of_nodes, filtered_points
def check_for_nodes(connecting_points, slice_i_plus_1): """ Given a set of stent points, the algorithm checks whether there are any duplicates. A duplicate would mean that that point was found by two stent points and could therefore be a node. An additional check is done to check whether there are no connecting points above the potential node. If this is the case, than the point is not a node. """ #Pointset to store 2D nodes point_nodes = Pointset(2) #Pointset to store point which need to be removed point_remove = Pointset(2) #points in slice_i_plus_1 points_check = stentPoints2d.detect_points(slice_i_plus_1) #For every connecting point for i in range(len(connecting_points)): for j in range(len(connecting_points)): #if points are the same if connecting_points[i].Distance( connecting_points[j]) <= 3 and i != j: #check if this point would find a connecting point point = Pointset(2) point.Append(connecting_points[i]) node_check, unused = find_connecting_points( point, points_check) #Only add node once. if not node_check: if not point_nodes: point_nodes.Append( (connecting_points[i] + connecting_points[j]) / 2) elif point_nodes.Contains(connecting_points[i]) == False: point_nodes.Append( (connecting_points[i] + connecting_points[j]) / 2) #The connecting points need to be removed later point_remove.append(connecting_points[i]) point_remove.append(connecting_points[i]) return point_nodes, point_remove
def initial_center_point(vol, seed_points_i, seed_points_i_plus_1, sampling, origin, alpha): """ Given two seed points, the algorithm will create the first center point and the global direction """ #Set global direction global_direction = seed_points_i_plus_1 - seed_points_i global_direction = Point(global_direction[2], global_direction[1], \ global_direction[0]).Normalize() #Create slice slice, unused, unused, unused, vec1, vec2, unused = \ centerline_tracking.get_slice(vol, sampling, seed_points_i, global_direction, False, alpha) #Search points and filter point_in_slice = stentPoints2d.detect_points(slice) try: filtered = stentPoints2d.cluster_points(point_in_slice, Point(128, 128)) except AssertionError: filtered = [] #Calculate new center and transform to 3d if filtered: center_point_2d = stentPoints2d.fit_cirlce(filtered) better_center_3d = convert_2d_point_to_3d_point( seed_points_i, vec1, vec2, center_point_2d) #If not too far, use better center. if better_center_3d.Distance(seed_points_i) > 10: center_point = better_center_3d else: center_point = seed_points_i else: center_point = seed_points_i return center_point, global_direction
def get_slice(vol, sampling, center_point, global_direction, look_for_bifurcation, alpha): """ Given two center points and the direction of the stent, the algorithm will first create a slice on the second center point. A new center point is calculated on this slice, which is used to find a local direction. The local direction is used to update the global direction with weigthing factor alpha (where 0 is following the local direction and 1 the global direction). Using this new direction a slice is created on the first center point. """ vec1 = Point(1, 0, 0) vec2 = Point(0, 1, 0) #Set second center point as rotation point rotation_point = Point(center_point[2], center_point[1], center_point[0]) + global_direction #Create the slice using the global direction slice, vec1, vec2 = slice_from_volume(vol, sampling, global_direction, rotation_point, vec1, vec2) #Search for points in this slice and filter these with the clustering method points_in_slice = stentPoints2d.detect_points(slice) try: points_in_slice_filtered = stentPoints2d.cluster_points(points_in_slice, \ Point(128,128)) except AssertionError: points_in_slice_filtered = [] #if filtering did not succeed the unfiltered points are used if not points_in_slice_filtered: points_in_slice_filtered = points_in_slice succeeded = False else: succeeded = True #if looking for bifurcation than the radius has to be calculated if succeeded and look_for_bifurcation: center_point_with_radius = stentPoints2d.fit_cirlce( \ points_in_slice_filtered) #convert 2d center point to 3d for the event that the bifurcation #is found center_point_3d_with_radius = convert_2d_point_to_3d_point( \ Point(rotation_point[2], rotation_point[1], rotation_point[0]), vec1, vec2, center_point_with_radius) #Convert pointset into point center_point_3d_with_radius = Point(center_point_3d_with_radius[0]) #Give the 3d center point the radius as attribute center_point_3d_with_radius.r = center_point_with_radius.r else: center_point_3d_with_radius = Point(0, 0, 0) center_point_3d_with_radius.r = [] #Now the local direction of the stent has to be found. Note that it is not #done when the chopstick filtering did not succeed. if succeeded: better_center_point = stentPoints2d.converge_to_centre(points_in_slice_filtered, \ Point(128,128)) else: better_center_point = Point(0, 0), [] #If no better center point has been found, there is no need to update global #direction if better_center_point[0] == Point(0, 0): updated_direction = global_direction else: better_center_point_3d = convert_2d_point_to_3d_point(\ Point(rotation_point[2], rotation_point[1], rotation_point[0]), \ vec1, vec2, better_center_point[0]) #Change pointset into a point better_center_point_3d = Point(better_center_point_3d[0]) #local direction (from starting center point to the better center point) local_direction = Point(better_center_point_3d[2]-center_point[2], \ better_center_point_3d[1]-center_point[1], better_center_point_3d[0] \ -center_point[0]).Normalize() #calculate updated direction updated_direction = ((1 - alpha) * local_direction + alpha * global_direction).Normalize() #Now a new slice can be created using the first center point as rotation point. rotation_point = Point(center_point[2], center_point[1], center_point[0]) slice, vec1, vec2 = slice_from_volume(vol, sampling, updated_direction, rotation_point, vec1, vec2) #Change order rotation_point = Point(center_point[0], center_point[1], center_point[2]) #return new center point new_center_point = center_point + Point(updated_direction[2], \ updated_direction[1], updated_direction[0]) return slice, new_center_point, updated_direction, rotation_point, vec1, vec2, \ center_point_3d_with_radius
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