def show_ctvolume(vol, graph=None, axis=None, showVol='MIP', clim=(0, 2500), isoTh=250, removeStent=True, climEditor=False, stripSize=6, stripSizeZ=None): """ Different ways to visualize the CT volume as reference For '2D' clim (-550,500) often good range """ import visvis as vv colormap = { 'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)] } if axis is None: axis = vv.gca() axis.MakeCurrent() if showVol == 'MIP': t = vv.volshow(vol, clim=clim, renderStyle='mip') elif showVol == 'ISO': if removeStent == True: vol = remove_stent_from_volume( vol, graph, stripSize=stripSize, stripSizeZ=stripSizeZ) # rings are removed for vis. t = vv.volshow(vol, clim=clim, renderStyle='iso') t.isoThreshold = isoTh t.colormap = colormap elif showVol == '2D': t = vv.volshow2(vol) t.clim = clim # bind ClimEditor to figure if climEditor: if showVol == 'ISO': c = _utils_GUI.IsoThEditor(axis) else: c = vv.ClimEditor(axis) c.position = (10, 50) # bind for show hide fig = vv.gcf() fig.eventKeyDown.Bind( lambda event: _utils_GUI.ShowHideSlider(event, c)) print('****') print('Use "s" to show/hide slider') print('****') return t
def visualize(im, vol, sz=0.25, thr=0.99): im, vol = im.numpy(), vol.numpy() print("Image shape:", im.shape) print("Volume shape:", vol.shape) # overlap with 3d representation + BGR->RGB im = im.transpose(1, 2, 0) # H,W,C im = im[:, :, ::-1] im = cv2.resize(im, (128, 128)) t = vv.imshow(im) t.interpolate = True # interpolate pixels # volshow will use volshow3 and rendering the isosurface if OpenGL version is >= 2.0 # Otherwise, it will show slices with bars that you can move (much less useful). im = (im * 128 + 128).astype(np.uint8) # im = np.ones_like(im) volRGB = np.stack(((vol >= thr) * im[:, :, 0], (vol >= thr) * im[:, :, 1], (vol >= thr) * im[:, :, 2]), axis=3) v = vv.volshow(volRGB, renderStyle='iso') v.transformations[1].sz = sz # Z rescaling l0 = vv.gca() l0.light0.ambient = 0.9 # 0.2 is default for light 0 l0.light0.diffuse = 1.0 # 1.0 is default a = vv.gca() a.axis.visible = 0 a.camera.fov = 0 # orthographic vv.use().Run()
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 Draw(self, nodesNr=0, drawTex=True, fignr=101, **kwargs): # Init visualization if fignr is not None: f = vv.figure(fignr) vv.clf() a = vv.gca() else: a = vv.gca() a.cameraType = '3d' a.daspect = 1, 1, -1 a.daspectAuto = False # f.position = -769.00, 342.00, 571.00, 798.00 #f.position = 269.00, 342.00, 571.00, 798.00 # Draw texture? if drawTex: self._tex1 = vv.volshow(self._vol) # Draw nodes? nodes = { 0: None, 1: self._nodes1, 2: self._nodes2, 3: self._nodes3 }[nodesNr] if nodes is not None: nodes.draw(**kwargs) a.SetLimits()
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 plot_progress(plots, sampler_info): settings = requests.get(sampler_info['settings']).json() lower = settings['lower'] upper = settings['upper'] subplt = vv.subplot(*(plots['shape'] + (1 + plots['count'], ))) plots['count'] += 1 # Request the training data training_data = requests.get(sampler_info['training_data_uri']).json() xres = 30 yres = 30 xeva, yeva = np.meshgrid(np.linspace(lower[0], upper[0], xres), np.linspace(lower[1], upper[1], yres)) Xquery = np.array([xeva.flatten(), yeva.flatten()]).T #Request the predictions from the server r = requests.get(sampler_info['pred_uri'], json=Xquery.tolist()) r.raise_for_status() pred = r.json() pred_mean = np.array(pred['predictive_mean']) id_matrix = np.reshape( np.arange(Xquery.shape[0])[:, np.newaxis], xeva.shape) n, n_outputs = pred_mean.shape # Plot the training data and the predictions vol = np.zeros((n_outputs, xeva.shape[0], xeva.shape[1])) for x in range(xres): for y in range(yres): vol[:, x, y] = pred_mean[id_matrix[x, y]] plt = vv.volshow(vol, renderStyle='mip', clim=(-0.5, 1)) plt.colormap = vv.CM_JET subplt.axis.xLabel = 'input 1' subplt.axis.yLabel = 'input 2' subplt.axis.zLabel = 'model output' a = ((np.asarray(training_data['X']) - np.array([np.min(xeva), np.min(yeva)])[np.newaxis, :]) / np.array([np.max(xeva) - np.min(xeva), np.max(yeva)-np.min(yeva)])[np.newaxis, :]) \ * np.array(xeva.shape) # NOQA n = a.shape[0] a = np.hstack((a, (n_outputs + 0.01) * np.ones((n, 1)))) pp = vv.Pointset(a) vv.plot(pp, ms='.', mc='w', mw='9', ls='')
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')
vol2 = s1.vol90 # Visualize and compare colormap = { 'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)] } import visvis as vv fig = vv.figure(1) vv.clf() fig.position = 0, 22, 1366, 706 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 )
import visvis as vv import numpy as np app = vv.use() vv.clf() # create volume vol = vv.aVolume(size=64) # set labels vv.xlabel('x axis') vv.ylabel('y axis') vv.zlabel('z axis') # show t = vv.volshow(vol, renderStyle='mip') # 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.gca() a.camera.fov = 45 # Create colormap editor wibject. vv.ColormapEditor(a) # Start app 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 plot_3d_diameter_map(name, data, unit_scale=1.0, measure_quantity='vox', radius_structure_elem=1, output_dir=None, width=512, height=512, camera_azth=44.5, camera_elev=35.8, camera_roll=0.0, camera_fov=35.0, camera_zoom=0.0035, camera_loc=(67.0, 81.6, 45.2), xlabel='', ylabel='', zlabel='', axis_color='w', background_color='k', cb_x_offset=10): """Renders orientation data in 3D with RGB angular color-coding. Parameters ---------- name : str Indicates the name of the output png file. data : 3D array Indicates the 3D array containing diameter at every point of the skeleton. unit_scale : float Indicates the scale factor of the data values. measure_quantity : str Indicates the name of measure of the values. radius_structure_elem : integer Indicates the size of the structure element of the dilation process to thicken the skeleton. output_dir : str Indicates the path to the output folder where the image will be stored. camera_azth : float Indicates the azimuth angle of the camera. width : int Indicates the width of the visualization window. height : int Indicates the width of the visualization window. camera_elev : float Indicates the latitude / elevation angle of the camera. camera_roll : float Indicates the roll angle of the camera. camera_fov : float Indicates the field of view of the camera. camera_zoom : float Indicates the zoom level of the camera. camera_loc : tuple Indicates the camera location. xlabel : str Indicates the label along the x-axis. ylabel : str Indicates the label along the y-axis. zlabel : str Indicates the label along the z-axis. axis_color : str Indicates the color of axes. background_color : str Indicates the background color of the figure. cb_x_offset : int Indicates the offset of the colorbar from the right window side. """ if not visvis_available: print( 'The visvis package is not found. The visualization cannot be done.' ) return rmin, rmax, cmin, cmax, zmin, zmax = _bbox_3D(data) dmtr = data[rmin:rmax, cmin:cmax, zmin:zmax] * unit_scale skel = np.zeros_like(dmtr, dtype=np.uint8) skel[dmtr.nonzero()] = 1 dmtr = ndi.grey_dilation(dmtr, structure=morphology.ball(radius_structure_elem)) skel = ndi.binary_dilation( skel, structure=morphology.ball(radius_structure_elem)).astype(np.float32) skel[skel.nonzero()] = 1. dmtr = dmtr * skel app = vv.use() fig = vv.figure() fig._currentAxes = None fig.relativeFontSize = 2. fig.position.w = width fig.position.h = height t = vv.volshow(dmtr[:, :, :], renderStyle='iso') t.isoThreshold = 0.5 t.colormap = vv.CM_JET a = vv.gca() a.camera.azimuth = camera_azth a.camera.elevation = camera_elev a.camera.roll = camera_roll a.camera.fov = camera_fov a.camera.zoom = camera_zoom a.camera.loc = camera_loc a.bgcolor = background_color a.axis.axisColor = axis_color a.axis.xLabel = xlabel a.axis.yLabel = ylabel a.axis.zLabel = zlabel cb = vv.colorbar() cb.SetLabel(f'Diameter, [{measure_quantity}]') cb._label.position.x += cb_x_offset if output_dir is not None: if not os.path.exists(output_dir): os.makedirs(output_dir) vv.screenshot(os.path.join(output_dir, f'{name}_3d_diameter.png'), sf=1, bg='w') app.Run()
# sd._nodes2.Unpack(ssdf.load('/home/almar/tmp.ssdf')) sd.Step3() # Create a mesh object for visualization (argument is strut tickness) if hasattr(sd._nodes3, 'CreateMesh'): bm = sd._nodes3.CreateMesh(0.6) # old else: bm = create_mesh(sd._nodes3, 0.6) # new # Create figue vv.figure(2); vv.clf() # Show volume and segmented stent as a graph a1 = vv.subplot(131) t = vv.volshow(vol) t.clim = 0, 3000 #sd._nodes1.Draw(mc='g', mw = 6) # draw seeded nodes #sd._nodes2.Draw(mc='g') # draw seeded and MCP connected nodes # Show cleaned up a2 = vv.subplot(132) sd._nodes3.Draw(mc='g', lc='b') # Show the mesh a3 = vv.subplot(133) a3.daspect = 1,-1,1 m = vv.mesh(bm) m.faceColor = 'g' # Use same camera
def showVolPhases(basedir, vols=None, ptcode=None, ctcode=None, cropname=None, showVol='iso', mipIsocolor=False, isoTh=310, slider=False, clim=(0,3000), clim2D=(-550, 500), fname=None): """ Show vol phases in motion container showVol= mip or iso or 2D; Provide either vols or location """ if vols is None: # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, 'phases', fname=fname) vols = [] for key in dir(s): if key.startswith('vol'): vols.append(s[key]) # Start vis f = vv.figure(1); vv.clf() f.position = 9.00, 38.00, 992.00, 944.00 a = vv.gca() a.daspect = 1, 1, -1 a.axis.axisColor = 1,1,1 a.axis.visible = False a.bgcolor = 0,0,0 if showVol=='mip': if not ptcode is None and not ctcode is None: vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode)) else: vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes ') else: if not ptcode is None and not ctcode is None: vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode)) else: vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes ') # Setup data container container = vv.MotionDataContainer(a) for vol in vols: if showVol == '2D': t = vv.volshow2(vol, clim=clim2D) # -750, 1000 t.parent = container else: t = vv.volshow(vol, clim=clim, renderStyle = showVol) t.parent = container if showVol == 'iso': t.isoThreshold = isoTh # iso or mip work well t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} if mipIsocolor: t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} # bind ClimEditor to figure if slider: if showVol=='mip': c = vv.ClimEditor(vv.gcf()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) ) if showVol=='iso': c = IsoThEditor(vv.gcf()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) ) f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, [a]) ) print('------------------------') print('Use keys 1, 2, 3, 4 and 5 for preset anatomic views') print('Use v for a default zoomed view') print('Use x to show and hide axis') print('------------------------') return t
def __init__(self,ptcode,ctcode,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)
def demo(restore_path): """ Trains a convolutional neural network to locate multiple spheres in a simulated artificial lateral line experiment. Currently, this implementation is a port from the original Theano implementation, which is why it still misses some functionality that is mentioned in the current version of the paper. :param config: Experiment config generated from command line input. """ # Create TensorFlow session sess = tf.Session() # Read the data from storage test_x, test_y, _, _ = read_data(config) print("Finished reading data") # Set up two data batchers that provide a straightforward interface for moving through data batches excitation0, excitation1, out = create_model(config, test_x, test_y, mode='test') # Initialize the graph variables sess.run(tf.global_variables_initializer()) # Create a saver saver = tf.train.Saver() saver.restore(sess, restore_path) out_numeric = sess.run(out, feed_dict={ excitation0: test_x[0:1, 0, :, :], excitation1: test_x[0:1, 1, :, :] }) # fig, ax = plt.subplots(2, 2) # # plt.ion() # plt.show() DataConfig.load() ex_cfg = DataConfig ex_cfg.resolution = 128 ex_cfg.n_sensors = 128 s, target_mesh, x_mesh2d, x_mesh3d, y_mesh3d, z_mesh3d = get_meshes() x_slice = x_mesh3d[:, :, 0] column_indices, row_indices0, row_indices0_mod, row_indices1, row_indices1_mod = get_index_arrays( ex_cfg, x_slice, y_mesh3d, z_mesh3d) ax_objs = None counter = 0 n_angles = 360 print("Running animation") for i in range(test_x.shape[0]): out_numeric = sess.run(out, feed_dict={ excitation0: test_x[i:i + 1, 0, :, :], excitation1: test_x[i:i + 1, 1, :, :] }) out_numeric = np.transpose(out_numeric[0]) halfway = out_numeric.shape[0] // 2 multis = get_3d_density(column_indices, ex_cfg.resolution, row_indices0, row_indices0_mod, row_indices1, row_indices1_mod, out_numeric[:halfway, :], out_numeric[halfway:, :]) target = get_3d_density(column_indices, ex_cfg.resolution, row_indices0, row_indices0_mod, row_indices1, row_indices1_mod, test_y[i, 0].T, test_y[i, 1].T) target3d = np.asarray(target) density3d = np.asarray(multis) # def display(): # contour3d(x_mesh3d, y_mesh3d, z_mesh3d, density3d, contours=[0.8], transparent=True) # display() a1.Clear() a2.Clear() vv.volshow(density3d, cm=vv.CM_JET, axes=a1) vv.volshow(target3d, cm=vv.CM_JET, axes=a2) if density3d.max() > args.level: mesh = vv.isosurface(density3d, args.level) m = vv.mesh(mesh, axes=a1) m.faceColor = (1, 1, 1) if target3d.max() > args.level: mesh = vv.isosurface(target3d, args.level) m = vv.mesh(mesh, axes=a2) m.faceColor = (1, 1, 1) a1.daspect = (3, 3, 2) a1.axis.xLabel = 'x' a1.axis.yLabel = 'y' a1.axis.zLabel = 'z' vv.title('Prediction reconstruction', axes=a1) a2.daspect = (3, 3, 2) a2.axis.xLabel = 'x' a2.axis.yLabel = 'y' a2.axis.zLabel = 'z' vv.title('Target reconstruction', axes=a2) for i in range(5): a1.camera.azimuth = counter % 360 counter += 3 a1.Draw() a2.Draw() f.DrawNow() if i < 4: time.sleep(0.2)
""" This example demonstrates rendering a color volume. This example demonstrates two render styles. Note that all render styles are capable of rendering color data. """ import numpy as np import visvis as vv app = vv.use() # Use vv.aVolume to create random bars for each color plane N = 64 vol = np.empty((N,N,N,3), dtype='float32') for i in range(3): vol[:,:,:,i] = vv.aVolume(10,N) # Show vv.figure() a1 = vv.subplot(121); t1 = vv.volshow(vol[:,:,:,:], renderStyle = 'mip') vv.title('color MIP render') a2 = vv.subplot(122); t2 = vv.volshow(vol[:,:,:,:], renderStyle = 'iso') t2.isoThreshold = 0.5 vv.title('color ISO-surface render') # Share cameras a1.camera = a2.camera # Run app app.Run()
def save_3D_gradient_images(save_path, data, name): """ Makes an avi of the volume rendered gradient specified by the name parameter using visvis """ #load all of the volumes into memory vols = [] #setup the visvis setup to capture all of the images f = vv.clf() a = vv.gca() m = vv.MotionDataContainer(a, interval = 500) #loop over all the times times = data.get_times() mn = 1000000000000 mx = -1 #get the min and max range over which to scale the image set for i in range(0, len(times)): #load the volume vol = data.get_gradient_at_time(times[i], name).C #get the min and max of these to save mx = max(np.max(vol), mx) mn = min(np.min(vol), mn) #delete the loaded volume for memory issues del vol #now take screen shots of these images for i in range(0, len(times)): #load the volume vol = data.get_gradient_at_time(times[i], name).C print(vol.shape) #draw it t = vv.volshow(vol) t.colormap = vv.CM_HOT t.renderstyle = 'iso' t.parent = m #set the camera filed of view a.camera.fov = 60 a.camera.elevation = 30 a.camera.zoom = 0.01 #set the limits to the min and max t.clim = (mn, mx) #Force the axis to draw now a.Draw() f.DrawNow() t_m.sleep(1) #get the zero padded time s = ZeroPad(times[-1], times[i]) #create the save file path file_path = save_path + name + "_" + s + ".jpeg" #Now get the screenshot vv.screenshot(file_path) #load this image using PIL, append a color bar showing the min and max ss = Image.open(file_path) w, h = ss.size #make a new font font = ImageFont.truetype("arial.ttf", 24) color_bar = draw_color_bar(mn, mx, 50, int(.99*h), font) #get the colorbar dimension w1, h1 = color_bar.size #make a new image ht = max(h, h1) im_final = Image.new("RGB", (w + w1 + 10, ht), "white") #paste the other images on to this im_final.paste(color_bar, (w + 10, 0)) im_final.paste(ss, (0, 0)) #Now finally draw the time and the text on top of this draw = ImageDraw.Draw(im_final) #get the text to draw txt = "Species: " + name + " Time: " + repr(times[i]) #gte the position pos = (25, 20) draw.text(pos, txt, font = font, fill = (0,0,0)) #save the final file im_final.save(file_path) #close all the figures vv.closeAll()
def __init__(self, vol, a_transversal, a_coronal, a_sagittal, a_MIP, a_text, nr_of_stents, clim=None): self.nr_of_stents = nr_of_stents self.f = vv.gcf() self.vol = vol # Create empty list of endpoints self.endpoints = [] self.endpoints = ['xx,yy,zz'] * nr_of_stents * 2 self.endpointsindex = 0 # Create text objects self._labelcurrent = vv.Label(a_text) self._labelx = vv.Label(a_text) self._labelxslice = vv.Label(a_text) self._labely = vv.Label(a_text) self._labelyslice = vv.Label(a_text) self._labelz = vv.Label(a_text) self._labelzslice = vv.Label(a_text) self._labelcurrent.position = -250, 10 self._labelx.position = -250, 35 self._labelxslice.position = -200, 35 self._labely.position = -250, 55 self._labelyslice.position = -200, 55 self._labelz.position = -250, 75 self._labelzslice.position = -200, 75 self._labelendpointstext = [] self._labelendpointstext.append(vv.Label(a_text)) self._labelendpointstext[0].position = 100, -5 self._labelendpointstext.append(vv.Label(a_text)) self._labelendpointstext[1].position = 230, -5 for i in range(2, self.nr_of_stents + 2): self._labelendpointstext.append(vv.Label(a_text)) self._labelendpointstext[i].position = 40, 15 + (20 * (i - 2)) self._labelendpoints = [] for i in range(0, self.nr_of_stents * 2, 2): self._labelendpoints.append(vv.Label(a_text)) self._labelendpoints[i].position = 100, 15 + (20 * (i / 2)), 50, 20 self._labelendpoints.append(vv.Label(a_text)) self._labelendpoints[i + 1].position = 230, 15 + (20 * (i / 2)), 50, 20 # Create Select button self._select = False self._butselect = vv.PushButton(a_text) self._butselect.position = -110, 150 self._butselect.text = 'Select' # Create Back button self._back = False self._butback = vv.PushButton(a_text) self._butback.position = 10, 150 self._butback.text = 'Back' # Create Close button self._finished = False self._butclose = vv.PushButton(a_text) self._butclose.position = -50, 180 self._butclose.text = 'Finish' # Get short name for sampling if isinstance(vol, Aarray): self._sam = sam = vol.sampling else: self._sam = None sam = (1, 1, 1) # Display the slices and 3D MIP self.b1 = VolViewer(vol, 0, axes=a_transversal, clim=clim) self.b2 = VolViewer(vol, 1, axes=a_coronal, clim=clim) self.b3 = VolViewer(vol, 2, axes=a_sagittal, clim=clim) renderstyle = 'mip' a_MIP.daspect = 1, 1, -1 self.b4 = vv.volshow(vol, clim=(0, 2500), renderStyle=renderstyle, axes=a_MIP) c = vv.ClimEditor(a_MIP) c.position = (10, 50) # set axis settings for a in [a_transversal, a_coronal, a_sagittal, a_MIP]: a.bgcolor = [0, 0, 0] a.axis.visible = False a.showAxis = True # get current slice number Zslice = self.b1.GetCurrentSlice() Yslice = self.b2.GetCurrentSlice() Xslice = self.b3.GetCurrentSlice() size = vol.shape # create lines for position of x,y and z slices origin = vol.origin Zrange = (origin[0], (size[0] * sam[0]) + origin[0]) Xrange = (origin[1], (size[1] * sam[1]) + origin[1]) Yrange = (origin[2], (size[2] * sam[2]) + origin[2]) self.l11 = vv.Line(a_transversal, [(Yslice, Xrange[0]), (Yslice, Xrange[1])]) self.l12 = vv.Line(a_transversal, [(Yrange[0], Xslice), (Yrange[1], Xslice)]) self.l21 = vv.Line(a_coronal, [(Zslice, Zrange[0]), (Zslice, Zrange[1])]) self.l22 = vv.Line(a_coronal, [(Yrange[0], Xslice), (Yrange[1], Xslice)]) self.l31 = vv.Line(a_sagittal, [(Zslice, Zrange[0]), (Zslice, Zrange[1])]) self.l32 = vv.Line(a_sagittal, [(Xrange[0], Yslice), (Xrange[1], Yslice)]) # change color of the lines for i in [self.l11, self.l12, self.l21, self.l22, self.l31, self.l32]: i.lc = 'g' # create a point in the MIP figure for the current position self.mippoint = vv.Line(a_MIP, [(Zslice, Xslice, Yslice)]) self.mippoint.ms = 'o' self.mippoint.mw = 5 self.mippoint.mc = 'g' self.mippoint.alpha = 0.9 # Get list of all range wobjects self._volviewers = [self.b1, self.b2, self.b3] # Bind events fig = a_text.GetFigure() fig.eventClose.Bind(self._OnFinish) self._butclose.eventPress.Bind(self._OnFinish) self._butselect.eventPress.Bind(self._OnSelect) self._butback.eventPress.Bind(self._OnBack) for r in self._volviewers: r.eventPositionUpdate.Bind(self._OnMouseClickAxis) for s in range(len(self._labelendpoints)): self._labelendpoints[s].eventMouseDown.Bind( self._OnMouseClickEndpoint) # Almost done self._SetTexts() self.updatePosition()
# The appearance of the line objects can be set in their # constructor, or by using their properties line1.lc, line1.mc = 'g', 'b' line2.lc, line2.mc = 'y', 'r' # Display a legend a1.legend = "Astronaut's face", "Astronaut's helmet" # Create second axes (with a black background) a2 = vv.subplot(122) a2.bgcolor = 'k' a2.axis.axisColor = 'w' # Display a texture vol = vv.aVolume(2) # returns a test volume as a numpy array texture3d = vv.volshow(vol) # Display a mesh using one of the "solid" functions mesh = vv.solidTeapot((32, 32, 80), scaling=(50, 50, 50)) mesh.faceColor = 0.4, 1, 0.4 mesh.specular = 'r' # Set orthographic projection a2.camera.fov = 45 # Create labels for the axis a2.axis.xLabel = 'x-axis' a2.axis.yLabel = 'y-axis' a2.axis.zLabel = 'z-axis' # Enter main loop
# constructor, or by using their properties line1.lc, line1.mc = 'g', 'b' line2.lc, line2.mc = 'y', 'r' # Display a legend a1.legend = "Lena's face", "Lena's shoulder" # Create second axes (with a black background) a2 = vv.subplot(122) a2.bgcolor = 'k' a2.axis.axisColor = 'w' # Display a texture vol = vv.aVolume(2) # returns a test volume as a numpy array texture3d = vv.volshow(vol) # Display a mesh using one of the "solid" functions mesh = vv.solidTeapot((32,32,80), scaling=(50,50,50)) mesh.faceColor = 0.4, 1, 0.4 mesh.specular = 'r' # Set orthographic projection a2.camera.fov = 45 # Create labels for the axis a2.axis.xLabel = 'x-axis' a2.axis.yLabel = 'y-axis' a2.axis.zLabel = 'z-axis' # Enter main loop
vv.clf() a = vv.gca() a.daspect = 1, 1, -1 a.axis.axisColor = 1, 1, 1 a.axis.visible = True a.bgcolor = 0, 0, 0 vv.title( 'Maximum intensity projection cine-loop of the original ECG-gated CT volumes of patient %s' % ptcode[8:]) # Setup data container container = vv.MotionDataContainer(a) showVol = 'mip' for vol in vols: # t = vv.volshow2(vol, clim=(-550, 500)) # -750, 1000 t = vv.volshow(vol, clim=(0, 2500), renderStyle=showVol) t.isoThreshold = 350 # iso or mip work well t.parent = container if showVol == 'iso': t.colormap = { 'g': [(0.0, 0.0), (0.33636364, 1.0)], 'b': [(0.0, 0.0), (0.49545455, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)], 'r': [(0.0, 0.0), (0.22272727, 1.0)] } f.eventKeyDown.Bind( lambda event: _utils_GUI.RotateView(event, [a], axishandling=False)) f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, [a])) foo = recordMovie(frameRate=7)
def on_key(event): global node_points if event.key == vv.KEY_DOWN: # hide nodes and labels t1.visible, t2.visible, t3.visible = False, False, False t4.visible, t5.visible, t6.visible = False, False, False for node_point in node_points: node_point.visible = False if event.key == vv.KEY_UP: # show nodes and labels t1.visible, t2.visible, t3.visible = True, True, True t4.visible, t5.visible, t6.visible = True, True, True for node_point in node_points: node_point.visible = True if event.text == 'n': # add clickable point: point on graph closest to picked point (SHIFT+R-click ) view = a.GetView() for node_point in node_points: node_point.visible = False snapOut = _utils_GUI.snap_picked_point_to_graph(model, vol, label) # x,y,z pickedOnGraph = snapOut[0] n1, n2 = snapOut[1] pickedOnGraphIndex = snapOut[2] pickedOnGraphDeforms = model.edge[n1][n2]['pathdeforms'][pickedOnGraphIndex] model.add_node(pickedOnGraph, deforms=pickedOnGraphDeforms) node_points = _utils_GUI.interactive_node_points(model, scale=0.7) _utils_GUI.node_points_callbacks(node_points, selected_nodes, t0=t0) # visualize # pickedOnGraph_sphere = vv.solidSphere(translation = (pickedOnGraph), scaling = (scale,scale,scale)) point = vv.plot(pickedOnGraph[0], pickedOnGraph[1], pickedOnGraph[2], mc = 'y', ms = 'o', mw = 9, alpha=0.5) a.SetView(view) if event.key == vv.KEY_ENTER: assert len(selected_nodes) == 2 or 3 or 4 # Node_to_node analysis 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 output = point_to_point_pulsatility(selectn1, n1Deforms, selectn2, n2Deforms) # update labels t1.text = '\b{Node pair}: %i - %i' % (nindex[0], nindex[1]) t2.text = 'Node-to-node Min: %1.2f mm' % output[0][0] t3.text = 'Node-to-node Max: %1.2f mm' % output[4][0] t4.text = 'Node-to-node Median: %1.2f mm' % output[2] t5.text = 'Node-to-node Q1 and Q3: %1.2f | %1.2f mm' % (output[1], output[3]) t6.text = '\b{Node-to-node Pulsatility: %1.2f mm}' % (output[5][0] ) t1.visible, t2.visible, t3.visible = True, True, True t4.visible, t5.visible, t6.visible = True, True, True # Store output including index/nr of nodes output.insert(0, [n1index]) # at the start output.insert(1, [n2index]) output[8].insert(0, [n1index]) output[9].insert(0, [n2index]) if output not in storeOutput: storeOutput.append(output) # Midpoint_to_node analysis if len(selected_nodes)== 3: # find the edge selected to get midpoint selected_nodes2 = selected_nodes.copy() for node1 in selected_nodes: selected_nodes2.remove(node1) # check combination once and not to self for node2 in selected_nodes2: if model.has_edge(node1.node, node2.node): # get midpoint of edge and its deforms output = get_midpoint_deforms_edge(model, node1.node, node2.node) break # edge found, to first for loop # get index of nodepair and midpoint and its deforms nodepair1 = output[0] midpoint1IndexPath = output[1] midpoint1 = output[2] midpoint1Deforms = output[3] # get node for i, node in enumerate(selected_nodes): if node.nr not in nodepair1: n3 = node break # get deforms for node n3Deforms = model.node[n3.node]['deforms'] # get pulsatility # first selected first in output if i > 0: # single node was not selected first output2 = point_to_point_pulsatility(midpoint1, midpoint1Deforms, n3.node, n3Deforms) else: output2 = point_to_point_pulsatility(n3.node, n3Deforms, midpoint1, midpoint1Deforms) # visualize midpoint view = a.GetView() point = vv.plot(midpoint1[0], midpoint1[1], midpoint1[2], mc = 'm', ms = 'o', mw = 8, alpha=0.5) a.SetView(view) # update labels t1.text = '\b{Node pairs}: (%i %i) - (%i)' % (nodepair1[0],nodepair1[1],n3.nr) t2.text = 'Midpoint-to-node Min: %1.2f mm' % output2[0][0] t3.text = 'Midpoint-to-node Max: %1.2f mm' % output2[4][0] t4.text = 'Midpoint-to-node Median: %1.2f mm' % output2[2] t5.text = 'Midpoint-to-node Q1 and Q3: %1.2f | %1.2f mm' % (output2[1], output2[3]) t6.text = '\b{Midpoint-to-node Pulsatility: %1.2f mm}' % (output2[5][0]) t1.visible, t2.visible, t3.visible = True, True, True t4.visible, t5.visible, t6.visible = True, True, True # Store output including index nodes if i > 0: output2.insert(0, nodepair1) # at the start output2.insert(1, [n3.nr]) output2[8].insert(0, midpoint1IndexPath) output2[9].insert(0, [n3.nr]) else: output2.insert(0, [n3.nr]) # at the start output2.insert(1, nodepair1) output2[8].insert(0, [n3.nr]) output2[9].insert(0, midpoint1IndexPath) if output2 not in storeOutput: storeOutput.append(output2) # Midpoint_to_midpoint analysis if len(selected_nodes) == 4: outputs = list() # get midpoints for the two edges # get nodepairs from order selected for i in (0,2): n1 = selected_nodes[i].node n2 = selected_nodes[i+1].node assert model.has_edge(n1, n2) # get midpoint of edge and its deforms output = get_midpoint_deforms_edge(model, n1, n2) midpoint = output[2] # store for both edges outputs.append(output) # visualize midpoint view = a.GetView() point = vv.plot(midpoint[0], midpoint[1], midpoint[2], mc = 'm', ms = 'o', mw = 8, alpha=0.5) a.SetView(view) assert len(outputs) == 2 # two midpoints should be found # get midpoints and deforms nodepair1 = outputs[0][0] midpoint1IndexPath = outputs[0][1] midpoint1 = outputs[0][2] midpoint1Deforms = outputs[0][3] nodepair2 = outputs[1][0] midpoint2IndexPath = outputs[1][1] midpoint2 = outputs[1][2] midpoint2Deforms = outputs[1][3] # get pulsatility midp to midp output2 = point_to_point_pulsatility(midpoint1, midpoint1Deforms, midpoint2, midpoint2Deforms) # # get max pulsatility between points on the paths # outputmaxP.append(edge_to_edge_max_pulsatility(model, nodepair1, nodepair2)) # update labels t1.text = '\b{Node pairs}: (%i %i) - (%i %i)' % (nodepair1[0], nodepair1[1], nodepair2[0], nodepair2[1]) t2.text = 'Midpoint-to-midpoint Min: %1.2f mm' % output2[0][0] t3.text = 'Midpoint-to-midpoint Max: %1.2f mm' % output2[4][0] t4.text = 'Midpoint-to-midpoint Median: %1.2f mm' % output2[2] t5.text = 'Midpoint-to-midpoint Q1 and Q3: %1.2f | %1.2f mm' % (output2[1], output2[3]) t6.text = '\b{Midpoint-to-midpoint Pulsatility: %1.2f mm}' % (output2[5][0]) t1.visible, t2.visible, t3.visible = True, True, True t4.visible, t5.visible, t6.visible = True, True, True # Store output including nodepairs of the midpoints output2.insert(0, nodepair1) # indices at the start output2.insert(1, nodepair2) output2[8].insert(0, midpoint1IndexPath) output2[9].insert(0, midpoint2IndexPath) if output2 not in storeOutput: storeOutput.append(output2) # Visualize analyzed nodes and deselect for node in selected_nodes: node.faceColor = (0,1,0,0.8) # # make green when analyzed selected_nodes.clear() if event.key == vv.KEY_ESCAPE: # FINISH, STORE TO EXCEL # visualize view = a.GetView() t = vv.volshow(vol, clim=clim, renderStyle='mip') # show mesh of model without deform coloring modelmesh = create_mesh(model, 0.4) # Param is thickness m = vv.mesh(modelmesh) m.faceColor = (0,1,0,1) # green a.SetView(view) # Store to EXCEL storeOutputToExcel(storeOutput,exceldir) for node_point in node_points: node_point.visible = False # show that store is ready
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 #a.camera.fov = 45 # Create colormap editor wibject. vv.ColormapEditor(a)
# create multiple instances of the same volume (simulate motion) vols = [vv.aVolume()] for i in range(9): vol = vols[i].copy() vol[2:] = vol[:-2] vol[:2] = 0 vols.append(vol) # create figure, axes, and data container object f = vv.clf() a = vv.gca() m = vv.MotionDataContainer(a) # create volumes, loading them into opengl memory, and insert into container. for vol in vols: t = vv.volshow(vol) t.parent = m t.colormap = vv.CM_HOT # Remove comments to use iso-surface rendering #t.renderStyle = 'iso' #t.isoThreshold = 0.2 # set some settings a.daspect = 1,1,-1 a.xLabel = 'x' a.yLabel = 'y' a.zLabel = 'z' # Enter main loop app = vv.use() app.Run()
vv.imshow(imTr, clim=clim) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title('Overlay') a2.daspect = 1, 1, -1 a3 = vv.subplot(223) vv.imshow(imTr, clim=clim) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title( 'Im2:Original transformed (DataDressedInterpolated u_\magnitude {})' .format(mat2['u_magnitude'][0][0])) a3.daspect = 1, 1, -1 else: clim = (-400, 1500) a1 = vv.subplot(221) vv.volshow(volOr, clim=clim) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title('Im1:Original (DataDressed)') a1.daspect = 1, 1, -1 a2 = vv.subplot(222) vv.volshow(volOr, clim=clim) vv.volshow(volTr, clim=clim) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title('Overlay') a2.daspect = 1, 1, -1 a3 = vv.subplot(223) vv.volshow(volTr, clim=clim) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title(
""" This example demonstrates rendering a color volume. This example demonstrates two render styles. Note that all render styles are capable of rendering color data. """ import numpy as np import visvis as vv app = vv.use() # Use vv.aVolume to create random bars for each color plane N = 64 vol = np.empty((N, N, N, 3), dtype='float32') for i in range(3): vol[:, :, :, i] = vv.aVolume(10, N) # Show vv.figure() a1 = vv.subplot(121) t1 = vv.volshow(vol[:, :, :, :], renderStyle='mip') vv.title('color MIP render') a2 = vv.subplot(122) t2 = vv.volshow(vol[:, :, :, :], renderStyle='iso') t2.isoThreshold = 0.5 vv.title('color ISO-surface render') # Share cameras a1.camera = a2.camera # Run app app.Run()
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 plot_3d_orientation_map(name, lat_data, azth_data, radius_structure_elem=1, output_dir=None, width=512, height=512, camera_azth=44.5, camera_elev=35.8, camera_roll=0.0, camera_fov=35.0, camera_zoom=0.0035, camera_loc=(67.0, 81.6, 45.2), xlabel='', ylabel='', zlabel='', axis_color='w', background_color='k'): """Renders orientation data in 3D with RGB angular color-coding. Parameters ---------- name : str Indicates the name of the output png file. lat_data : 3D array Indicates the 3D array containing latitude / elevation angle at every point of the skeleton in radians. azth_data : 3D array Indicates the 3D array containing azimuth angle at every point of the skeleton in radians. radius_structure_elem : integer Indicates the size of the structure element of the dilation process to thicken the skeleton. output_dir : str Indicates the path to the output folder where the image will be stored. width : int Indicates the width of the visualization window. height : int Indicates the width of the visualization window. camera_azth : float Indicates the azimuth angle of the camera. camera_elev : float Indicates the latitude / elevation angle of the camera. camera_roll : float Indicates the roll angle of the camera. camera_fov : float Indicates the field of view of the camera. camera_zoom : float Indicates the zoom level of the camera. camera_loc : tuple Indicates the camera location. xlabel : str Indicates the label along the x-axis. ylabel : str Indicates the label along the y-axis. zlabel : str Indicates the label along the z-axis. axis_color : str Indicates the color of axes. background_color : str Indicates the background color of the figure. """ if not visvis_available: print( 'The visvis package is not found. The visualization cannot be done.' ) return rmin, rmax, cmin, cmax, zmin, zmax = _bbox_3D(azth_data) azth, lat = azth_data[rmin:rmax, cmin:cmax, zmin:zmax], \ np.abs(lat_data[rmin:rmax, cmin:cmax, zmin:zmax]) skel = azth.copy().astype(np.float32) skel[skel.nonzero()] = 1. azth = ndi.grey_dilation(azth, structure=morphology.ball(radius_structure_elem)) lat = ndi.grey_dilation(lat, structure=morphology.ball(radius_structure_elem)) skel = ndi.binary_dilation( skel, structure=morphology.ball(radius_structure_elem)) Z, Y, X = skel.nonzero() vol_orient = np.zeros(skel.shape + (3, ), dtype=np.float32) print(vol_orient.size, vol_orient[skel.nonzero()].size) for z, y, x in zip(Z, Y, X): vol_orient[z, y, x] = geo2rgb(lat[z, y, x], azth[z, y, x]) app = vv.use() fig = vv.figure() fig._currentAxes = None fig.relativeFontSize = 2. fig.position.w = width fig.position.h = height t = vv.volshow(vol_orient[:, :, :], renderStyle='iso') t.isoThreshold = 0.5 a = vv.gca() a.camera.azimuth = camera_azth a.camera.elevation = camera_elev a.camera.roll = camera_roll a.camera.fov = camera_fov a.camera.zoom = camera_zoom a.camera.loc = camera_loc a.bgcolor = background_color a.axis.axisColor = axis_color a.axis.xLabel = xlabel a.axis.yLabel = ylabel a.axis.zLabel = zlabel # def mouseUp(event): # print 'mouseUp!!' # a = vv.gca() # print a.camera.GetViewParams() # # a.eventMouseUp.Bind(mouseUp) # fig.eventMouseUp.Bind(mouseUp) # # a.Draw() # fig.DrawNow() if output_dir is not None: if not os.path.exists(output_dir): os.makedirs(output_dir) vv.screenshot(os.path.join(output_dir, f'{name}_3d_orientation.png'), sf=1, bg=background_color) app.Run()
model = s2.model model2 = model.copy() # Load static CT image to add as reference s = loadvol(basedir, ptcode, ctcode, cropname, 'avgreg') vol = s.vol ## Visualize f = vv.figure(2); vv.clf() 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=(0, 2500), renderStyle='mip') model.Draw(mc='b', mw = 10, lc='g') #model_hooks.Draw(mc='r', mw = 10, lc='r') #model_struts.Draw(mc='m', mw = 10, lc='m') #model_top.Draw(mc='y', mw = 10, lc='y') #model_2nd.Draw(mc='c', mw = 10, lc='c') vv.xlabel('x (mm)');vv.ylabel('y (mm)');vv.zlabel('z (mm)') vv.title('Model for LSPEAS %s - %s' % (ptcode[7:], ctcode)) # viewringcrop = # a.SetView(viewringcrop) ## Get hooks in vessel wall def add_nodes_edge_to_newmodel(modelnew, model,n,neighbour): """ Get edge and nodes with attributes from model and add to newmodel
help="Show textured mesh NOT YET IMPLEMENTED") args = parser.parse_args() vol = np.fromfile(args.volume, dtype=np.int8) # vol = vol.reshape((200, 192, 192)) im = vv.imread(args.image) t = vv.imshow(im) t.interpolate = True # interpolate pixels # volshow will use volshow3 and rendering the isosurface if OpenGL # version is >= 2.0. Otherwise, it will show slices with bars that you # can move (much less useful). volRGB = np.stack(((vol > 1) * im[:, :, 0], (vol > 1) * im[:, :, 1], (vol > 1) * im[:, :, 2]), axis=3) v = vv.volshow(volRGB, renderStyle='iso') v.transformations[1].sz = 0.5 # Z was twice as deep during training l0 = vv.gca() l0.light0.ambient = 0.9 # 0.2 is default for light 0 l0.light0.diffuse = 1.0 # 1.0 is default a = vv.gca() a.camera.fov = 0 # orthographic vv.use().Run()
# Step B: Crop and Save SSDF vols = [vol] for cropname in cropnames: savecropvols(vols, ssdf_basedir, ptcode, ctcode, cropname, stenttype) ## Visualize result s1 = loadvol(ssdf_basedir, ptcode, ctcode, cropnames[0], what ='phase') vol = s1.vol # Visualize and compare colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} import visvis as vv fig = vv.figure(1); vv.clf() fig.position = 0, 22, 1366, 706 a = vv.gca() a.daspect = 1,1,-1 t1 = vv.volshow(vol, clim=(0, 2500), renderStyle='iso') # iso or mip t1.isoThreshold = 400 t1.colormap = colormap t2 = vv.volshow2(vol, 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('Static CT Volume' )
The size of the volume (for each dimension). """ # Create volume vol = np.zeros((size, size, size), dtype=np.float32) # Make bars for iter in range(N): # x b = BarDescription(size) vol[b.i - b.w1:b.i + b.w1, b.j - b.w2:b.j + b.w2, b.k1:-b.k2] += b.value # y b = BarDescription(size) vol[b.i - b.w1:b.i + b.w1, b.k1:-b.k2, b.j - b.w2:b.j + b.w2] += b.value # z b = BarDescription(size) vol[b.k1:-b.k2, b.i - b.w1:b.i + b.w1, b.j - b.w2:b.j + b.w2] += b.value # Clip and return vol[vol > 1.0] = 1.0 return vol if __name__ == '__main__': vv.figure() t = vv.volshow(aVolume())
N : int The number of bars for each dimension. size : int The size of the volume (for each dimension). """ # Create volume vol = np.zeros((size,size,size), dtype=np.float32) # Make bars for iter in range(N): # x b = BarDescription(size) vol[ b.i-b.w1:b.i+b.w1, b.j-b.w2:b.j+b.w2, b.k1:-b.k2 ] += b.value # y b = BarDescription(size) vol[ b.i-b.w1:b.i+b.w1, b.k1:-b.k2, b.j-b.w2:b.j+b.w2 ] += b.value # z b = BarDescription(size) vol[ b.k1:-b.k2, b.i-b.w1:b.i+b.w1, b.j-b.w2:b.j+b.w2 ] += b.value # Clip and return vol[vol>1.0]=1.0 return vol if __name__ == '__main__': vv.figure() t=vv.volshow(aVolume())
import argparse import visvis as vv app = vv.use() if __name__ == "__main__": parser = argparse.ArgumentParser( description='Plot the disparity space image (DSI) using 3D slices') parser.add_argument( '-i', '--input', default='dsi.npy', type=str, help='path to the NPY file containing the DSI (default: dsi.npy)') args = parser.parse_args() a = vv.gca() a.daspect = 1, -1, 1 a.daspectAuto = True vol = np.load(args.input) # Reorder axis so that the Z axis points forward instead of up vol = np.swapaxes(vol, 0, 1) vol = np.flip(vol, axis=0) t = vv.volshow(vol, renderStyle='mip') t.colormap = vv.CM_HOT app.Run()
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)
vol = s2.vol s3 = loadvol(basedir, ptcode, ctcode, cropname, 'phases') vol0ori = s3.vol0 # todo: backward/forward based on how deforms were obtained?? # deforms was obtained as backward, from original phases to mean volume avgreg deform = pirt.DeformationFieldBackward(deforms[0]) # vol2 = pirt.interp.deform_backward(vol, deforms[0]) # te low level, gebruikt awarp niet vol2 = deform.inverse().as_backward().apply_deformation( vol0ori) # gebruikt pirt deformation.py vv.figure(1) vv.clf() a1 = vv.subplot(131) t1 = vv.volshow(vol) a1.daspect = (1, 1, -1) vv.title('vol average of cardiac cycle') # vv.figure(2); vv.clf() a2 = vv.subplot(132) t2 = vv.volshow(vol2) a2.daspect = (1, 1, -1) vv.title('vol 0 deformed to avg volume') # vv.figure(3); vv.clf() a3 = vv.subplot(133) t3 = vv.volshow2((vol2 - vol), clim=(-500, 500)) a3.daspect = (1, 1, -1) vv.title('difference') a1.camera = a2.camera = a3.camera t1.clim = t2.clim = 0, 2000
def select_stent(volnr, params=None): """ This functions calls the stent extration function. It contains seed points for each dataset """ if params is None: params = getDefaultParams() ssdf._stent_tracking_params = params if volnr == 1: #vol 1 vol, sampling, origin = load_volume(1) seed_points = Pointset(3) seed_points.Append(60, 110, 133) seed_points.Append(100, 75, 150) seed_points.Append(160, 70, 148) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 2: #vol 2 vol, sampling, origin = load_volume(2) seed_points = Pointset(3) seed_points.Append(60, 175, 155) seed_points.Append(100, 150, 170) seed_points.Append(165, 140, 167) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 3: #vol 3 vol, sampling, origin = load_volume(3) seed_points = Pointset(3) seed_points.Append(47, 160, 140) seed_points.Append(80, 145, 130) seed_points.Append(130, 130, 128) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 4: #vol 4 vol, sampling, origin = load_volume(4) seed_points = Pointset(3) seed_points.Append(40, 160, 160) seed_points.Append(140, 145, 135) seed_points.Append(150, 150, 150) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 5: #vol 5 vol, sampling, origin = load_volume(5) seed_points = Pointset(3) seed_points.Append(34, 150, 170) seed_points.Append(60, 135, 180) seed_points.Append(130, 140, 180) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 6: #vol 6 vol, sampling, origin = load_volume(6) seed_points = Pointset(3) seed_points.Append(40, 170, 175) seed_points.Append(70, 160, 180) seed_points.Append(140, 142, 168) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 7: #vol 7 vol, sampling, origin = load_volume(7) seed_points = Pointset(3) seed_points.Append(40, 180, 160) seed_points.Append(110, 160, 160) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 8: #vol 8 vol, sampling, origin = load_volume(8) seed_points = Pointset(3) seed_points.Append(60, 130, 190) seed_points.Append(80, 110, 180) seed_points.Append(120, 112, 140) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) elif volnr == 18: #vol 18 vol, sampling, origin = load_volume(18) seed_points = Pointset(3) seed_points.Append(70, 170, 140) seed_points.Append(135, 150, 160) node_points_stent, center_points_stent, stent_points_stent = stent_detection( vol, sampling, origin, seed_points) else: raise ValueError('Invalid volnr') plot = True if plot: points = Pointset(3) for i in range(len(node_points_stent)): points.Append(node_points_stent[i][2], node_points_stent[i][1], node_points_stent[i][0]) points_2 = Pointset(3) for i in range(len(stent_points_stent)): points_2.Append(stent_points_stent[i][2], stent_points_stent[i][1], stent_points_stent[i][0]) vv.closeAll() vv.volshow(vol) vv.plot(points_2, ls='', ms='.', mc='g', mw=4, alpha=0.5) vv.plot(points, ls='', ms='.', mc='b', mw=4, alpha=0.9) graph = from_nodes_to_graph(node_points_stent) return graph