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 plot(image): # ax = vv.gca() # ms = vv.Mesh(ax) logging.warning([image.shape, image.spacing]) vol = image[:, :, :, 0] logging.warning([vol.min(), vol.max()]) vol = util.normalize(vol, 'ADCm') logging.warning([vol.min(), vol.max()]) vol = vv.Aarray(vol, image.spacing) cmap = None # cmap = vv.CM_VIRIDIS render_style = 'mip' # render_style = 'iso' # render_style = 'ray' # render_style = 'edgeray' # render_style = 'litray' vv.figure() vv.xlabel('x axis') vv.ylabel('y axis') vv.zlabel('z axis') a1 = vv.subplot(111) t1 = vv.volshow(vol, cm=cmap, renderStyle=render_style) t1.isoThreshold = 0.7 vv.title(render_style) # a1.camera = a2.camera = a3.camera vv.ColormapEditor(a1)
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 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 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
def visVol(volData): """ This example demonstrates rendering a color volume. We demonstrate two renderers capable of rendering color data: the colormip and coloriso renderer. """ import visvis as vv app = vv.use() # Load volume vol = volData # set labels vv.xlabel("x axis") vv.ylabel("y axis") vv.zlabel("z axis") # # Create figure and make subplots with different renderers # vv.figure(1); vv.clf() # RS = ['mip', 'iso', 'edgeray', 'ray', 'litray'] # a0 = None # tt = [] # for i in range(5): # a = vv.subplot(3,2,i+2) # t = vv.volshow(vol) # vv.title('Renderstyle ' + RS[i]) # t.colormap = vv.CM_HOT # t.renderStyle = RS[i] # t.isoThreshold = 200 # Only used in iso render style # tt.append(t) # if a0 is None: # a0 = a # else: # a.camera = a0.camera t = vv.volshow(vol, renderStyle="edgeray") t.colormap = vv.CM_HOT # Get axes and set camera to orthographic mode (with a field of view of 70) a = vv.gca() a.camera.fov = 45 # Create colormap editor wibject. vv.ColormapEditor(a) # Create colormap editor in first axes # cme = vv.ColormapEditor(vv.gcf(), t) # Run app # app.Create() app.Run()
def DrawModelAxes(vol, graph=None, ax=None, axVis=False, meshColor=None, getLabel=False, mc='b', lc='g', mw=7, lw=0.6, **kwargs): """ Draw model with volume with axes set ax = axes to draw (a1 or a2 or a3); graph = sd._nodes1 or 2 or 3 meshColor = None or faceColor e.g. 'g' """ #todo: prevent TypeError: draw() got an unexpected keyword argument mc/lc when not given as required variable #todo: *args voor vol in drawModelAxes of **kwargs[key] in functies hieronder if ax is None: ax = vv.gca() ax.MakeCurrent() ax.daspect = 1, 1, -1 ax.axis.axisColor = 1, 1, 1 ax.bgcolor = 0, 0, 0 ax.axis.visible = axVis vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') if graph is None: show_ctvolume(vol, graph, axis=ax, removeStent=False, **kwargs) label = pick3d(vv.gca(), vol) return label if hasattr(graph, 'number_of_edges'): if graph.number_of_edges( ) == 0: # get label from picked seeds sd._nodes1 show_ctvolume(vol, graph, axis=ax, **kwargs) label = pick3d(vv.gca(), vol) graph.Draw(mc=mc, lc=lc) return label if not meshColor is None: bm = create_mesh(graph, 0.5) # (argument is strut tickness) m = vv.mesh(bm) m.faceColor = meshColor # 'g' show_ctvolume(vol, graph, axis=ax, **kwargs) graph.Draw(mc=mc, lc=lc) if getLabel == True: label = pick3d(vv.gca(), vol) return label else: pick3d(vv.gca(), vol) return
def show_vox(self, vfunc): """ Displays a 3-D rendering of a voxelized property. :param vfunc: function accepting this MasonView instance and returning a 3-D np.array of some voxelized property """ app = vv.use() vv.figure(1) vv.xlabel('Eastings (units)') vv.ylabel('Northings (units)') vv.zlabel('Depth (units)') a = vv.gca() a.camera.fov = 70 a.daspect = 1, 1, -1 vox = vfunc(self) t = vv.volshow(vox, cm=vv.CM_JET, renderStyle='ray') vv.ColormapEditor(a) app.Run()
def psf_volume(stack, xyz_ratio, filepath): app = vv.use() # Init a figure with two axes a1 = vv.subplot(121) vv.title('PSF Volume') a2 = vv.subplot(122) vv.title('PSF XYZ Cross Sections') # show t1 = vv.volshow(stack, axes=a1) # volume t2 = vv.volshow2(stack, axes=a2) # cross-section interactive # set labels for both axes vv.xlabel('Pixel X', axes=a1) vv.ylabel('Pixel Y', axes=a1) vv.zlabel('Z-Slice', axes=a1) vv.xlabel('Pixel X', axes=a2) vv.ylabel('Pixel Y', axes=a2) vv.zlabel('Z-Slice', axes=a2) # set colormaps t1.colormap = vv.CM_JET t2.colormap = vv.CM_JET # set correct aspect ration corresponding to voxel size a1.daspect = 1, 1, xyz_ratio a2.daspect = 1, 1, xyz_ratio # show grid a1.axis.showGrid = 1 a2.axis.showGrid = 1 # run visvis and show results app.Run() # save screenshot if filepath != 'nosave': print 'Saving PSF volume.' savename = filepath[:-4] + '_PSF_3D.png' # sf: scale factor vv.screenshot(savename, sf=1, bg='w')
def show_layer_boundaries(self, sample): """ Displays a 3-D rendering of boundary surfaces. :param sample: index of sample for which to plot boundaries """ app = vv.use() vv.figure(1) X = np.linspace(self.xbounds[0], self.xbounds[1], self.xres) Y = np.linspace(self.ybounds[0], self.xbounds[1], self.yres) Z = np.linspace(self.zbounds[0], self.xbounds[1], self.zres) vv.xlabel('Eastings (m)') vv.ylabel('Northings (m)') vv.zlabel('Depth (m)') a = vv.gca() a.camera.fov = 70 a.daspect = 1, 1, -1 for i in range(len(self.layers)): C = plt.cm.jet(i / float(len(self.layers))) C = np.array([[[C[0], C[1], C[2]]]]) m = vv.surf(X, Y, self.fbounds[i][sample], C) vv.ColormapEditor(a) app.Run()
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))
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
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 t1.visible = False t2 = vv.Label(a, 'Edge cost: ', fontSize=11, color='c')
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) ) #===============================================================================
# Show volume and nodes/edges a2 = vv.subplot(142) t = vv.volshow(vol) t.clim = 0, 3000 sd._nodes1.Draw(mc='b') # draw seeded nodes # Show volume and nodes/edges a3 = vv.subplot(143) t = vv.volshow(vol) t.clim = 0, 3000 sd._nodes2.Draw(mc='b', lc='g') #new_nodes1.Draw(mc='b', mw = 6) vv.xlabel('x') vv.ylabel('y') vv.zlabel('z') # Show volume and cleaned up a4 = vv.subplot(144) a4.daspect = 1, 1, -1 t = vv.volshow(vol) #t.renderStyle = 'ray' t.clim = 0, 3000 #t = vv.volshow2(vol) # to see some vessel anatomy #t.clim = -250, 250 # or -750, 500 #vv.ColormapEditor(vv.gcf()) m = vv.mesh(bm) m.faceColor = 'g' vv.xlabel('x') vv.ylabel('y')
'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(121) t1 = vv.volshow(vol1, clim=(0, 3000), renderStyle='iso') # iso or mip t1.isoThreshold = 400 t1.colormap = colormap a1b = vv.volshow2(vol1, clim=(-550, 500)) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') # vv.title('One volume at %i procent of cardiac cycle' % phase ) vv.title('Vol40') a2 = vv.subplot(122) a2.daspect = 1, 1, -1 t2 = vv.volshow(vol2, clim=(0, 3000), renderStyle='iso') # iso or mip t2.isoThreshold = 400 t2.colormap = colormap a2b = vv.volshow2(vol2, clim=(-550, 500)) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') # vv.title('One volume at %i procent of cardiac cycle' % phase ) vv.title('Vol78') a1.camera = a2.camera
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')
def dicom2ssdf(dicom_basedir, ptcode, ctcode, basedir, cropnames=['stent'], savedistolicavg=False, visvol=True, visdynamic=False): """ read dicom volumes and store as ssdf format """ #Step A vols2 = [vol2 for vol2 in imageio.get_reader(dicom_basedir, 'DICOM', 'V')] try: for i, vol in enumerate(vols2): print(vol.meta.ImagePositionPatient) for i, vol in enumerate(vols2): print(vol.shape) for i, vol in enumerate(vols2): print(vol.meta.AcquisitionTime) print(vol.meta.sampling) assert vol.shape == vols2[0].shape assert vol.meta.SeriesTime == vols2[0].meta.SeriesTime except AttributeError: print('Some meta information is not available') pass # check order of phases vols = vols2.copy() try: for i, vol in enumerate(vols): print(vol.meta.SeriesDescription) assert str(i * 10) in vol.meta.SeriesDescription # 0% , 10% etc. except AttributeError: # meta info is missing print('vol.meta.SeriesDescription meta information is not available') pass except AssertionError: # not correct order, fix vols = [None] * len(vols2) for i, vol in enumerate(vols2): print(vol.meta.SeriesDescription) phase = int(vol.meta.SeriesDescription[:1]) # use phase to fix order of phases vols[phase] = vol # Step B: Crop and Save SSDF # Load and show first volume: crop with a margin of at least ~25 mm print() print('Crop with margins ~25 mm around ROI for the registration algorithm') stenttype = None # deprecate, not needed for cropname in cropnames: savecropvols(vols, basedir, ptcode, ctcode, cropname, stenttype) # Step C: average diastolic phases if savedistolicavg: phases = 50, 10 # use 7 phases from 50% to 10% saveaveraged(basedir, ptcode, ctcode, cropname, phases) # Visualize 1 phase import visvis as vv if visvol: vol1 = vols[1] 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)] } fig = vv.figure(2) vv.clf() fig.position = 0, 22, 1366, 706 a1 = vv.subplot(111) a1.daspect = 1, 1, -1 renderStyle = 'mip' t1 = vv.volshow(vol1, clim=(0, 3000), renderStyle=renderStyle) # iso or mip if renderStyle == 'iso': t1.isoThreshold = 300 t1.colormap = colormap a1 = vv.volshow2(vol1, clim=(-500, 500), renderStyle=renderStyle) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title('One volume at 10\% procent of cardiac cycle') if visdynamic: from lspeas.utils.vis import showVolPhases showVol = 'mip' t = showVolPhases(basedir, vols2, showVol=showVol, mipIsocolor=True, isoTh=310, clim=(60, 3000), slider=True) return vols
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,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)
# calculate B field at given points B = sol.CalculateB(points=points) Babs = np.linalg.norm(B, axis=1) # draw results # prepare axes a = vv.gca() a.cameraType = '3d' a.daspectAuto = False vol = Babs.reshape(grid.shape[1:]).T vol = np.clip(vol, 0.002, 0.01) vol = vv.Aarray(vol, sampling=(resolution, resolution, resolution), origin=(volume_corner1[2], volume_corner1[1], volume_corner1[0])) # set labels vv.xlabel('x axis') vv.ylabel('y axis') vv.zlabel('z axis') sol.vv_PlotWires() t = vv.volshow2(vol, renderStyle='mip', cm=vv.CM_JET) vv.colorbar() app = vv.use() app.Run()
def zlabel(text, axes=None): """ zlabel(text, axes=None) Set the zlabel of an axes. Note that you can also use "axes.axis.zLabel = text". Parameters ---------- text : string The text to display. axes : Axes instance Display the image in this axes, or the current axes if not given. """ if axes is None: axes = vv.gca() axes.axis.zLabel = text if __name__ == '__main__': # Create a 3D plot a = vv.gca() vv.plot([1, 2, 3], [1, 3, 2], [3, 1, 2]) a.cameraType = '3d' # Set labels for all 3 dimensions vv.xlabel('label x') vv.ylabel('label y') vv.zlabel('label z')
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)
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))
ms='.', ls='', mc='b', mw=18, axes=a1) # ends vv.plot(centerline1, ms='.', ls='', mw=8, mc='y', axes=a1) vv.plot(renal1, ms='.', ls='', mc='m', mw=18, axes=a1) vv.plot(renal1_and_cl_point, ms='.', ls='-', mc='m', mw=18, axes=a1) # vv.plot(R1_left_and_cl_point, ms='.', ls='-', mc='c', mw=18, axes = a1) # vv.plot(R1_right_and_cl_point, ms='.', ls='-', mc='c', mw=18, axes = a1) # vv.plot(R1_ant_and_cl_point, ms='.', ls='-', mc='c', mw=18, axes = a1) # vv.plot(R1_post_and_cl_point, ms='.', ls='-', mc='c', mw=18, axes = a1) vv.xlabel('x (mm)') vv.ylabel('y (mm)') vv.zlabel('z (mm)') vv.title('Analysis for model LSPEAS %s - %s' % (ptcode[7:], ctcode1)) a1.axis.axisColor = 1, 1, 1 a1.bgcolor = 0, 0, 0 a1.daspect = 1, 1, -1 # z-axis flipped a1.axis.visible = showAxis if ctcode2: a2 = vv.subplot(122) show_ctvolume(vol2, model2, showVol=showVol, clim=clim0, isoTh=isoTh) pick3d(vv.gca(), vol2) model2.Draw(mc='b', mw=10, lc='g') vm = vv.mesh(modelmesh2) vm.faceColor = 'g' # m = vv.mesh(vessel2) # m.faceColor = (1,0,0, alpha) # red
def demo(*args, **kwargs): import math m = 80 # width of grid n = m ** 2 # number of points minVal = -2.0 maxVal = 2.0 delta = (maxVal - minVal) / (m - 1) X, Y = numpy.mgrid[minVal:maxVal + delta:delta, minVal:maxVal + delta:delta] X = X.flatten() Y = Y.flatten() Z = numpy.sin(X) * numpy.cos(Y) # Create the data point-matrix M = numpy.array([X, Y, Z]).T # Translation values (a.u.): Tx = 0.5 Ty = -0.3 Tz = 0.2 # Translation vector T = numpyTransform.translation(Tx, Ty, Tz) S = numpyTransform.scaling(1.0, N=4) # Rotation values (rad.): rx = 0.3 ry = -0.2 rz = 0.05 Rx = numpy.matrix([[1, 0, 0, 0], [0, math.cos(rx), -math.sin(rx), 0], [0, math.sin(rx), math.cos(rx), 0], [0, 0, 0, 1]]) Ry = numpy.matrix([[math.cos(ry), 0, math.sin(ry), 0], [0, 1, 0, 0], [-math.sin(ry), 0, math.cos(ry), 0], [0, 0, 0, 1]]) Rz = numpy.matrix([[math.cos(rz), -math.sin(rz), 0, 0], [math.sin(rz), math.cos(rz), 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]) # Rotation matrix R = Rx * Ry * Rz transformMat = numpy.matrix(numpy.identity(4)) transformMat *= T transformMat *= R transformMat *= S # Transform data-matrix plus noise into model-matrix D = numpyTransform.transformPoints(transformMat, M) # Add noise to model and data M = M + 0.01 * numpy.random.randn(n, 3) D = D + 0.01 * numpy.random.randn(n, 3) # Run ICP (standard settings) initialGuess = numpy.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) lowerBounds = numpy.array([-pi, -pi, -pi, -100.0, -100.0, -100.0]) upperBounds = numpy.array([pi, pi, pi, 100.0, 100.0, 100.0]) icp = ICP(M, D, maxIterations=15, dataDownsampleFactor=1, minimizeMethod='fmincon', **kwargs) # icp = ICP(M, D, maxIterations=15, dataDownsampleFactor=1, minimizeMethod='point', **kwargs) transform, err, t = icp.runICP(x0=initialGuess, lb=lowerBounds, ub=upperBounds) # Transform data-matrix using ICP result Dicp = numpyTransform.transformPoints(transform[-1], D) # Plot model points blue and transformed points red if False: import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = fig.add_subplot(2, 2, 1, projection='3d') ax.scatter(M[:, 0], M[:, 1], M[:, 2], c='r', marker='o') ax.scatter(D[:, 0], D[:, 1], D[:, 2], c='b', marker='^') ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') ax = fig.add_subplot(2, 2, 2, projection='3d') ax.scatter(M[:, 0], M[:, 1], M[:, 2], c='r', marker='o') ax.scatter(Dicp[:, 0], Dicp[:, 1], Dicp[:, 2], c='b', marker='^') ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') ax = fig.add_subplot(2, 2, 3) ax.plot(t, err, 'x--') ax.set_xlabel('X Label') ax.set_ylabel('Y Label') plt.show() else: import visvis as vv app = vv.use() vv.figure() vv.subplot(2, 2, 1) vv.plot(M[:, 0], M[:, 1], M[:, 2], lc='b', ls='', ms='o') vv.plot(D[:, 0], D[:, 1], D[:, 2], lc='r', ls='', ms='x') vv.xlabel('[0,0,1] axis') vv.ylabel('[0,1,0] axis') vv.zlabel('[1,0,0] axis') vv.title('Red: z=sin(x)*cos(y), blue: transformed point cloud') # Plot the results vv.subplot(2, 2, 2) vv.plot(M[:, 0], M[:, 1], M[:, 2], lc='b', ls='', ms='o') vv.plot(Dicp[:, 0], Dicp[:, 1], Dicp[:, 2], lc='r', ls='', ms='x') vv.xlabel('[0,0,1] axis') vv.ylabel('[0,1,0] axis') vv.zlabel('[1,0,0] axis') vv.title('ICP result') # Plot RMS curve vv.subplot(2, 2, 3) vv.plot(t, err, ls='--', ms='x') vv.xlabel('time [s]') vv.ylabel('d_{RMS}') vv.title('KD-Tree matching') if 'optAlg' in kwargs: opt2 = nlopt.opt(kwargs['optAlg'], 2) vv.title(opt2.get_algorithm_name()) del opt2 else: vv.title('KD-Tree matching') app.Run()
import visvis as vv import numpy as np import cPickle as pickle import gzip f=gzip.open(sys.argv[1],"rb") data=pickle.load(f) #!/usr/bin/env python app = vv.use() vv.clf() # set labels vv.xlabel('x axis') vv.ylabel('y axis') vv.zlabel('z axis') # show print np.sum(data) t = vv.volshow(data,renderStyle='iso',axesAdjust=True) #t.isoThreshold = 0.5 # try the differtent render styles, for examample # "t.renderStyle='iso'" or "t.renderStyle='ray'" # If the drawing hangs, your video drived decided to render in software mode. # This is unfortunately (as far as I know) not possible to detect. # It might help if your data is shaped a power of 2. # Get axes and set camera to orthographic mode (with a field of view of 70) a = vv.gcf() f = vv.gca()#fqwang
import visvis as vv def zlabel(text, axes=None): """ zlabel(text, axes=None) Set the zlabel of an axes. Note that you can also use "axes.axis.zLabel = text". Parameters ---------- text : string The text to display. axes : Axes instance Display the image in this axes, or the current axes if not given. """ if axes is None: axes = vv.gca() axes.axis.zLabel = text if __name__=='__main__': # Create a 3D plot a = vv.gca() vv.plot([1,2,3],[1,3,2],[3,1,2]) a.cameraType = '3d' # Set labels for all 3 dimensions vv.xlabel('label x') vv.ylabel('label y') vv.zlabel('label z')