def figparts(): """ Visualize ring parts """ fig = vv.figure(4); fig.position = 8.00, 30.00, 944.00, 1002.00 vv.clf() a0 = vv.subplot(121) show_ctvolume(vol, model, showVol=showVol, clim=clim0, isoTh=isoTh) modelR1, modelR2 = modelsR1R2[0][0], modelsR1R2[0][1] modelR1.Draw(mc='g', mw = 10, lc='g') # R1 = green modelR2.Draw(mc='c', mw = 10, lc='c') # R2 = cyan vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') vv.title('Analysis for model LSPEAS %s - %s' % (ptcode[7:], ctcode)) a0.axis.axisColor= 1,1,1 a0.bgcolor= 0,0,0 a0.daspect= 1, 1, -1 # z-axis flipped a0.axis.visible = showAxis a1 = vv.subplot(122) show_ctvolume(vol, model, showVol=showVol, clim=clim0, isoTh=isoTh) models[0][0].Draw(mc='y', mw = 10, lc='y') # struts = yellow models[0][1].Draw(mc='r', mw = 10, lc='r') # hooks = red vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') vv.title('Analysis for model LSPEAS %s - %s' % (ptcode[7:], ctcode)) a1.axis.axisColor= 1,1,1 a1.bgcolor= 0,0,0 a1.daspect= 1, 1, -1 # z-axis flipped a1.axis.visible = showAxis a0.camera = a1.camera
def show_surface_and_vol(vol, pp_isosurface, showVol='MIP', clim=(-200, 1000), isoTh=300, climEditor=True): """ Show the generated isosurface in original volume """ f = vv.figure() ax = vv.gca() ax.daspect = 1, 1, -1 ax.axis.axisColor = 1, 1, 1 ax.bgcolor = 0, 0, 0 # show vol and iso vertices show_ctvolume(vol, showVol=showVol, isoTh=isoTh, clim=clim, climEditor=climEditor) label = pick3d(vv.gca(), vol) vv.plot(pp_isosurface, ms='.', ls='', mc='r', alpha=0.2, mw=4) a = vv.gca() 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('------------------------') vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') return label
def vis3Dfit(fitted, vol, model, ptcode, ctcode, showAxis, **kwargs): """Visualize ellipse fit in 3D with CT volume in current axis input: fitted = _fit3D output = (pp3, plane, pp3_2, e3) """ from stentseg.utils import fitting import numpy as np pp3,plane,pp3_2,e3 = fitted[0],fitted[1],fitted[2],fitted[3] a = vv.gca() # show_ctvolume(vol, model, showVol=showVol, clim=clim0, isoTh=isoTh) show_ctvolume(vol, model, **kwargs) vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') vv.title('Ellipse fit for model %s - %s' % (ptcode[7:], ctcode)) a.axis.axisColor= 1,1,1 a.bgcolor= 0,0,0 a.daspect= 1, 1, -1 # z-axis flipped a.axis.visible = showAxis # For visualization, calculate 4 points on rectangle that lies on the plane x1, x2 = pp3.min(0)[0]-0.3, pp3.max(0)[0]+0.3 y1, y2 = pp3.min(0)[1]-0.3, pp3.max(0)[1]+0.3 p1 = x1, y1, -(x1*plane[0] + y1*plane[1] + plane[3]) / plane[2] p2 = x2, y1, -(x2*plane[0] + y1*plane[1] + plane[3]) / plane[2] p3 = x2, y2, -(x2*plane[0] + y2*plane[1] + plane[3]) / plane[2] p4 = x1, y2, -(x1*plane[0] + y2*plane[1] + plane[3]) / plane[2] vv.plot(pp3, ls='', ms='.', mc='y', mw = 10) vv.plot(fitting.project_from_plane(pp3_2, plane), lc='r', ls='', ms='.', mc='r', mw=9) # vv.plot(fitting.project_from_plane(fitting.sample_circle(c3), plane), lc='r', lw=2) vv.plot(fitting.project_from_plane(fitting.sample_ellipse(e3), plane), lc='b', lw=2) vv.plot(np.array([p1, p2, p3, p4, p1]), lc='g', lw=2) # vv.legend('3D points', 'Projected points', 'Circle fit', 'Ellipse fit', 'Plane fit') vv.legend('3D points', 'Projected points', 'Ellipse fit', 'Plane fit')
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 drawmodelphasescycles(vol1, model1, modelori1, showVol, isoTh=300, removeStent=False, showmodelavgreg=False, showvol=True, phases=range(10), colors='cgmrcgywmb', meshWithColors=False, stripSizeZ=None, ax=None): """ draw model and volume (show optional) at different phases cycle """ if ax is None: ax = vv.gca() ax.daspect = 1, 1, -1 ax.axis.axisColor = 0, 0, 0 ax.bgcolor = 1, 1, 1 vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') # draw t = show_ctvolume(vol1, modelori1, showVol=showVol, removeStent=removeStent, climEditor=True, isoTh=isoTh, clim=clim0, stripSizeZ=stripSizeZ) if showmodelavgreg: # show model and CT mid cycle mw = 5 for model in model1: model.Draw(mc='b', mw=mw, lc='b', alpha=0.5) label = pick3d(ax, vol1) if not showvol: t.visible = False # get models in different phases for model in model1: for phasenr in phases: model_phase = get_graph_in_phase(model, phasenr=phasenr) if meshWithColors: modelmesh1 = create_mesh_with_abs_displacement(model_phase, radius=radius, dim=dimensions) m = vv.mesh(modelmesh1, colormap=vv.CM_JET, clim=clim2) #todo: use colormap Viridis or Magma as JET is not linear (https://bids.github.io/colormap/) else: model_phase.Draw(mc=colors[phasenr], mw=10, lc=colors[phasenr]) # modelmesh1 = create_mesh(model_phase, radius = radius) # m = vv.mesh(modelmesh1); m.faceColor = colors[phasenr] if meshWithColors: vv.colorbar() return ax
dist_for_R1_post = dist_over_centerline(centerline1, R1_post_and_cl_point[0], renal1_and_cl_point[0]) # Main outcome 1: distance 2nd ring valleys to renal # Main outcome 2: migration 2nd ring valleys from discharge to 1, 6, 12 months ## Visualize f = vv.figure(2) vv.clf() f.position = 0.00, 22.00, 1920.00, 1018.00 alpha = 0.5 if ctcode2: a1 = vv.subplot(121) else: a1 = vv.gca() show_ctvolume(vol1, model1, showVol=showVol, clim=clim0, isoTh=isoTh) pick3d(vv.gca(), vol1) model1.Draw(mc='b', mw=10, lc='g') vm = vv.mesh(modelmesh1) vm.faceColor = 'g' # m = vv.mesh(vessel1) # m.faceColor = (1,0,0, alpha) # red # vis vessel, centerline, renal origo, peaks valleys R1 vv.plot(ppvessel1, ms='.', ls='', mc='r', alpha=0.2, mw=7, axes=a1) # vessel vv.plot(PointSet(list(c1_start1)), ms='.', ls='', mc='g', mw=18, axes=a1) # start1 vv.plot([e[0] for e in c1_ends], [e[1] for e in c1_ends], [e[2] for e in c1_ends], ms='.', ls='',
showAxis = True # True or False showVol = 'MIP' # MIP or ISO or 2D or None ringpart = True # True; False nstruts = 8 clim0 = (0,3000) # clim0 = -550,500 clim2 = (0,4) radius = 0.07 dimensions = 'xyz' isoTh = 250 ## Visualize with GUI f = vv.figure(3); vv.clf() f.position = 968.00, 30.00, 944.00, 1002.00 a = vv.gca() show_ctvolume(vol, model, showVol=showVol, clim=clim0, isoTh=isoTh) model.Draw(mc='b', mw = 10, lc='g') vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') vv.title('Analysis for model LSPEAS %s - %s' % (ptcode[7:], ctcode)) a.axis.axisColor= 1,1,1 a.bgcolor= 0,0,0 a.daspect= 1, 1, -1 # z-axis flipped a.axis.visible = showAxis # Initialize labels GUI from visvis import Pointset from stentseg.stentdirect import stentgraph t1 = vv.Label(a, 'Edge ctvalue: ', fontSize=11, color='c') t1.position = 0.1, 5, 0.5, 20 # x (frac w), y, w (frac), h t1.bgcolor = None
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) ) #===============================================================================
## Load all rings of the limb for i in nrs: ring = 'ringR%s' %(i) filename = '%s_%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'model'+what,ring) s["ringR" + str(i)] = ssdf.load(os.path.join(basedir1, filename)) ## Visualize centerlines rings s2 = loadmodel(targetdir2, ptcode, ctcode, cropname, modelname='stentseedsavgreg') pmodel = points_from_nodes_in_graph(s2.model) if FIG1 == True: f = vv.figure(1); vv.clf() f.position = 709.00, 30.00, 1203.00, 1008.00 a1 = vv.subplot(121) show_ctvolume(s.vol, None, showVol=showVol, clim=clim0, isoTh=isoTh, removeStent=False) label = pick3d(vv.gca(), s.vol) a1.axis.visible = showAxis a1.daspect = 1,1,-1 a2 = vv.subplot(122) vv.plot(pmodel, ms='.', ls='', alpha=0.2, mw = 2) # stent seed points for i in nrs: pp = s["ringR" + str(i)].ringpoints vv.plot(pp[0],pp[1],pp[2], ms='.', ls='', mw=3, mc='c') a2.axis.visible = showAxis a2.daspect = 1,1,-1 # a1.camera = a2.camera ## Distances
] # 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() fig.position = 0.00, 22.00, 1920.00, 1018.00 clim = (0, 2500) # Show volume a1 = vv.subplot(111) a1.daspect = 1, 1, -1 t = show_ctvolume(vol, axis=a1, showVol='ISO', clim=clim, isoTh=250, removeStent=False, climEditor=True) label = pick3d(vv.gca(), vol) vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') ## Show 3D movie, by alternating the 10 volumes # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, 'phases') vols = [] for key in dir(s): if key.startswith('vol'):
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))
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
f = vv.figure() vv.clf() f.position = 0.00, 22.00, 1920.00, 1018.00 ax = vv.gca() ax.daspect = 1, 1, -1 ax.axis.axisColor = 0, 0, 0 ax.bgcolor = 1, 1, 1 vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') # draw showVol = 'ISO' t = show_ctvolume(vol, showVol=showVol, removeStent=False, climEditor=True, isoTh=300) if showmodelavgreg: # show model and CT mid cycle mw = 5 modelcll.Draw(mc='b', mw=mw, lc='b', alpha=0.5) label = pick3d(ax, vol) if not showvol: t.visible = False # get centerline models in different phases for phasenr in phases: model_phase = get_graph_in_phase(modelcll, phasenr=phasenr) model_phase.Draw(mc=color[phasenr], mw=10, lc=color[phasenr])
def showModelsStatic(ptcode,codes, vols, ss, mm, vs, showVol, clim, isoTh, clim2, clim2D, drawMesh=True, meshDisplacement=True, drawModelLines=True, showvol2D=False, showAxis=False, drawVessel=False, vesselType=1, meshColor=None, **kwargs): """ show one to four models in multipanel figure. Input: arrays of codes, vols, ssdfs; params from show_models_static Output: axes, colorbars """ # init fig f = vv.figure(1); vv.clf() # f.position = 0.00, 22.00, 1920.00, 1018.00 mw = 5 if drawMesh == True: lc = 'w' meshColor = meshColor else: lc = 'g' # create subplots if isinstance(codes, str): # if 1 ctcode, otherwise tuple of strings a1 = vv.subplot(111) axes = [a1] elif codes == (codes[0],codes[1]): a1 = vv.subplot(121) a2 = vv.subplot(122) axes = [a1,a2] elif codes == (codes[0],codes[1], codes[2]): a1 = vv.subplot(131) a2 = vv.subplot(132) a3 = vv.subplot(133) axes = [a1,a2,a3] elif codes == (codes[0],codes[1], codes[2], codes[3]): a1 = vv.subplot(141) a2 = vv.subplot(142) a3 = vv.subplot(143) a4 = vv.subplot(144) axes = [a1,a2,a3,a4] elif codes == (codes[0],codes[1], codes[2], codes[3], codes[4]): a1 = vv.subplot(151) a2 = vv.subplot(152) a3 = vv.subplot(153) a4 = vv.subplot(154) a5 = vv.subplot(155) axes = [a1,a2,a3,a4,a5] else: a1 = vv.subplot(111) axes = [a1] for i, ax in enumerate(axes): ax.MakeCurrent() vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') vv.title('Model for LSPEAS %s - %s' % (ptcode[7:], codes[i])) t = show_ctvolume(vols[i], ss[i].model, axis=ax, showVol=showVol, clim=clim, isoTh=isoTh, **kwargs) label = pick3d(ax, vols[i]) if drawModelLines == True: ss[i].model.Draw(mc='b', mw = mw, lc=lc) if showvol2D: for i, ax in enumerate(axes): t2 = vv.volshow2(vols[i], clim=clim2D, axes=ax) cbars = [] # colorbars if drawMesh: for i, ax in enumerate(axes): m = vv.mesh(mm[i], axes=ax) if meshDisplacement: m.clim = clim2 m.colormap = vv.CM_JET #todo: use colormap Viridis or Magma as JET is not linear (https://bids.github.io/colormap/) cb = vv.colorbar(ax) cbars.append(cb) elif meshColor is not None: if len(meshColor) == 1: m.faceColor = meshColor[0] # (0,1,0,1) else: m.faceColor = meshColor[i] else: m.faceColor = 'g' if drawVessel: for i, ax in enumerate(axes): v = showVesselMesh(vs[i], ax, type=vesselType) for ax in axes: ax.axis.axisColor = 1,1,1 ax.bgcolor = 25/255,25/255,112/255 # midnightblue # http://cloford.com/resources/colours/500col.htm ax.daspect = 1, 1, -1 # z-axis flipped ax.axis.visible = showAxis # set colorbar position for cbar in cbars: p1 = cbar.position cbar.position = (p1[0], 20, p1[2], 0.98) # x,y,w,h # bind rotate view and view presets [1,2,3,4,5] f = vv.gcf() f.eventKeyDown.Bind(lambda event: _utils_GUI.RotateView(event,axes,axishandling=False) ) f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event,axes) ) return axes, cbars
def identify_peaks_valleys(midpoints_peaks_valleys, model, vol, vis=True): """ Given a cloud of points containing 2 peak and 2 valley points for R1 and R2, identify and return these locations. Uses clustering and x,y,z """ # detect clusters to further label locations kmeans = KMeans(n_clusters=4) kmeans.fit(midpoints_peaks_valleys) centroids = kmeans.cluster_centers_ # x,y,z labels = kmeans.labels_ # identify left, right, ant, post centroid (assumes origin is prox right anterior) left = list(centroids[:, 0]).index(max(centroids[:, 0])) # max x value right = list(centroids[:, 0]).index(min(centroids[:, 0])) anterior = list(centroids[:, 1]).index(min(centroids[:, 1])) # min y value posterior = list(centroids[:, 1]).index(max(centroids[:, 1])) # get points into grouped arrays cLeft, cRight, cAnterior, cPosterior = [], [], [], [] for i, p in enumerate(midpoints_peaks_valleys): if labels[i] == left: cLeft.append(tuple(p.flat)) elif labels[i] == right: cRight.append(tuple(p.flat)) elif labels[i] == anterior: cAnterior.append(tuple(p.flat)) elif labels[i] == posterior: cPosterior.append(tuple(p.flat)) cLeft = np.asarray(cLeft) cRight = np.asarray(cRight) cAnterior = np.asarray(cAnterior) cPosterior = np.asarray(cPosterior) # divide into R1 R2 R1_left = cLeft[list(cLeft[:, 2]).index(min( cLeft[:, 2]))] # min z for R1; valley R2_left = cLeft[list(cLeft[:, 2]).index(max(cLeft[:, 2]))] # valley R1_right = cRight[list(cRight[:, 2]).index(min( cRight[:, 2]))] # min z for R1; valley R2_right = cRight[list(cRight[:, 2]).index(max(cRight[:, 2]))] # valley R1_ant = cAnterior[list(cAnterior[:, 2]).index(min( cAnterior[:, 2]))] # min z for R1; peak R2_ant = cAnterior[list(cAnterior[:, 2]).index(max(cAnterior[:, 2]))] # peak R1_post = cPosterior[list(cPosterior[:, 2]).index(min( cPosterior[:, 2]))] # min z for R1; peak R2_post = cPosterior[list(cPosterior[:, 2]).index(max(cPosterior[:, 2]))] # peak if vis == True: # visualize identified locations f = vv.figure(1) vv.clf() f.position = 968.00, 30.00, 944.00, 1002.00 a = vv.gca() colors = ['r', 'g', 'b', 'm', 'c', 'y', 'w', 'k'] for i, p in enumerate([ R1_left, R2_left, R1_right, R2_right, R1_ant, R2_ant, R1_post, R2_post ]): vv.plot(p[0], p[1], p[2], ms='.', ls='', mc=colors[i], mw=14) vv.legend('R1 left', 'R2 left', 'R1 right', 'R2 right', 'R1 ant', 'R2 ant', 'R1 post', 'R2 post') show_ctvolume(vol, model, showVol='MIP', clim=(0, 2500)) pick3d(vv.gca(), vol) model.Draw(mc='b', mw=10, lc='g') for i in range(len(midpoints_peaks_valleys)): vv.plot(midpoints_peaks_valleys[i], ms='.', ls='', mc=colors[labels[i]], mw=6) a.axis.axisColor = 1, 1, 1 a.bgcolor = 0, 0, 0 a.daspect = 1, 1, -1 # z-axis flipped a.axis.visible = True return R1_left, R2_left, R1_right, R2_right, R1_ant, R2_ant, R1_post, R2_post