def showModel3d(basedir,ptcode, ctcode, cropname='ring', showVol='MIP', showmodel=True, graphname='model', **kwargs): """ show model and vol in 3d by mip iso or 2D graphname 'all' draws all graph models stored in s, if multiple """ s = loadmodel(basedir, ptcode, ctcode, cropname, modelname='modelavgreg') vol = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg').vol # figure f = vv.figure(); vv.clf() f.position = 0.00, 22.00, 1920.00, 1018.00 a = vv.gca() a.axis.axisColor = 1,1,1 a.axis.visible = False a.bgcolor = 0,0,0 a.daspect = 1, 1, -1 t = show_ctvolume(vol, axis=a, showVol=showVol, removeStent=False, climEditor=True, **kwargs) label = pick3d(a, vol) vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') if showmodel: if graphname == 'all': for key in dir(s): if key.startswith('model'): s[key].Draw(mc='b', mw = 5, lc='g', alpha = 0.5) else: s[graphname].Draw(mc='b', mw = 5, lc='g', alpha = 0.5) vv.title('Model for LSPEAS %s - %s' % (ptcode[8:], ctcode)) # f.eventKeyDown.Bind(lambda event: _utils_GUI.RotateView(event, [a], axishandling=False )) f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, [a]) ) return f, a, label, s
def make_model_dynamic(basedir, ptcode, ctcode, cropname, what='avgreg'): """ Read deforms and model to make model dynamic, ie, add deforms to edges and nodes in the graph """ # Load deforms s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms') deformkeys = [] for key in dir(s): if key.startswith('deform'): deformkeys.append(key) deforms = [s[key] for key in deformkeys] deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms] paramsreg = s.params # Load model s = loadmodel(basedir, ptcode, ctcode, cropname, 'model'+what) for key in dir(s): if key.startswith('model'): model = s[key] # Combine ... incorporate_motion_nodes(model, deforms, s.origin) # adds deforms PointSets incorporate_motion_edges(model, deforms, s.origin) # adds deforms PointSets s[key] = model.pack() # also pack seeds before save if key.startswith('seeds'): s[key] = s[key].pack() # Save back filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'model'+what) s.paramsreg = paramsreg ssdf.save(os.path.join(basedir, ptcode, filename), s) print('saved dynamic to disk in {} as {}.'.format(basedir, filename) )
def makeLandmarkModelDynamic(basedir, ptcode, ctcode, cropname, what='landmarksavgreg', savedir=None): """ Make model dynamic with deforms from registration (and store/overwrite to disk) """ #todo: change in default and merge with branch landmarks? import pirt from stentseg.motion.dynamic import (incorporate_motion_nodes, incorporate_motion_edges) from visvis import ssdf import os if savedir is None: savedir = basedir # Load deforms s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms') deformkeys = [] for key in dir(s): if key.startswith('deform'): deformkeys.append(key) deforms = [s[key] for key in deformkeys] deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms] paramsreg = s.params # Load model where landmarks were stored # s2 = loadmodel(savedir, ptcode, ctcode, cropname, what) fname = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, what) s2 = ssdf.load(os.path.join(savedir, fname)) # Turn into graph model model = stentgraph.StentGraph() model.unpack(s2[what]) # Combine ... incorporate_motion_nodes(model, deforms, s2.origin) incorporate_motion_edges(model, deforms, s2.origin) # Save back filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, what) s2.model = model.pack() s2.paramsreg = paramsreg ssdf.save(os.path.join(savedir, filename), s2) print('saved to disk to {}.'.format(os.path.join(savedir, filename)))
def loadvolmodel(basedir, ptcode, ctcode1, cropname, modelname, nstruts=8, ringpart=False): """ load vol and model """ s1 = loadmodel(basedir, ptcode, ctcode1, cropname, modelname) model = s1.model models1 = [] for ringname in ringnames: model1 = s1[ringname] if ringpart: models = get_model_struts(model1, nstruts=nstruts) modelRs = get_model_rings(models[2]) # model_R1R2 model1 = modelRs[ringpart - 1] # R1 or R2 models1.append(model1) vol1 = loadvol(basedir, ptcode, ctcode1, cropname, 'avgreg').vol return vol1, models1, model
def __init__(self, ptcode, ctcode, basedir, clim=None): """ select start and endpoints to be used for centerline generation """ from stentseg.apps._3DPointSelector import select3dpoints # from stentseg.apps.ui_dialog import MyDialog # from PyQt4 import QtGui import imageio import os from stentseg.utils.datahandling import select_dir, loadvol import copy # Select dataset to register cropname = 'prox' what = 'avgreg' # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) vol_org = copy.deepcopy(s.vol) s.vol.sampling = [ vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2] ] s.sampling = s.vol.sampling # # Select nr of stents # app = QtGui.QApplication([]) # m = MyDialog() # m.show() # m.exec_() # nr_of_stents = int(m.combo.currentText()) # Endpoint selection points = select3dpoints(s.vol, nr_of_stents=6, clim=clim) self.StartPoints = points[0] self.EndPoints = points[1] print('StartPoints are: ' + str(self.StartPoints)) print('EndPoints are: ' + str(self.EndPoints))
drawVessel = True clim = (0, 2500) clim2D = -200, 500 # MPR clim2 = (0, 2) isoTh = 180 # 250 ## Load data # Load CT image data for reference, and deform data to measure motion try: # If we run this script without restart, we can re-use volume and deforms vol1 deforms except NameError: vol1 = loadvol(basedir, ptcode, ctcode1, cropvol, 'avgreg').vol s_deforms = loadvol(basedir, ptcode, ctcode1, cropvol, 'deforms') deforms = [ s_deforms[key] for key in dir(s_deforms) if key.startswith('deform') ] deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms] # Load vessel mesh (mimics) # We make sure that it is a mesh without faces, which makes our sampling easier try: ppvessel except NameError: # Load mesh with visvis, then put in our meshlib.Mesh() and let it ensure that # the mesh is closed, check the winding, etc. so that we can cut it with planes, # and reliably calculate volume. filename = '{}_{}_neck.stl'.format(ptcode, ctcode1)
def __init__(self,ptcode,ctcode,allcenterlines,basedir): """ Script to show the stent plus centerline model and select points on centerlines for motion analysis """ import os, time import pirt import visvis as vv import numpy as np import math import itertools import xlsxwriter from datetime import datetime from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.utils.new_pointset import PointSet from stentseg.stentdirect.stentgraph import create_mesh from stentseg.motion.vis import create_mesh_with_abs_displacement from stentseg.utils.visualization import show_ctvolume from pirt.utils.deformvis import DeformableTexture3D, DeformableMesh from stentseg.utils import PointSet from stentseg.stentdirect import stentgraph from visvis import Pointset # for meshes from stentseg.stentdirect.stentgraph import create_mesh from visvis.processing import lineToMesh, combineMeshes from visvis import ssdf from stentseg.utils.picker import pick3d try: from PyQt4 import QtCore, QtGui # PyQt5 except ImportError: from PySide import QtCore, QtGui # PySide2 from stentseg.apps.ui_dialog import MyDialog from stentseg.utils.centerline import dist_over_centerline # added for Mirthe import copy cropname = 'prox' exceldir = os.path.join(basedir,ptcode) # Load deformations and avg ct (forward for mesh) # centerlines combined in 1 model m = loadmodel(basedir, ptcode, ctcode, cropname, modelname = 'centerline_total_modelavgreg_deforms') model = m.model # centerlines separated in a model for each centerline # m_sep = loadmodel(basedir, ptcode, ctcode, cropname, modelname = 'centerline_modelavgreg_deforms') s = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg') vol_org = copy.deepcopy(s.vol) s.vol.sampling = [vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]] s.sampling = s.vol.sampling vol = s.vol # Start visualization and GUI fig = vv.figure(30); vv.clf() fig.position = 0.00, 30.00, 944.00, 1002.00 a = vv.gca() a.axis.axisColor = 1,1,1 a.axis.visible = True a.bgcolor = 0,0,0 a.daspect = 1, 1, -1 lim = 2500 t = vv.volshow(vol, clim=(0, lim), renderStyle='mip') pick3d(vv.gca(), vol) b = model.Draw(mc='b', mw = 0, lc='g', alpha = 0.5) vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') vv.title('Model for LSPEAS %s - %s' % (ptcode[7:], ctcode)) # Add clickable nodes t0 = time.time() node_points = [] for i, node in enumerate(sorted(model.nodes())): node_point = vv.solidSphere(translation = (node), scaling = (0.6,0.6,0.6)) node_point.faceColor = 'b' node_point.alpha = 0.5 node_point.visible = True node_point.node = node node_point.nr = i node_points.append(node_point) t1 = time.time() print('Clickable nodes created, which took %1.2f min.' % ((t1-t0)/60)) # list of correctly clicked nodes selected_nodes_sum = set() # Initialize labels t0 = vv.Label(a, '\b{Node nr|location}: ', fontSize=11, color='w') t0.position = 0.1, 25, 0.5, 20 # x (frac w), y, w (frac), h t0.bgcolor = None t0.visible = True t1 = vv.Label(a, '\b{Nodepair}: ', fontSize=11, color='w') t1.position = 0.1, 45, 0.5, 20 t1.bgcolor = None t1.visible = True # Initialize output variable to store pulsatility analysis storeOutput = list() def on_key(event): if event.key == vv.KEY_ENTER: # mogenlijkheden aantal nodes # 1 voor relative beweging vanuit avg punt # 2 voor onderlinge beweging tussen twee punten # 3 voor hoek in punt 2 van punt 1 naar punt 3 if len(selected_nodes) == 1: selectn1 = selected_nodes[0].node n1index = selected_nodes[0].nr n1Deforms = model.node[selectn1]['deforms'] output = point_pulsatility(selectn1, n1Deforms) output['NodesIndex'] = [n1index] # Store output with name dialog_output = get_index_name() output['Name'] = dialog_output storeOutput.append(output) # update labels t1.text = '\b{Node}: %i' % (n1index) t1.visible = True print('selection of 1 node stored') if len(selected_nodes) == 2: # get nodes selectn1 = selected_nodes[0].node selectn2 = selected_nodes[1].node # get index of nodes which are in fixed order n1index = selected_nodes[0].nr n2index = selected_nodes[1].nr nindex = [n1index, n2index] # get deforms of nodes n1Deforms = model.node[selectn1]['deforms'] n2Deforms = model.node[selectn2]['deforms'] # get pulsatility cl_merged = append_centerlines(allcenterlines) output = point_to_point_pulsatility(cl_merged, selectn1, n1Deforms, selectn2, n2Deforms, type='euclidian') output['NodesIndex'] = nindex # get distance_centerline #dist_cl = dist_over_centerline(cl_merged, selectn1, selectn2, type='euclidian') # toegevoegd Mirthe #dist_cl = dist_centerline_total(cl_merged, selectn1, # n1Deforms, selectn2, n2Deforms, type='euclidian') # Store output with name dialog_output = get_index_name() output['Name'] = dialog_output storeOutput.append(output) # update labels t1.text = '\b{Node pair}: %i - %i' % (nindex[0], nindex[1]) t1.visible = True print('selection of 2 nodes stored') if len(selected_nodes) == 3: # get nodes selectn1 = selected_nodes[0].node selectn2 = selected_nodes[1].node selectn3 = selected_nodes[2].node # get index of nodes which are in fixed order n1index = selected_nodes[0].nr n2index = selected_nodes[1].nr n3index = selected_nodes[2].nr nindex = [n1index, n2index, n3index] # get deforms of nodes n1Deforms = model.node[selectn1]['deforms'] n2Deforms = model.node[selectn2]['deforms'] n3Deforms = model.node[selectn3]['deforms'] # get angulation output = line_line_angulation(selectn1, n1Deforms, selectn2, n2Deforms, selectn3, n3Deforms) output['NodesIndex'] = nindex # Store output with name dialog_output = get_index_name() output['Name'] = dialog_output storeOutput.append(output) # update labels t1.text = '\b{Nodes}: %i - %i - %i' % (nindex[0], nindex[1], nindex[2]) t1.visible = True print('selection of 3 nodes stored') if len(selected_nodes) > 3: for node in selected_nodes: node.faceColor = 'b' selected_nodes.clear() print('to many nodes selected, select 1,2 or 3 nodes') if len(selected_nodes) < 1: for node in selected_nodes: node.faceColor = 'b' selected_nodes.clear() print('to few nodes selected, select 1,2 or 3 nodes') # Visualize analyzed nodes and deselect for node in selected_nodes: selected_nodes_sum.add(node) for node in selected_nodes_sum: node.faceColor = 'g' # make green when analyzed selected_nodes.clear() if event.key == vv.KEY_ESCAPE: # FINISH MODEL, STORE TO EXCEL # Store to EXCEL storeOutputToExcel(storeOutput, exceldir) vv.close(fig) print('output stored to excel') selected_nodes = list() def select_node(event): """ select and deselect nodes by Double Click """ if event.owner not in selected_nodes: event.owner.faceColor = 'r' selected_nodes.append(event.owner) elif event.owner in selected_nodes: event.owner.faceColor = 'b' selected_nodes.remove(event.owner) def pick_node(event): nodenr = event.owner.nr node = event.owner.node t0.text = '\b{Node nr|location}: %i | x=%1.3f y=%1.3f z=%1.3f' % (nodenr,node[0],node[1],node[2]) def unpick_node(event): t0.text = '\b{Node nr|location}: ' def point_pulsatility(point1, point1Deforms): n1Indices = point1 + point1Deforms pos_combinations = list(itertools.combinations(range(len(point1Deforms)),2)) distances = [] for i in pos_combinations: v = point1Deforms[i[0]] - point1Deforms[i[1]] distances.append(((v[0]**2 + v[1]**2 + v[2]**2)**0.5 )) distances = np.array(distances) # get max distance between phases point_phase_max = distances.max() point_phase_max = [point_phase_max, [x*10 for x in (pos_combinations[list(distances).index(point_phase_max)])]] # get min distance between phases point_phase_min = distances.min() point_phase_min = [point_phase_min, [x*10 for x in (pos_combinations[list(distances).index(point_phase_min)])]] return {'point_phase_min':point_phase_min,'point_phase_max': point_phase_max, 'Node1': [point1, point1Deforms]} def point_to_point_pulsatility(cl, point1, point1Deforms, point2, point2Deforms,type='euclidian'): import numpy as np n1Indices = point1 + point1Deforms n2Indices = point2 + point2Deforms # define vector between nodes v = n1Indices - n2Indices distances = ( (v[:,0]**2 + v[:,1]**2 + v[:,2]**2)**0.5 ).reshape(-1,1) # get min and max distance point_to_pointMax = distances.max() point_to_pointMin = distances.min() # add phase in cardiac cycle where min and max where found (5th = 50%) point_to_pointMax = [point_to_pointMax, (list(distances).index(point_to_pointMax) )*10] point_to_pointMin = [point_to_pointMin, (list(distances).index(point_to_pointMin) )*10] # get median of distances point_to_pointMedian = np.percentile(distances, 50) # Q2 # median of the lower half, Q1 and upper half, Q3 point_to_pointQ1 = np.percentile(distances, 25) point_to_pointQ3 = np.percentile(distances, 75) # Pulsatility min max distance point to point point_to_pointP = point_to_pointMax[0] - point_to_pointMin[0] # add % change to pulsatility point_to_pointP = [point_to_pointP, (point_to_pointP/point_to_pointMin[0])*100 ] # find index of point on cll and calculate length change cll ??? if isinstance(cl, PointSet): cl = np.asarray(cl).reshape((len(cl),3)) indpoint1 = np.where( np.all(cl == point1, axis=-1) )[0] # -1 counts from last to the first axis indpoint2 = np.where( np.all(cl == point2, axis=-1) )[0] # renal point n1Indices = point1 + point1Deforms n2Indices = point2 + point2Deforms clDeforms = [] clpart_deformed = [] vectors = [] clpart = [] d = [] dist_cl = [] clpartDeforms = [] clpart_deformed_test = [] for i in range(len(cl)): clDeforms1 = model.node[cl[i,0], cl[i,1], cl[i,2]]['deforms'] clDeforms.append(clDeforms1) clpart_deformed1 = cl[i] + clDeforms1 clpart_deformed.append(clpart_deformed1) # clpart = cl[min(indpoint1[0], indpoint2[0]):max(indpoint1[0], indpoint2[0])+1] clpart = clpart_deformed[min(indpoint1[0], indpoint2[0]):max(indpoint1[0], indpoint2[0])+1] # for i in range(len(clpart)): # clpartDeforms1 = model.node[clpart[i,0], clpart[i,1], clpart[i,2]]['deforms'] # clpartDeforms.append(clpartDeforms1) # clpart_deformed1_test = cl[i] + clpartDeforms1 # clpart_deformed_test.append(clpart_deformed1_test) # for k in range(len(n1Indices)): # vectors_phases = np.vstack([clpart_deformed_test[i+1][k]-clpart_deformed_test[i][k] for i in range(len(clpart)-1)]) # vectors.append(vectors_phases) for k in range(len(n1Indices)): vectors_phases = np.vstack([clpart[i+1][k]-clpart[i][k] for i in range(len(clpart)-1)]) vectors.append(vectors_phases) for i in range(len(vectors)): if type == 'euclidian': d1 = (vectors[i][:,0]**2 + vectors[i][:,1]**2 + vectors[i][:,2]**2)**0.5 # 3Dvector length in mm d.append(d1) elif type == 'z': d = abs(vectors[i][:,2]) # x,y,z ; 1Dvector length in mm for i in range(len(d)): dist = d[i].sum() dist_cl.append(dist) #if indpoint2 > indpoint1: # stent point proximal to renal on centerline: positive #dist_cl*=-1 cl_min_index1 = np.argmin(dist_cl) cl_min_index = cl_min_index1*10 cl_min = min(dist_cl) cl_max_index1 = np.argmax(dist_cl) cl_max_index = cl_max_index1*10 cl_max = max(dist_cl) print ([dist_cl]) print ([point1, point2]) return {'point_to_pointMin': point_to_pointMin, 'point_to_pointQ1': point_to_pointQ1, 'point_to_pointMedian': point_to_pointMedian, 'point_to_pointQ3': point_to_pointQ3, 'point_to_pointMax': point_to_pointMax, 'point_to_pointP': point_to_pointP, 'Node1': [point1, point1Deforms], 'Node2': [point2, point2Deforms], 'distances': distances, 'dist_cl': dist_cl, 'cl_min_index': cl_min_index, 'cl_max_index': cl_max_index, 'cl_min': cl_min, 'cl_max': cl_max} def line_line_angulation(point1, point1Deforms, point2, point2Deforms, point3, point3Deforms): n1Indices = point1 + point1Deforms n2Indices = point2 + point2Deforms n3Indices = point3 + point3Deforms # get vectors v1 = n1Indices - n2Indices v2 = n3Indices - n2Indices # get angles angles = [] for i in range(len(v1)): angles.append(math.degrees(math.acos((np.dot(v1[i],v2[i]))/ (np.linalg.norm(v1[i])*np.linalg.norm(v2[i]))))) angles = np.array(angles) # get all angle differences of all phases pos_combinations = list(itertools.combinations(range(len(v1)),2)) angle_diff = [] for i in pos_combinations: v = point1Deforms[i[0]] - point1Deforms[i[1]] angle_diff.append(abs(angles[i[0]] - angles[i[1]])) angle_diff = np.array(angle_diff) # get max angle differences point_angle_diff_max = angle_diff.max() point_angle_diff_max = [point_angle_diff_max, [x*10 for x in (pos_combinations[list(angle_diff).index(point_angle_diff_max)])]] # get min angle differences point_angle_diff_min = angle_diff.min() point_angle_diff_min = [point_angle_diff_min, [x*10 for x in (pos_combinations[list(angle_diff).index(point_angle_diff_min)])]] return {'point_angle_diff_min':point_angle_diff_min, 'point_angle_diff_max': point_angle_diff_max, 'angles': angles, 'Node1': [point1, point1Deforms], 'Node2': [point2, point2Deforms], 'Node3': [point3, point1Deforms]} def append_centerlines(allcenterlines): """ Merge seperated PointSet centerlines into one PointSet """ # cl_merged = allcenterlines[0] cl_merged = PointSet(3) for i in range(0,len(allcenterlines)): for point in allcenterlines[i]: cl_merged.append(point) return cl_merged def get_index_name(): # Gui for input name app = QtGui.QApplication([]) m = MyDialog() m.show() m.exec_() dialog_output = m.edit.text() return dialog_output def storeOutputToExcel(storeOutput, exceldir): """Create file and add a worksheet or overwrite existing """ # https://pypi.python.org/pypi/XlsxWriter workbook = xlsxwriter.Workbook(os.path.join(exceldir,'storeOutput.xlsx')) worksheet = workbook.add_worksheet('General') # set column width worksheet.set_column('A:A', 35) worksheet.set_column('B:B', 30) # add a bold format to highlight cells bold = workbook.add_format({'bold': True}) # write title and general tab worksheet.write('A1', 'Output ChEVAS dynamic CT, 10 Phases', bold) analysisID = '%s_%s_%s' % (ptcode, ctcode, cropname) worksheet.write('A2', 'Filename:', bold) worksheet.write('B2', analysisID) worksheet.write('A3', 'Date and Time:', bold) date_time = datetime.now() #strftime("%d-%m-%Y %H:%M") date_format_str = 'dd-mm-yyyy hh:mm' date_format = workbook.add_format({'num_format': date_format_str, 'align': 'left'}) worksheet.write_datetime('B3', date_time, date_format) # write 'storeOutput' sort_index = [] for i in range(len(storeOutput)): type = len(storeOutput[i]['NodesIndex']) sort_index.append([i, type]) sort_index = np.array(sort_index) sort_index = sort_index[sort_index[:,1].argsort()] for i, n in sort_index: worksheet = workbook.add_worksheet(storeOutput[i]['Name']) worksheet.set_column('A:A', 35) worksheet.set_column('B:B', 20) worksheet.write('A1', 'Name:', bold) worksheet.write('B1', storeOutput[i]['Name']) if n == 1: worksheet.write('A2', 'Type:', bold) worksheet.write('B2', '1 Node') worksheet.write('A3', 'Minimum translation (mm, Phases)',bold) worksheet.write('B3', storeOutput[i]['point_phase_min'][0]) worksheet.write_row('C3', list(storeOutput[i]['point_phase_min'][1])) worksheet.write('A4', 'Maximum translation (mm, Phases)',bold) worksheet.write('B4', storeOutput[i]['point_phase_max'][0]) worksheet.write_row('C4', list(storeOutput[i]['point_phase_max'][1])) worksheet.write('A5', 'Avg node position and deformations', bold) worksheet.write('B5', str(list(storeOutput[i]['Node1'][0]))) worksheet.write_row('C5', [str(x)for x in list(storeOutput[i]['Node1'][1])]) worksheet.write('A6', 'Node Index Number', bold) worksheet.write_row('B6', list(storeOutput[i]['NodesIndex'])) elif n == 2: worksheet.write('A2', 'Type:', bold) worksheet.write('B2', '2 Nodes') worksheet.write('A3', 'Minimum distance (mm, Phases)',bold) worksheet.write('B3', storeOutput[i]['point_to_pointMin'][0]) worksheet.write('C3', storeOutput[i]['point_to_pointMin'][1]) worksheet.write('A4', 'Q1 distance (mm)',bold) worksheet.write('B4', storeOutput[i]['point_to_pointQ1']) worksheet.write('A5', 'Median distance (mm)',bold) worksheet.write('B5', storeOutput[i]['point_to_pointMedian']) worksheet.write('A6', 'Q3 distance (mm)',bold) worksheet.write('B6', storeOutput[i]['point_to_pointQ3']) worksheet.write('A7', 'Maximum distance (mm, phases)',bold) worksheet.write('B7', storeOutput[i]['point_to_pointMax'][0]) worksheet.write('C7', storeOutput[i]['point_to_pointMax'][1]) worksheet.write('A8', 'Maximum distance difference (mm)', bold) worksheet.write('B8', storeOutput[i]['point_to_pointP'][0]) worksheet.write('A9', 'Distances for each phase', bold) worksheet.write_row('B9', [str(x) for x in list(storeOutput[i]['distances'])]) worksheet.write('A10', 'Avg node1 position and deformations', bold) worksheet.write('B10', str(list(storeOutput[i]['Node1'][0]))) worksheet.write_row('C10', [str(x) for x in list(storeOutput[i]['Node1'][1])]) worksheet.write('A11', 'Avg node2 position and deformations', bold) worksheet.write('B11', str(list(storeOutput[i]['Node2'][0]))) worksheet.write_row('C11', [str(x) for x in list(storeOutput[i]['Node2'][1])]) worksheet.write('A12', 'Node Index Number', bold) worksheet.write_row('B12', list(storeOutput[i]['NodesIndex'])) worksheet.write('A13', 'Length centerline', bold) worksheet.write('B13', str(list(storeOutput[i]['dist_cl']))) worksheet.write('A14', 'Minimum length centerline', bold) worksheet.write('B14', storeOutput[i]['cl_min']) worksheet.write('C14', storeOutput[i]['cl_min_index']) worksheet.write('A15', 'Maximum length centerline', bold) worksheet.write('B15', storeOutput[i]['cl_max']) worksheet.write('C15', storeOutput[i]['cl_max_index']) elif n == 3: worksheet.write('A2', 'Type:', bold) worksheet.write('B2', '3 Nodes') worksheet.write('A3', 'Minimum angle difference (degrees, Phases)',bold) worksheet.write('B3', storeOutput[i]['point_angle_diff_min'][0]) worksheet.write_row('C3', list(storeOutput[i]['point_angle_diff_min'][1])) worksheet.write('A4', 'Maximum angle difference (degrees, Phases)',bold) worksheet.write('B4', storeOutput[i]['point_angle_diff_max'][0]) worksheet.write_row('C4', list(storeOutput[i]['point_angle_diff_max'][1])) worksheet.write('A5', 'Angles for each phase (degrees)',bold) worksheet.write_row('B5', list(storeOutput[i]['angles'])) worksheet.write('A6', 'Avg node1 position and deformations', bold) worksheet.write('B6', str(list(storeOutput[i]['Node1'][0]))) worksheet.write_row('C6', [str(x) for x in list(storeOutput[i]['Node1'][1])]) worksheet.write('A7', 'Avg node2 position and deformations', bold) worksheet.write('B7', str(list(storeOutput[i]['Node2'][0]))) worksheet.write_row('C7', [str(x) for x in list(storeOutput[i]['Node2'][1])]) worksheet.write('A8', 'Avg node2 position and deformations', bold) worksheet.write('B8', str(list(storeOutput[i]['Node3'][0]))) worksheet.write_row('C8', [str(x) for x in list(storeOutput[i]['Node3'][1])]) worksheet.write('A9', 'Node Index Number', bold) worksheet.write_row('B9', list(storeOutput[i]['NodesIndex'])) workbook.close() # Bind event handlers fig.eventKeyDown.Bind(on_key) for node_point in node_points: node_point.eventDoubleClick.Bind(select_node) node_point.eventEnter.Bind(pick_node) node_point.eventLeave.Bind(unpick_node)
from stentseg.utils.visualization import DrawModelAxes import visvis as vv from stentseg.utils import _utils_GUI # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup', r'G:\LSPEAS_ssdf_backup') # Select dataset to register ptcode = 'LSPEAS_008' ctcode = '1month' cropname = 'stent' what = 'phases' # avgreg # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) vol = s.vol80 clim = (0, 2500) # clim = (-100,300) showVol = '2D' fig = vv.figure(2) vv.clf() fig.position = 0.00, 22.00, 1920.00, 1018.00 label = DrawModelAxes(vol, clim=clim, showVol=showVol) # lc, mc a = vv.gca() # bind rotate view [a,d rotate; z,x axes] fig.eventKeyDown.Bind(lambda event: _utils_GUI.RotateView(event, [a]))
for i, vol in enumerate(vols2): print(vol.meta.sampling) phase = int(vol.meta.SeriesDescription[:1]) vols[phase] = vol for j, vol in enumerate(vols): print(vol.meta.SeriesDescription) assert vol.shape == vols[0].shape assert str(j * 10) in vol.meta.SeriesDescription # 0% , 10% etc. ## Step B: Crop and Save SSDF for cropname in cropnames: savecropvols(vols, basedir, ptcode, ctcode, cropname, stenttype) ## Visualize result s1 = loadvol(basedir, ptcode, ctcode, cropnames[0], what='10phases') vol1 = s1.vol40 vol2 = s1.vol90 # Visualize and compare colormap = { 'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)] } import visvis as vv fig = vv.figure(1) vv.clf() fig.position = 0, 22, 1366, 706
# Select the ssdf basedir basedir = select_dir(r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup', r'G:\LSPEAS_ssdf_backup') basedirstl = select_dir( r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation', r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation') # Select dataset ptcode = 'LSPEAS_008' ctcode = 'discharge' cropname = 'stent' what = 'centerline' # Load deforms s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms') deformkeys = [] for key in dir(s): if key.startswith('deform'): deformkeys.append(key) deforms = [s[key] for key in deformkeys] deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms] paramsreg = s.params # Load centerline mat matName = '%s_%s_%s_%s.mat' % (ptcode, ctcode, cropname, what) centerlineMat = scipy.io.loadmat(os.path.join(basedirstl, ptcode, matName)) # Load model s = loadmodel(basedirstl, ptcode, ctcode, cropname, what) for key in dir(s):
def __init__(self, dicom_basedir, ptcode, ctcode, basedir): import imageio #import easygui from stentseg.utils.datahandling import loadvol from stentseg.utils.datahandling import savecropvols, saveaveraged ## Select base directory for LOADING DICOM data #dicom_basedir = easygui.diropenbox() print('DICOM Path = ', dicom_basedir) #ctcode = '12months' # 'pre', 'post_x', '12months' stenttype = 'nellix' ## Select base directory to SAVE SSDF #basedir = easygui.diropenbox() print('Base Path = ', basedir) # Set which crops to save cropnames = ['prox'] #,'stent'] # ['ring'] or ['ring','stent'] or .. #=============================================================================== ## Step A: read single volumes to get vols: # folder1 = '10%' # folder2 = '60%' # vol1 = imageio.volread(os.path.join(dicom_basedir, folder1), 'dicom') # vol2 = imageio.volread(os.path.join(dicom_basedir, folder2), 'dicom') # print( ) # # if vol1.meta.SeriesDescription[:2] < vol2.meta.SeriesDescription[:2]: # vols4078 = [vol1,vol2] # else: # vols4078 = [vol2,vol1] # # vols = vols4078.copy() # # for vol in vols: # vol.meta.PatientName = ptcode # anonimyze # vol.meta.PatientID = 'anonymous' # print(vol.meta.SeriesDescription,'-', vol.meta.sampling) #=============================================================================== ##Orginele code #=============================================================================== # # folder1 = '40% iDose' # folder2 = '78 iDose' # vol1 = imageio.volread(os.path.join(dicom_basedir, folder1), 'dicom') # vol2 = imageio.volread(os.path.join(dicom_basedir, folder2), 'dicom') # print( ) # # if vol1.meta.SeriesDescription[:2] < vol2.meta.SeriesDescription[:2]: # vols4078 = [vol1,vol2] # else: # vols4078 = [vol2,vol1] # # vols = vols4078.copy() # # for vol in vols: # vol.meta.PatientName = ptcode # anonimyze # vol.meta.PatientID = 'anonymous' # print(vol.meta.SeriesDescription,'-', vol.meta.sampling) #=============================================================================== ## Step A: read 10 volumes to get vols # Deze zoekt alle mappen en dat zijn er dus 10 maar niet in de goede volgorde vols2 = [ vol2 for vol2 in imageio.get_reader(dicom_basedir, 'DICOM', 'V') ] vols = [None] * len(vols2) for i, vol in enumerate(vols2): # print(vol.meta.sampling) print(vol.meta.SeriesDescription) phase = int(vol.meta.SeriesDescription[:1]) # use phase to fix order of phases vols[phase] = vol #vols[phase].meta.ImagePositionPatient = (0.0,0.0,0.0) for i, vol in enumerate( vols): #wat ik heb veranderd is i, en enumerate() print(vol.meta.SeriesDescription) assert vol.shape == vols[0].shape assert str(i * 10) in vol.meta.SeriesDescription # 0% , 10% etc. ## Step B: Crop and Save SSDF # 1 of 2 cropnames opgeven voor opslaan 1 of 2 crpos. # Het eerste volume wordt geladen in MIP, crop met marges van minimaal 30 mm for cropname in cropnames: savecropvols(vols, basedir, ptcode, ctcode, cropname, stenttype) # saveaveraged(basedir, ptcode, ctcode, cropname, range(0,100,10)) ## Visualize result #s1 = loadvol(basedir, ptcode, ctcode, cropnames[0], what ='10avgreg') #s2 = loadvol(basedir, ptcode, ctcode, cropnames[0], what ='10phases') s1 = loadvol(basedir, ptcode, ctcode, cropnames[0], what='phases') #s2 = loadvol(basedir, ptcode, ctcode, cropnames[0], what = 'avg010') #vol1 = s1.vol vol1 = s1.vol40 # Visualize and compare colormap = { 'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)] } import visvis as vv fig = vv.figure(1) vv.clf() fig.position = 0, 22, 1366, 706 a1 = vv.subplot(111) a1.daspect = 1, 1, -1 # t1 = vv.volshow(vol1, clim=(0, 3000), renderStyle='iso') # iso or mip # t1.isoThreshold = 600 # stond op 400 maar je moet hoger zetten als je alleen stent wil # t1.colormap = colormap a1 = vv.volshow2(vol1, clim=(-500, 1500), renderStyle='mip') vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') # vv.title('One volume at %i procent of cardiac cycle' % phase ) vv.title('Vol40')
from stentseg.utils.visualization import DrawModelAxes, show_ctvolume from stentseg.utils.utils_graphs_pointsets import get_graph_in_phase from stentseg.utils.picker import pick3d basedir = select_dir(r'E:\Nellix_chevas\CT_SSDF\SSDF_automated', r'D:\Nellix_chevas_BACKUP\CT_SSDF\SSDF_automated') ptcode = 'chevas_09_thin' ctcode = '12months' phases = range(10) # all 10 phases showmodelavgreg = True showvol = True # get vol for reference s = loadvol(basedir, ptcode, ctcode, 'prox', what='avgreg') # set sampling for cases where this was not stored correctly s.vol.sampling = [s.sampling[1], s.sampling[1], s.sampling[2]] vol = s.vol s_modelcll = loadmodel(basedir, ptcode, ctcode, 'prox', modelname='centerline_total_modelavgreg_deforms') # get graph modelcll = s_modelcll.model s_modelcll_vessel = loadmodel(basedir, ptcode, ctcode,
else: vol = imageio.volread(os.path.join(dicom_basedir, ptcode, ctcode), 'dicom') print () print(vol.meta.SeriesDescription) print(vol.meta.sampling) print() # Step B: Crop and Save SSDF vols = [vol] for cropname in cropnames: savecropvols(vols, ssdf_basedir, ptcode, ctcode, cropname, stenttype) ## Visualize result s1 = loadvol(ssdf_basedir, ptcode, ctcode, cropnames[0], what ='phase') vol = s1.vol # Visualize and compare colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} import visvis as vv fig = vv.figure(1); vv.clf() fig.position = 0, 22, 1366, 706 a = vv.gca() a.daspect = 1,1,-1 t1 = vv.volshow(vol, clim=(0, 2500), renderStyle='iso') # iso or mip t1.isoThreshold = 400
def showVolPhases(basedir, vols=None, ptcode=None, ctcode=None, cropname=None, showVol='iso', mipIsocolor=False, isoTh=310, slider=False, clim=(0,3000), clim2D=(-550, 500), fname=None): """ Show vol phases in motion container showVol= mip or iso or 2D; Provide either vols or location """ if vols is None: # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, 'phases', fname=fname) vols = [] for key in dir(s): if key.startswith('vol'): vols.append(s[key]) # Start vis f = vv.figure(1); vv.clf() f.position = 9.00, 38.00, 992.00, 944.00 a = vv.gca() a.daspect = 1, 1, -1 a.axis.axisColor = 1,1,1 a.axis.visible = False a.bgcolor = 0,0,0 if showVol=='mip': if not ptcode is None and not ctcode is None: vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode)) else: vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes ') else: if not ptcode is None and not ctcode is None: vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode)) else: vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes ') # Setup data container container = vv.MotionDataContainer(a) for vol in vols: if showVol == '2D': t = vv.volshow2(vol, clim=clim2D) # -750, 1000 t.parent = container else: t = vv.volshow(vol, clim=clim, renderStyle = showVol) t.parent = container if showVol == 'iso': t.isoThreshold = isoTh # iso or mip work well t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} if mipIsocolor: t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} # bind ClimEditor to figure if slider: if showVol=='mip': c = vv.ClimEditor(vv.gcf()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) ) if showVol=='iso': c = IsoThEditor(vv.gcf()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) ) f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, [a]) ) print('------------------------') print('Use keys 1, 2, 3, 4 and 5 for preset anatomic views') print('Use v for a default zoomed view') print('Use x to show and hide axis') print('------------------------') return t
def __init__(self,ptcode,ctcode,basedir, threshold=300, show=True, normalize=False, modelname='modelvessel'): import os import numpy as np import visvis as vv from visvis import ssdf from stentseg.utils import PointSet, _utils_GUI from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.stentdirect.stentgraph import create_mesh from stentseg.stentdirect import stentgraph, StentDirect, getDefaultParams from stentseg.stentdirect import AnacondaDirect, EndurantDirect, NellixDirect from stentseg.utils.visualization import show_ctvolume from stentseg.utils.picker import pick3d, label2worldcoordinates, label2volindices import scipy from scipy import ndimage import copy from stentseg.utils.get_isosurface import get_isosurface3d, isosurface_to_graph, show_surface_and_vol # Select dataset to register cropname = 'prox' #phase = 10 #what = 'phase'+str(phase) what = 'avgreg' # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) # sampling was not properly stored after registration for all cases: reset sampling vol_org = copy.deepcopy(s.vol) s.vol.sampling = [vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]] # z,y,x s.sampling = s.vol.sampling vol = s.vol # Get isosurface verts, faces, pp_vertices, mesh = get_isosurface3d(vol, threshold=threshold, showsurface=False) if show: self.label = show_surface_and_vol(vol, pp_vertices, showVol='MIP') # Convert to graph model = isosurface_to_graph(pp_vertices) # model with nodes # Store segmentation to disk p = threshold stentType = 'isosurface' # Build struct s2 = vv.ssdf.new() s2.sampling = s.sampling s2.origin = s.origin s2.stenttype = s.stenttype s2.croprange = s.croprange for key in dir(s): if key.startswith('meta'): suffix = key[4:] s2['meta'+suffix] = s['meta'+suffix] s2.what = what s2.params = p s2.stentType = stentType # Store model (not also volume) s2.model = model.pack() # Save filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, modelname+ what) ssdf.save(os.path.join(basedir, ptcode, filename), s2) print('saved to disk as {}.'.format(filename) )
from stentseg.utils import PointSet, _utils_GUI, visualization basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_BACKUP', r'G:\LSPEAS_ssdf_BACKUP') ptcode = 'LSPEAS_025' ctcode = '1month' cropname = 'ring' modelname = 'modelavgreg' s = loadmodel(basedir, ptcode, ctcode, cropname, modelname) model = s.model.copy() # Load volume s_vol = loadvol(basedir, ptcode, ctcode, cropname, 'avgreg') vol = s_vol.vol # Load deforms s_deforms = loadvol(basedir, ptcode, ctcode, cropname, 'deforms') deformkeys = [] for key in dir(s_deforms): if key.startswith('deform'): deformkeys.append(key) deforms = [s_deforms[key] for key in deformkeys] deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms] selected_nodes = list() node_points, t3 = nodeInteraction(model, vol, selected_nodes) print(s.origin) # for same crop the origins should be the same
def identifyCenterlines(s, ptcode, ctcode, basedir, modelname, showVol='MIP', **kwargs): """ s is struct with models """ from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.utils.picker import pick3d from stentseg.utils.visualization import show_ctvolume from stentseg.utils import _utils_GUI showAxis = False # showVol = 'MIP' # MIP or ISO or 2D or None clim = (0, 2500) # clim = -200,500 # 2D isoTh = 250 cropname = 'prox' # init fig f = vv.figure() vv.clf() f.position = 0.00, 22.00, 1920.00, 1018.00 # load vol svol = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg') # set sampling for cases where this was not stored correctly svol.vol.sampling = [svol.sampling[1], svol.sampling[1], svol.sampling[2]] vol = svol.vol s.sampling = [svol.sampling[1], svol.sampling[1], svol.sampling[2]] # for model # show vol t = show_ctvolume(vol, showVol=showVol, clim=clim, isoTh=isoTh, **kwargs) label = pick3d(vv.gca(), vol) vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') if showVol == 'MIP': c = vv.ClimEditor(vv.gca()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c)) print('Use "s" to show/hide slider') if showVol == 'ISO': c = _utils_GUI.IsoThEditor(vv.gca()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c)) print('Use "s" to show/hide slider') f.eventKeyDown.Bind( lambda event: _utils_GUI.ViewPresets(event, [vv.gca()])) print('------------------------') print('Use keys 1, 2, 3, 4 and 5 for preset anatomic views') print('Use v for a default zoomed view') print('Use x to show and hide axis') print('------------------------') ax, s2 = interactiveCenterlineID(s, ptcode, ctcode, basedir, cropname, modelname) return ax, s2
def __init__(self, ptcode, ctcode, StartPoints, EndPoints, basedir, modelname='modelavgreg'): """ with start and endpoints provided, calculate centerline and save as ssdf in basedir as model and dynamic model """ #todo: name of dynamic model is now deforms, unclear, should be dynamic #import numpy as np import visvis as vv import numpy as np import os import copy from stentseg.utils import PointSet, _utils_GUI from stentseg.utils.centerline import (find_centerline, points_from_nodes_in_graph, points_from_mesh, smooth_centerline) from stentseg.utils.datahandling import loadmodel, loadvol from stentseg.utils.visualization import show_ctvolume from stentseg.utils.picker import pick3d stentnr = len(StartPoints) cropname = 'prox' what = modelname what_vol = 'avgreg' vismids = True m = loadmodel(basedir, ptcode, ctcode, cropname, what) s = loadvol(basedir, ptcode, ctcode, cropname, what_vol) s.vol.sampling = [s.sampling[1], s.sampling[1], s.sampling[2]] s.sampling = s.vol.sampling start1 = StartPoints.copy() ends = EndPoints.copy() from stentseg.stentdirect import stentgraph ppp = points_from_nodes_in_graph(m.model) allcenterlines = [] # for pp allcenterlines_nosmooth = [] # for pp centerlines = [] # for stentgraph nodes_total = stentgraph.StentGraph() for j in range(stentnr): if j == 0 or not start1[j] == ends[j - 1]: # if first stent or when stent did not continue with this start point nodes = stentgraph.StentGraph() centerline = PointSet(3) # empty # Find main centerline # if j > 3: # for stent with midpoints # centerline1 = find_centerline(ppp, start1[j], ends[j], step= 1, # ndist=10, regfactor=0.5, regsteps=10, verbose=False) #else: centerline1 = find_centerline(ppp, start1[j], ends[j], step=1, ndist=10, regfactor=0.5, regsteps=1, verbose=False) # centerline1 is a PointSet print('Centerline calculation completed') # ========= Maaike ======= smoothfactor = 15 # Mirthe used 2 or 4 # check if cll continued here from last end point if not j == 0 and start1[j] == ends[j - 1]: # yes we continued ppart = centerline1[: -1] # cut last but do not cut first point as this is midpoint else: # do not use first points, as they are influenced by user selected points ppart = centerline1[1:-1] for p in ppart: centerline.append(p) # if last stent or stent does not continue with next start-endpoint if j == stentnr - 1 or not ends[j] == start1[j + 1]: # store non-smoothed for vis allcenterlines_nosmooth.append(centerline) pp = smooth_centerline(centerline, n=smoothfactor) # add pp to list allcenterlines.append(pp) # list with PointSet per centerline self.allcenterlines = allcenterlines # add pp as nodes for i, p in enumerate(pp): p_as_tuple = tuple(p.flat) nodes.add_node(p_as_tuple) nodes_total.add_node(p_as_tuple) # add pp as one edge so that pathpoints are in fixed order pstart = tuple(pp[0].flat) pend = tuple(pp[-1].flat) nodes.add_edge(pstart, pend, path=pp) nodes_total.add_edge(pstart, pend, path=pp) # add final centerline nodes model to list centerlines.append(nodes) # ========= Maaike ======= ## Store segmentation to disk # Build struct s2 = vv.ssdf.new() s2.sampling = s.sampling s2.origin = s.origin s2.stenttype = m.stenttype s2.croprange = m.croprange for key in dir(m): if key.startswith('meta'): suffix = key[4:] s2['meta' + suffix] = m['meta' + suffix] s2.what = what s2.params = s.params #reg s2.paramsseeds = m.params s2.stentType = 'nellix' s2.StartPoints = StartPoints s2.EndPoints = EndPoints # keep centerlines as pp also [Maaike] s2.ppallCenterlines = allcenterlines for k in range(len(allcenterlines)): suffix = str(k) pp = allcenterlines[k] s2['ppCenterline' + suffix] = pp s3 = copy.deepcopy(s2) s3['model'] = nodes_total.pack() # Store model for each centerline for j in range(len(centerlines)): suffix = str(j) model = centerlines[j] s2['model' + suffix] = model.pack() # Save model with seperate centerlines. filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'centerline_' + what) vv.ssdf.save(os.path.join(basedir, ptcode, filename), s2) print('saved to disk as {}.'.format(filename)) # Save model with combined centerlines filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'centerline_total_' + what) vv.ssdf.save(os.path.join(basedir, ptcode, filename), s3) print('saved to disk as {}.'.format(filename)) # remove intermediate centerline points # start1 = map(tuple, start1) # ends = map(tuple, ends) startpoints_clean = copy.deepcopy(start1) endpoints_clean = copy.deepcopy(ends) duplicates = list(set(start1) & set(ends)) for i in range(len(duplicates)): startpoints_clean.remove(duplicates[i]) endpoints_clean.remove(duplicates[i]) #Visualize f = vv.figure(10) vv.clf() a1 = vv.subplot(121) a1.daspect = 1, 1, -1 vv.plot(ppp, ms='.', ls='', alpha=0.6, mw=2) for j in range(len(startpoints_clean)): vv.plot(PointSet(list(startpoints_clean[j])), ms='.', ls='', mc='g', mw=20) # startpoint green vv.plot(PointSet(list(endpoints_clean[j])), ms='.', ls='', mc='r', mw=20) # endpoint red for j in range(len(allcenterlines)): vv.plot(allcenterlines[j], ms='.', ls='', mw=10, mc='y') vv.title('Centerlines and seed points') vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') # for j in range(len(allcenterlines_nosmooth)): # vv.plot(allcenterlines_nosmooth[j], ms='o', ls='', mw=10, mc='c', alpha=0.6) a2 = vv.subplot(122) a2.daspect = 1, 1, -1 vv.plot(ppp, ms='.', ls='', alpha=0.6, mw=2) # vv.volshow(s.vol, clim=clim, renderStyle = 'mip') t = show_ctvolume(s.vol, axis=a2, showVol='ISO', clim=(0, 2500), isoTh=250, removeStent=False, climEditor=True) label = pick3d(vv.gca(), s.vol) for j in range(len(startpoints_clean)): vv.plot(PointSet(list(startpoints_clean[j])), ms='.', ls='', mc='g', mw=20, alpha=0.6) # startpoint green vv.plot(PointSet(list(endpoints_clean[j])), ms='.', ls='', mc='r', mw=20, alpha=0.6) # endpoint red for j in range(len(allcenterlines)): vv.plot(allcenterlines[j], ms='o', ls='', mw=10, mc='y', alpha=0.6) # show midpoints (e.g. duplicates) if vismids: for p in duplicates: vv.plot(p[0], p[1], p[2], mc='m', ms='o', mw=10, alpha=0.6) a2.axis.visible = False vv.title('Centerlines and seed points') a1.camera = a2.camera f.eventKeyDown.Bind( lambda event: _utils_GUI.RotateView(event, [a1, a2])) f.eventKeyDown.Bind( lambda event: _utils_GUI.ViewPresets(event, [a1, a2])) # Pick node for midpoint to redo get_centerline self.pickedCLLpoint = _utils_GUI.Event_pick_graph_point( nodes_total, s.vol, label, nodesOnly=True) # x,y,z # use key p to select point #=============================================================================== vv.figure(11) vv.gca().daspect = 1, 1, -1 t = show_ctvolume(s.vol, showVol='ISO', clim=(0, 2500), isoTh=250, removeStent=False, climEditor=True) label2 = pick3d(vv.gca(), s.vol) for j in range(len(startpoints_clean)): vv.plot(PointSet(list(startpoints_clean[j])), ms='.', ls='', mc='g', mw=20, alpha=0.6) # startpoint green vv.plot(PointSet(list(endpoints_clean[j])), ms='.', ls='', mc='r', mw=20, alpha=0.6) # endpoint red vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') #=============================================================================== ## Make model dynamic (and store/overwrite to disk) import pirt from stentseg.motion.dynamic import incorporate_motion_nodes, incorporate_motion_edges # Load deforms filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'deforms') s1 = vv.ssdf.load(os.path.join(basedir, ptcode, filename)) deformkeys = [] for key in dir(s1): if key.startswith('deform'): deformkeys.append(key) deforms = [s1[key] for key in deformkeys] deforms = [ pirt.DeformationFieldBackward(*fields) for fields in deforms ] for i in range(len(deforms)): deforms[i]._field_sampling = tuple(s1.sampling) paramsreg = s1.params # Load model s2 = loadmodel(basedir, ptcode, ctcode, cropname, 'centerline_' + what) s3 = loadmodel(basedir, ptcode, ctcode, cropname, 'centerline_total_' + what) # Combine ... for key in dir(s2): if key.startswith('model'): incorporate_motion_nodes(s2[key], deforms, s.origin) incorporate_motion_edges(s2[key], deforms, s.origin) model = s2[key] s2[key] = model.pack() # Combine ... for key in dir(s3): if key.startswith('model'): incorporate_motion_nodes(s3[key], deforms, s.origin) incorporate_motion_edges(s3[key], deforms, s.origin) model = s3[key] s3[key] = model.pack() # Save s2.paramsreg = paramsreg filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'centerline_' + what + '_deforms') vv.ssdf.save(os.path.join(basedir, ptcode, filename), s2) print('saved to disk as {}.'.format(filename)) # Save s3.paramsreg = paramsreg filename = '%s_%s_%s_%s.ssdf' % ( ptcode, ctcode, cropname, 'centerline_total_' + what + '_deforms') vv.ssdf.save(os.path.join(basedir, ptcode, filename), s3) print('saved to disk as {}.'.format(filename))
print("avgreg saved to disk.") t1 = time.time() t_in_min = (t1 - t0) / 60 print('Registration completed for %s - %s, which took %1.2f min.' % (ptcode, ctcode, t_in_min)) ## Load deforms and apply deform to registered phases/vols if visualize: #load avgreg avg = 'avgreg' filename = '%s_%s.ssdf' % (fileTr, avg) savg = loadvol(dirsaveinsilico, ptcode, ctcode, None, 'avgreg', fname=filename) # loadvol sets savg.sampling and savg.origin vol = savg.vol # show #f = vv.figure(2); vv.clf() #f.position = 968.00, 30.00, 944.00, 1002.00 #a = vv.subplot(111) #a.daspect = 1, 1, -1 if reg2d: t = vv.imshow(vol, clim=clim, axes=a4) else: t = vv.volshow(vol, clim=clim, renderStyle='mip', axes=a4) #t.isoThreshold = 600 vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z')
def __init__(self,ptcode,ctcode,basedir, seed_th=[600], show=True, normalize=False, modelname='model'): import os import numpy as np import visvis as vv from visvis import ssdf from stentseg.utils import PointSet, _utils_GUI from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.stentdirect.stentgraph import create_mesh from stentseg.stentdirect import stentgraph, StentDirect, getDefaultParams from stentseg.stentdirect import AnacondaDirect, EndurantDirect, NellixDirect from stentseg.utils.visualization import show_ctvolume from stentseg.utils.picker import pick3d, label2worldcoordinates, label2volindices import scipy from scipy import ndimage import copy # Select dataset to register cropname = 'prox' # phase = 10 #dataset = 'avgreg' #what = str(phase) + dataset # avgreg what = 'avgreg' # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) # sampling was not properly stored after registration for all cases: reset sampling vol_org = copy.deepcopy(s.vol) s.vol.sampling = [vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2]] # z,y,x s.sampling = s.vol.sampling vol = s.vol ## Initialize segmentation parameters stentType = 'nellix' # 'zenith';'nellix' runs modified pruning algorithm in Step3 p = getDefaultParams(stentType) p.seed_threshold = seed_th # step 1 [lower th] or [lower th, higher th] # p.seedSampleRate = 7 # step 1, nellix p.whatphase = what ## Perform segmentation # Instantiate stentdirect segmenter object if stentType == 'anacondaRing': sd = AnacondaDirect(vol, p) # inherit _Step3_iter from AnacondaDirect class #runtime warning using anacondadirect due to mesh creation, ignore elif stentType == 'endurant': sd = EndurantDirect(vol, p) elif stentType == 'nellix': sd = NellixDirect(vol, p) else: sd = StentDirect(vol, p) ## show histogram and normalize # f = vv.figure(3) # a = vv.gca() # vv.hist(vol, drange=(300,vol.max())) # normalize vol to certain limit if normalize: sd.Step0(3071) vol = sd._vol # b= vv.hist(vol, drange=(300,3071)) # b.color = (1,0,0) ## Perform step 1 for seeds sd.Step1() ## Visualize if show: fig = vv.figure(2); vv.clf() fig.position = 0.00, 22.00, 1920.00, 1018.00 clim = (0,2000) # Show volume and model as graph a1 = vv.subplot(121) a1.daspect = 1,1,-1 # t = vv.volshow(vol, clim=clim) t = show_ctvolume(vol, axis=a1, showVol='MIP', clim =clim, isoTh=250, removeStent=False, climEditor=True) label = pick3d(vv.gca(), vol) sd._nodes1.Draw(mc='b', mw = 2) # draw seeded nodes #sd._nodes2.Draw(mc='b', lc = 'g') # draw seeded and MCP connected nodes vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') # Show volume and cleaned up graph a2 = vv.subplot(122) a2.daspect = 1,1,-1 sd._nodes1.Draw(mc='b', mw = 2) # draw seeded nodes # t = vv.volshow(vol, clim=clim) # label = pick3d(vv.gca(), vol) # sd._nodes2.Draw(mc='b', lc='g') # sd._nodes3.Draw(mc='b', lc='g') vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') # # Show the mesh #=============================================================================== # a3 = vv.subplot(133) # a3.daspect = 1,1,-1 # t = vv.volshow(vol, clim=clim) # pick3d(vv.gca(), vol) # #sd._nodes3.Draw(mc='b', lc='g') # m = vv.mesh(bm) # m.faceColor = 'g' # # _utils_GUI.vis_spared_edges(sd._nodes3) # vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') #=============================================================================== # Use same camera a1.camera = a2.camera #= a3.camera switch = True a1.axis.visible = switch a2.axis.visible = switch #a3.axis.visible = switch ## Store segmentation to disk # Get graph model model = sd._nodes1 # Build struct s2 = vv.ssdf.new() s2.sampling = s.sampling s2.origin = s.origin s2.stenttype = s.stenttype s2.croprange = s.croprange for key in dir(s): if key.startswith('meta'): suffix = key[4:] s2['meta'+suffix] = s['meta'+suffix] s2.what = what s2.params = p s2.stentType = stentType # Store model (not also volume) s2.model = model.pack() # Save filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, modelname+ what) ssdf.save(os.path.join(basedir, ptcode, filename), s2) print('saved to disk as {}.'.format(filename) ) ## Make model dynamic (and store/overwrite to disk) #=============================================================================== # # import pirt # from stentsegf.motion.dynamic import incorporate_motion_nodes, incorporate_motion_edges # # # Load deforms # s = loadvol(basedir, ptcode, ctcode, cropname, '10deforms') # deformkeys = [] # for key in dir(s): # if key.startswith('deform'): # deformkeys.append(key) # deforms = [s[key] for key in deformkeys] # deforms = [pirt.DeformationFieldBackward(*fields) for fields in deforms] # paramsreg = s.params # # # Load model # s = loadmodel(basedir, ptcode, ctcode, cropname, 'model'+what) # model = s.model # # # Combine ... # incorporate_motion_nodes(model, deforms, s.origin) # incorporate_motion_edges(model, deforms, s.origin) # # # Save back # filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'model'+what) # s.model = model.pack() # s.paramsreg = paramsreg # ssdf.save(os.path.join(basedir, ptcode, filename), s) # print('saved to disk as {}.'.format(filename) ) #===============================================================================
def __init__(self, ptcode, ctcode, basedir, showVol='mip', meshWithColors=False, motion='amplitude', clim2=(0, 2)): """ Script to show the stent model. [ nellix] """ import os import pirt import visvis as vv from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from pirt.utils.deformvis import DeformableTexture3D, DeformableMesh from stentseg.stentdirect.stentgraph import create_mesh from stentseg.stentdirect import stentgraph from stentseg.utils.visualization import show_ctvolume from stentseg.motion.vis import create_mesh_with_abs_displacement import copy from stentseg.motion.dynamic import incorporate_motion_nodes, incorporate_motion_edges from lspeas.utils.ecgslider import runEcgSlider from stentseg.utils import _utils_GUI import numpy as np cropname = 'prox' # params nr = 1 # motion = 'amplitude' # amplitude or sum dimension = 'xyz' showVol = showVol # MIP or ISO or 2D or None clim0 = (0, 2000) # clim2 = (0,2) motionPlay = 9, 1 # each x ms, a step of x % s = loadvol(basedir, ptcode, ctcode, cropname, what='deforms') m = loadmodel(basedir, ptcode, ctcode, cropname, 'centerline_total_modelavgreg_deforms') v = loadmodel(basedir, ptcode, ctcode, cropname, modelname='centerline_total_modelvesselavgreg_deforms') s2 = loadvol(basedir, ptcode, ctcode, cropname, what='avgreg') vol_org = copy.deepcopy(s2.vol) s2.vol.sampling = [ vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2] ] s2.sampling = s2.vol.sampling vol = s2.vol # merge models into one for dynamic visualization model_total = stentgraph.StentGraph() for key in dir(m): if key.startswith('model'): model_total.add_nodes_from( m[key].nodes(data=True)) # also attributes model_total.add_edges_from(m[key].edges(data=True)) for key in dir(v): if key.startswith('model'): model_total.add_nodes_from( v[key].nodes(data=True)) # also attributes model_total.add_edges_from(v[key].edges(data=True)) # Load deformations (forward for mesh) deformkeys = [] for key in dir(s): if key.startswith('deform'): deformkeys.append(key) deforms = [s[key] for key in deformkeys] deforms = [[field[::2, ::2, ::2] for field in fields] for fields in deforms] # These deforms are forward mapping. Turn into DeformationFields. # Also get the backwards mapping variants (i.e. the inverse deforms). # The forward mapping deforms should be used to deform meshes (since # the information is used to displace vertices). The backward mapping # deforms should be used to deform textures (since they are used in # interpolating the texture data). deforms_f = [pirt.DeformationFieldForward(*f) for f in deforms] deforms_b = [f.as_backward() for f in deforms_f] # Create mesh if meshWithColors: try: modelmesh = create_mesh_with_abs_displacement(model_total, radius=0.7, dim=dimension, motion=motion) except KeyError: print('Centerline model has no pathdeforms so we create them') # use unsampled deforms deforms2 = [s[key] for key in deformkeys] # deforms as backward for model deformsB = [ pirt.DeformationFieldBackward(*fields) for fields in deforms2 ] # set sampling to original # for i in range(len(deformsB)): # deformsB[i]._field_sampling = tuple(s.sampling) # not needed because we use unsampled deforms # Combine ... incorporate_motion_nodes(model_total, deformsB, s2.origin) convert_paths_to_PointSet(model_total) incorporate_motion_edges(model_total, deformsB, s2.origin) convert_paths_to_ndarray(model_total) modelmesh = create_mesh_with_abs_displacement(model_total, radius=0.7, dim=dimension, motion=motion) else: modelmesh = create_mesh(model_total, 0.7, fullPaths=True) ## Start vis f = vv.figure(nr) vv.clf() if nr == 1: f.position = 8.00, 30.00, 944.00, 1002.00 else: f.position = 968.00, 30.00, 944.00, 1002.00 a = vv.gca() a.axis.axisColor = 1, 1, 1 a.axis.visible = False a.bgcolor = 0, 0, 0 a.daspect = 1, 1, -1 t = vv.volshow(vol, clim=clim0, renderStyle=showVol, axes=a) vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') if meshWithColors: if dimension == 'xyz': dim = '3D' vv.title( 'Model for chEVAS %s (color-coded %s of movement in %s in mm)' % (ptcode[8:], motion, dim)) else: vv.title('Model for chEVAS %s' % (ptcode[8:])) colorbar = True # Create deformable mesh dm = DeformableMesh(a, modelmesh) # in x,y,z dm.SetDeforms(*[list(reversed(deform)) for deform in deforms_f]) # from z,y,x to x,y,z if meshWithColors: dm.clim = clim2 dm.colormap = vv.CM_JET #todo: use colormap Viridis or Magma as JET is not linear (https://bids.github.io/colormap/) if colorbar: vv.colorbar() colorbar = False else: dm.faceColor = 'g' # Run mesh a.SetLimits() # a.SetView(viewringcrop) dm.MotionPlay(motionPlay[0], motionPlay[1]) # (10, 0.2) = each 10 ms do a step of 20% dm.motionSplineType = 'B-spline' dm.motionAmplitude = 0.5 ## run ecgslider ecg = runEcgSlider(dm, f, a, motionPlay)
# basedir = select_dir(r'D:\LSPEAS_F\LSPEASF_ssdf') # Select dataset to register # ptcode = 'QRM_FANTOOM_20160121' # ctcode = '12months' cropnames = ['stent'] ptcodes = ['LSPEAS_018', 'LSPEAS_025', 'LSPEAS_023', 'LSPEAS_024'] ctcodes = ['24months'] for ptcode in ptcodes: for ctcode in ctcodes: for cropname in cropnames: # Load volumes try: s = loadvol(basedir, ptcode, ctcode, cropname, 'phases') except FileNotFoundError: continue vols = [s['vol%i' % (i * 10)] for i in range(10)] #todo: resample to isotropic? # for vol in vols: # see function in datahandling #todo: normalize data!! comparable histograms, comparable mass image forces t0 = time.time() # Initialize registration object reg = pirt.reg.GravityRegistration(*vols) # Set params reg.params.mass_transforms = 2 # 2nd order (Laplacian) triggers more at lines
def __init__(self, ptcode, ctcode, basedir): ## Perform image registration import os, time import numpy as np import visvis as vv import pirt.reg # Python Image Registration Toolkit from stentseg.utils.datahandling import select_dir, loadvol import scipy from scipy import ndimage # Select dataset to register cropname = 'prox' what = 'phases' # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) vols = [] phases = [] for key in dir(s): if key.startswith('vol'): print(key) # create vol with zoom in z-direction zscale = (s[key].sampling[0] / s[key].sampling[1]) # z / y # resample vol using spline interpolation, 3rd order piecewise polynomial vol_zoom = scipy.ndimage.interpolation.zoom( s[key], [zscale, 1, 1], 'float32') s[key].sampling = [ s[key].sampling[1], s[key].sampling[1], s[key].sampling[2] ] # set scale and origin vol_zoom_type = vv.Aarray(vol_zoom, s[key].sampling, s[key].origin) vol = vol_zoom_type phases.append(key) vols.append(vol) t0 = time.time() # Initialize registration object reg = pirt.reg.GravityRegistration(*vols) reg.params.mass_transforms = 2 # 2nd order (Laplacian) triggers more at lines reg.params.speed_factor = 1.0 reg.params.deform_wise = 'groupwise' # groupwise! reg.params.mapping = 'backward' reg.params.deform_limit = 1.0 reg.params.final_scale = 1.0 # We might set this a wee bit lower than 1 (but slower!) reg.params.scale_sampling = 16 reg.params.final_grid_sampling = 20 reg.params.grid_sampling_factor = 0.5 # Go! reg.register(verbose=1) t1 = time.time() print('Registration completed, which took %1.2f min.' % ((t1 - t0) / 60)) # Store registration result from visvis import ssdf # Create struct s2 = vv.ssdf.new() N = len(vols) for key in dir(s): if key.startswith('meta'): s2[key] = s[key] s2.origin = s.origin s2.stenttype = s.stenttype s2.croprange = s.croprange # Obtain deform fields for i in range(N): fields = [field for field in reg.get_deform(i).as_backward()] phase = phases[i][3:] s2['deform%s' % phase] = fields s2.sampling = s2['deform%s' % phase][0].sampling # Sampling of deform is different! s2.originDeforms = s2['deform%s' % phase][0].origin # But origin is zero s2.params = reg.params # Save filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'deforms') ssdf.save(os.path.join(basedir, ptcode, filename), s2) print("deforms saved to disk.") #============================================================================ # Store averaged volume, where the volumes are registered #from visvis import ssdf # Create average volume from *all* volumes deformed to the "center" N = len(reg._ims) mean_vol = np.zeros(reg._ims[0].shape, 'float64') for i in range(N): vol, deform = reg._ims[i], reg.get_deform(i) mean_vol += deform.as_backward().apply_deformation(vol) mean_vol *= 1.0 / N # Create struct s_avg = ssdf.new() for key in dir(s): if key.startswith('meta'): s_avg[key] = s[key] s_avg.sampling = s.vol0.sampling # z, y, x after interpolation s_avg.origin = s.origin s_avg.stenttype = s.stenttype s_avg.croprange = s.croprange s_avg.vol = mean_vol.astype('float32') s_avg.params = s2.params fig1 = vv.figure(1) vv.clf() fig1.position = 0, 22, 1366, 706 a1 = vv.subplot(111) a1.daspect = 1, 1, -1 renderstyle = 'mip' a1b = vv.volshow(s_avg.vol, clim=(0, 2000), renderStyle=renderstyle) #a1b.isoThreshold = 600 vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title('Average volume of %s phases (%s) (resized data)' % (len(phases), renderstyle)) # Save avg = 'avgreg' filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, avg) ssdf.save(os.path.join(basedir, ptcode, filename), s_avg) print("avgreg saved to disk.") t1 = time.time() print('Registration completed, which took %1.2f min.' % ((t1 - t0) / 60))
## Renal origin coordinates: input by user/read excel # coordinates, left and right most caudal renal # ctcode1 xrenal1, yrenal1, zrenal1 = 132.7, 89.2, 85.5 renal1 = PointSet(list((xrenal1, yrenal1, zrenal1))) # ctcode2 if ctcode2: xrenal2, yrenal2, zrenal2 = 171, 165.1, 39.5 renal2 = PointSet(list((xrenal2, yrenal2, zrenal2))) # renal_left, renal_right = foo.readRenalsExcel(sheet_renals_obs, ptcode, ctcode1) # renal1 = renal_left ## Load (dynamic) stent models, vessel, ct # Load static CT image to add as reference s = loadvol(basedir, ptcode, ctcode1, cropname, 'avgreg') vol1 = s.vol if ctcode2: s = loadvol(basedir, ptcode, ctcode2, cropname, 'avgreg') vol2 = s.vol # load stent model s2 = loadmodel(basedir, ptcode, ctcode1, cropname, modelname) model1 = s2.model modelmesh1 = create_mesh(model1, meshradius) if ctcode2: s2 = loadmodel(basedir, ptcode, ctcode2, cropname, modelname) model2 = s2.model modelmesh2 = create_mesh(model2, meshradius) # Load vessel mesh (output Mimics)
from stentseg.utils import _utils_GUI import copy from stentseg.utils.picker import pick3d from stentseg.apps.record_movie import recordMovie # Select the ssdf basedir basedir = select_dir(r'F:\Nellix_chevas\CT_SSDF\SSDF_automated', r'D:\Nellix_chevas_BACKUP\CT_SSDF\SSDF_automated') # Select dataset to register ptcode = 'chevas_02' ctcode, nr = '12months', 1 cropname = 'prox' ## Show single vol s0 = loadvol(basedir, ptcode, ctcode, cropname, 'phases') # vol = s0.vol vol = s0.vol20 key = 'vol20' zscale = (s0[key].sampling[0] / s0[key].sampling[1]) # z / y # resample vol using spline interpolation, 3rd order polynomial vol_zoom = scipy.ndimage.interpolation.zoom(s0[key], [zscale, 1, 1], 'float32') s0[key].sampling = [ s0[key].sampling[1], s0[key].sampling[1], s0[key].sampling[2] ] # aanpassingen voor scale en origin vol_zoom_type = vv.Aarray(vol_zoom, s0[key].sampling, s0[key].origin) vol = vol_zoom_type fig = vv.figure() vv.clf()
# ptcode = 'QRM_FANTOOM_20160121' # ctcode, nr = 'ZA3-75-1.2', 1 cropname = 'ring' modelname = 'modelavgreg' motion = 'amplitude' # amplitude or sum dimension = 'xyz' showVol = 'ISO' # MIP or ISO or 2D or None clim0 = (-10, 2500) clim2 = (0, 3) isoTh = 250 motionPlay = 9, 1 # each x ms, a step of perc of T staticref = 'avgreg' # 'avg7020' meshWithColors = True # Load deformations (forward for mesh) s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms') # deforms = [s['deform%i'%(i*10)] for i in range(10)] deformkeys = [] for key in dir(s): if key.startswith('deform'): deformkeys.append(key) deforms = [s[key] for key in deformkeys] # deforms = [[field[::2,::2,::2] for field in fields] for fields in deforms] try: s2 = loadvol(basedir, ptcode, ctcode, 'ring', staticref) except FileNotFoundError: s2 = loadvol(basedir, ptcode, ctcode, 'ring', staticref) vol = s2.vol s3 = loadvol(basedir, ptcode, ctcode, cropname, 'phases')
basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup') # Select dataset to register ptcode = 'LSPEAS_025' ctcode = '24months' cropname = 'ring' modelname = 'modelavgreg' # Load the stent model and mesh s = loadmodel(basedir, ptcode, ctcode, cropname, modelname) model = s.model model2 = model.copy() # Load static CT image to add as reference s2 = loadvol(basedir, ptcode, ctcode, cropname, 'avgreg') vol = s2.vol f = vv.figure(1) vv.clf() a = vv.subplot(1, 2, 1) a.axis.axisColor = 1, 1, 1 a.axis.visible = False a.bgcolor = 0, 0, 0 a.daspect = 1, 1, -1 t = vv.volshow(vol, clim=(0, 2500), renderStyle='mip') label = pick3d(a, vol) # model.Draw(mc='b', mw = 10, lc='g') vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)')