def surface(volume, threshold=0.5, verbose=1): verts, faces = measure.marching_cubes(volume, threshold) if verbose == 2: import visvis as vv vv.mesh(np.fliplr(verts), faces) vv.use().Run()
def main(select=3, **kwargs): """Script main function. select: int 1: Medical data 2: Blocky data, different every time 3: Two donuts 4: Ellipsoid """ import visvis as vv # noqa: delay import visvis and GUI libraries # Create test volume if select == 1: vol = vv.volread('stent') isovalue = kwargs.pop('level', 800) elif select == 2: vol = vv.aVolume(20, 128) isovalue = kwargs.pop('level', 0.2) elif select == 3: with timer('computing donuts'): vol = donuts() isovalue = kwargs.pop('level', 0.0) # Uncommenting the line below will yield different results for # classic MC # vol *= -1 elif select == 4: vol = ellipsoid(4, 3, 2, levelset=True) isovalue = kwargs.pop('level', 0.0) else: raise ValueError('invalid selection') # Get surface meshes with timer('finding surface lewiner'): vertices1, faces1 = marching_cubes_lewiner(vol, isovalue, **kwargs)[:2] with timer('finding surface classic'): vertices2, faces2 = marching_cubes_classic(vol, isovalue, **kwargs) # Show vv.figure(1) vv.clf() a1 = vv.subplot(121) vv.title('Lewiner') m1 = vv.mesh(np.fliplr(vertices1), faces1) a2 = vv.subplot(122) vv.title('Classic') m2 = vv.mesh(np.fliplr(vertices2), faces2) a1.camera = a2.camera # visvis uses right-hand rule, gradient_direction param uses left-hand rule m1.cullFaces = m2.cullFaces = 'front' # None, front or back vv.use().Run()
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 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 showVesselMesh(vesselstl, ax=None, vesselMeshColor=(1,0,0,0.5), type = 1, **kwargs): """ plot pointcloud of mesh in ax type = 1 use vv.mesh; type = 2 use vv.plot """ if ax is None: ax = vv.gca() if vesselstl is None: return if type == 1: vessel = vv.mesh(vesselstl, axes=ax, **kwargs) vessel.faceColor = vesselMeshColor # (1,0,0,0.5) or alpha 0.4-0.6 return vessel elif type == 2: # get PointSet from STL ppvessel = points_from_mesh(vesselstl, invertZ = False) # removes duplicates vv.plot(ppvessel, ms='.', ls='', mc= 'r', alpha=0.2, mw = 7, axes = ax) return ppvessel
def plot_3d(image, threshold=100): # Position the scan upright, # so the head of the patient would be at the top facing the camera p = image.transpose(2, 1, 0) p = p[::2, ::2, ::2] # verts, faces = measure.marching_cubes(p, threshold) # verts, faces,_,_ = measure.marching_cubes_lewiner(p, threshold) verts, faces, normals, values = measure.marching_cubes(p, threshold) ''' verts, faces, normals, values = marching_cubes_lewiner(myvolume, 0.0) # doctest: +SKIP >>> vv.mesh(np.fliplr(verts), faces, normals, values) # doctest: +SKIP >>> vv.use().Run() # doctest: +SKIP ''' lung_mesh = vv.mesh(np.fliplr(verts), faces, normals, values, verticesPerFace=4, colormap=None, clim=None, texture=None, axesAdjust=True, axes=None) # lung_mesh.setcolor([0.45, 0.45, 0.75]) faceColor = 'g' vv.use().Run() fig = plt.figure(figsize=(10, 10)) ax = fig.add_subplot(111, projection='3d') # Fancy indexing: `verts[faces]` to generate a collection of triangles mesh = Poly3DCollection(verts[faces], alpha=0.1) face_color = [0.5, 0.5, 1] mesh.set_facecolor(face_color) ax.add_collection3d(mesh) ax.set_xlim(0, p.shape[0]) ax.set_ylim(0, p.shape[1]) ax.set_zlim(0, p.shape[2]) plt.show()
self.show() #%% # Create visvis application app = vv.use() app.Create() # Create main window frame and set a resolution. main_w = MainWindow() main_w.resize(1200, 800) # Create the 3 D shape model as a mesh. verticesPerFace equals 3 since triangles define the # mesh's surface in this case vv.mesh(vertices=VERTICES, faces=faces, verticesPerFace=3) # Get axes objects axes = vv.gca() # Set a black background axes.bgcolor = 'black' # Deactivate the grid and make the x, y, z axes invisible axes.axis.showGrid = False axes.axis.visible = False # Set some camera settings # Please note: if you want to "fly" arond the comet with w, a, s, d (translation) and i, j, k, l # (tilt) replace '3d' with 'fly' axes.camera = '3d'
# Main outcome 1: distance 2nd ring valleys to renal # Main outcome 2: migration 2nd ring valleys from discharge to 1, 6, 12 months ## Visualize f = vv.figure(2) vv.clf() f.position = 0.00, 22.00, 1920.00, 1018.00 alpha = 0.5 if ctcode2: a1 = vv.subplot(121) else: a1 = vv.gca() show_ctvolume(vol1, model1, showVol=showVol, clim=clim0, isoTh=isoTh) pick3d(vv.gca(), vol1) model1.Draw(mc='b', mw=10, lc='g') vm = vv.mesh(modelmesh1) vm.faceColor = 'g' # m = vv.mesh(vessel1) # m.faceColor = (1,0,0, alpha) # red # vis vessel, centerline, renal origo, peaks valleys R1 vv.plot(ppvessel1, ms='.', ls='', mc='r', alpha=0.2, mw=7, axes=a1) # vessel vv.plot(PointSet(list(c1_start1)), ms='.', ls='', mc='g', mw=18, axes=a1) # start1 vv.plot([e[0] for e in c1_ends], [e[1] for e in c1_ends], [e[2] for e in c1_ends], ms='.', ls='', mc='b', mw=18, axes=a1) # ends
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 a1.camera = a2.camera = a3.camera # test = vv.plot([0,0,0], axesAdjust=False, ls='', ms='.', mc='r', mw=15) if False: node = sd._nodes3.nodes()[3] pp = vv.Pointset( np.array(list(node)).reshape(1,3) ) test.SetPoints(pp) # Take a screenshot #vv.screenshot('/home/almar/projects/valve_result_pat001.jpg', vv.gcf(), sf=2)
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
def _plot_visvis(verts, faces, normals, values): import visvis as vv vv.mesh(np.fliplr(verts), faces, normals, values) vv.use().Run()
def interactiveClusterRemoval(graph, radius=0.7, axVis=False, faceColor=(0.5, 1.0, 0.3), selectColor=(1.0, 0.3, 0.3)): """ showGraphAsMesh(graph, radius=0.7, faceColor=(0.5,1.0,0.3), selectColor=(1.0,0.3, 0.3) ) Manual delete clusters in the graph. Show the given graph as a mesh, or to be more precize as a set of meshes representing the clusters of the graph. By holding the mouse over a mesh, it can be selected, after which it can be deleted by pressing delete. Use sd._nodes3 for graph when in segmentation. Returns the axes in which the meshes are drawn. """ import visvis as vv import networkx as nx from stentseg.stentdirect import stentgraph from stentseg.stentdirect.stentgraph import create_mesh # Get clusters of nodes clusters = list(nx.connected_components(graph)) # Build meshes meshes = [] for cluster in clusters: # skip single nodes as these cannot be converted with create_mesh if len(cluster) == 1: continue g = graph.copy() for c in clusters: if not c == cluster: g.remove_nodes_from(c) # Convert to mesh (this takes a while) bm = create_mesh(g, radius=radius) # Store meshes.append(bm) # Define callback functions def meshEnterEvent(event): event.owner.faceColor = selectColor def meshLeaveEvent(event): event.owner.faceColor = faceColor def figureKeyEvent(event): if event.key == vv.KEY_DELETE: m = event.owner.underMouse if hasattr(m, 'faceColor'): m.Destroy() graph.remove_nodes_from(clusters[m.index]) # Visualize a = vv.gca() fig = a.GetFigure() for i, bm in enumerate(meshes): m = vv.mesh(bm) m.faceColor = faceColor m.eventEnter.Bind(meshEnterEvent) m.eventLeave.Bind(meshLeaveEvent) m.hitTest = True m.index = i # Bind event handlers to figure fig.eventKeyDown.Bind(figureKeyEvent) a.SetLimits() a.bgcolor = 'k' a.axis.axisColor = 'w' a.axis.visible = axVis a.daspect = 1, 1, -1 # Prevent the callback functions from going out of scope a._callbacks = meshEnterEvent, meshLeaveEvent, figureKeyEvent # Done return axes return a
selections = {'gyroid': gyroid, 'schwarz_p': schwarz_p, 'schwarz_d': schwarz_d} mm = [50, 50, 50] n = 100 a = 10 x = np.linspace(0, mm[0], n) y = np.linspace(0, mm[1], n) z = np.linspace(0, mm[2], n) X, Y, Z = np.meshgrid(x, y, z) function_values = selections['schwarz_p'](X / a, Y / a, Z / a) #Use marching cubes to obtain the surface mesh of the ellipsoids verts, faces, normals, values = measure.marching_cubes_lewiner( function_values, 0) for i, v in enumerate(mm): verts[:, i] *= (v / n) #Fancy indexing: 'verts[faces]' to generate a collection of triangles vv.mesh(np.fliplr(verts), faces, normals, values) vv.use().Run() # # Create the mesh # gyr_mesh = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype)) # for i, f in enumerate(faces): # for j in range(3): # gyr_mesh.vectors[i][j] = verts[f[j],:] # gyr_mesh.save('gyroid_stl.stl')
isovalue = 0.0 # vol = np.empty((n,n,n), 'float32') for iz in range(vol.shape[0]): for iy in range(vol.shape[1]): for ix in range(vol.shape[2]): z, y, x = float(iz)*a+b, float(iy)*a+b, float(ix)*a+b vol[iz,iy,ix] = ( ( (8*x)**2 + (8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) * ( (8*x)**2 + (8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) - 64 * ( (8*x)**2 + (8*y-2)**2 ) ) * ( ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) * ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) - 64 * ( ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 ) ) + 1025 # Uncommenting the line below will yield different results for classic MC #vol = -vol # Get surface meshes bm1 = isosurface(vol, isovalue, 1, useClassic=True) t0 = time.time() bm2 = isosurface(vol, isovalue, 1) print('finding surface took %1.0f ms' % (1000*(time.time()-t0)) ) # Show vv.figure(1); vv.clf() vv.subplot(121); vv.imshow(im); vv.plot(pp, ls='+', lc='r', lw=2) a1=vv.subplot(222); m1=vv.mesh(bm1) #t=vv.volshow(vol) a2=vv.subplot(224); m2=vv.mesh(bm2) a1.camera = a2.camera
#!/usr/bin/env python """ This example illustrates how to create an isosurface from a volume and display it. This code relies on scikit-image. """ import visvis as vv vol = vv.volread('stent') # a standard visvis volume mesh = vv.isosurface(vol) # returns a visvis BaseMesh object vv.figure(1) vv.clf() vv.volshow2(vol) m = vv.mesh(mesh) m.faceColor = (0, 1, 1) vv.title('Isosurface') app = vv.use() app.Run()
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
) * ( ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) * ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) - 64 * ( ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 ) ) + 1025 # Uncommenting the line below will yield different results for classic MC #vol = -vol elif SELECT == 4: vol = ellipsoid(4, 3, 2, levelset=True) isovalue = 0 # Get surface meshes t0 = time.time() vertices1, faces1, _ = marching_cubes_lewiner(vol, isovalue, gradient_direction=gradient_dir, use_classic=False) print('finding surface lewiner took %1.0f ms' % (1000*(time.time()-t0)) ) t0 = time.time() vertices2, faces2, _ = marching_cubes_classic(vol, isovalue, gradient_direction=gradient_dir) print('finding surface classic took %1.0f ms' % (1000*(time.time()-t0)) ) # Show vv.figure(1); vv.clf() a1 = vv.subplot(121); m1 = vv.mesh(np.fliplr(vertices1), faces1) a2 = vv.subplot(122); m2 = vv.mesh(np.fliplr(vertices2), faces2) a1.camera = a2.camera # visvis uses right-hand rule, gradient_direction param uses left-hand rule m1.cullFaces = m2.cullFaces = 'front' # None, front or back vv.use().Run()
Parameters ---------- vol : 3D numpy array The volume for which to calculate the isosurface. isovalue : float The value at which the surface should be created. If not given or None, the average of the min and max of vol is used. step : int The stepsize for stepping through the volume. Larger steps yield faster but coarser results. The result shall always be topologically correct though. useClassic : bool If True, uses the classic marching cubes by Lorensen (1987) is used. This algorithm has many ambiguities and is not guaranteed to produce a topologically correct result. useValues : bool If True, the returned BaseMesh object will also have a value for each vertex, which is related to the maximum value in a local region near the isosurface. """ from visvis.utils.iso import isosurface as _isosurface return _isosurface(im, isovalue, step, useClassic, useValues) if __name__ == '__main__': vv.mesh(isosurface(vv.volread('stent')))
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)
if not os.path.isfile(fname): # try loading from the resource dir path = visvis.misc.getResourceDir() fname2 = os.path.join(path, fname) if os.path.isfile(fname2): fname = fname2 else: raise IOError("Mesh file '%s' does not exist." % fname) # Use file extension to read file if fname.lower().endswith('.stl'): readFunc = vv.io.stl.StlReader.read elif fname.lower().endswith('.obj'): readFunc = vv.io.wavefront.WavefrontReader.read elif fname.lower().endswith('.ssdf') or fname.lower().endswith('.bsdf'): readFunc = ssdfRead else: raise ValueError('meshRead cannot determine file type.') # Read return readFunc(fname, check) if __name__ == '__main__': bm = meshRead('bunny.ssdf') vv.figure(1); vv.clf() a = vv.subplot(121) m = vv.mesh(bm)
(8 * z)**2 + 16 - 1.85 * 1.85) - 64 * ((8 * x)**2 + (8 * y - 2)**2)) * ( ((8 * x)**2 + ((8 * y - 2) + 4) * ((8 * y - 2) + 4) + (8 * z)**2 + 16 - 1.85 * 1.85) * ((8 * x)**2 + ((8 * y - 2) + 4) * ((8 * y - 2) + 4) + (8 * z)**2 + 16 - 1.85 * 1.85) - 64 * (((8 * y - 2) + 4) * ((8 * y - 2) + 4) + (8 * z)**2)) + 1025 # Uncommenting the line below will yield different results for classic MC #vol = -vol # Get surface meshes bm1 = isosurface(vol, isovalue, 1, useClassic=True) t0 = time.time() bm2 = isosurface(vol, isovalue, 1) print('finding surface took %1.0f ms' % (1000 * (time.time() - t0))) # Show vv.figure(1) vv.clf() vv.subplot(121) vv.imshow(im) vv.plot(pp, ls='+', lc='r', lw=2) a1 = vv.subplot(222) m1 = vv.mesh(bm1) #t=vv.volshow(vol) a2 = vv.subplot(224) m2 = vv.mesh(bm2) a1.camera = a2.camera
elif SELECT == 4: vol = ellipsoid(4, 3, 2, levelset=True) isovalue = 0 # Get surface meshes t0 = time.time() vertices1, faces1, _, _ = marching_cubes_lewiner( vol, isovalue, gradient_direction=gradient_dir, use_classic=False) print('finding surface lewiner took %1.0f ms' % (1000 * (time.time() - t0))) t0 = time.time() vertices2, faces2 = marching_cubes_classic(vol, isovalue, gradient_direction=gradient_dir) print('finding surface classic took %1.0f ms' % (1000 * (time.time() - t0))) # Show vv.figure(1) vv.clf() a1 = vv.subplot(121) m1 = vv.mesh(np.fliplr(vertices1), faces1) a2 = vv.subplot(122) m2 = vv.mesh(np.fliplr(vertices2), faces2) a1.camera = a2.camera # visvis uses right-hand rule, gradient_direction param uses left-hand rule m1.cullFaces = m2.cullFaces = 'front' # None, front or back vv.use().Run()
def interactiveCenterlineID(s, ptcode, ctcode, basedir, cropname, modelname, radius=0.7, axVis=True, faceColor=(0.5, 1.0, 0.3), selectColor=(1.0, 0.3, 0.3)): """ showGraphAsMesh(graph, radius=0.7, faceColor=(0.5,1.0,0.3), selectColor=(1.0,0.3, 0.3) ) Manual identidy centerlines; s contains models. Show the given graphs as a mesh, or to be more precize as a set of meshes representing the centerlines in the struct. By holding the mouse over a mesh, it can be selected, after which it can be identified by pressing enter. Returns the axes in which the meshes are drawn and s2 with new named models. """ import visvis as vv import networkx as nx from stentseg.stentdirect import stentgraph from stentseg.stentdirect.stentgraph import create_mesh # from nellix._select_centerline_points import _Select_Centerline_Points import copy import numpy as np print("Move mouse over centerlines and press ENTER to identify") print( "Give either NelL, NelR, LRA, RRA, SMA for stents or vLRA, vRRA, vSMA for transition vessel-stent" ) print("Press ESCAPE to save ssdf and finish") # Get clusters of nodes from each centerline clusters = [] meshes = [] s2 = copy.copy(s) for key in s: if key.startswith('model'): clusters.append(s[key]) del s2[key] # Convert to mesh (this takes a while) bm = create_mesh(s[key], radius=radius, fullPaths=False) # Store meshes.append(bm) ppallcenterlines = [] ppendsall = [] for key2 in s: if key2.startswith('ppC'): # 'ppCenterline1' 2 .. ppallcenterlines.append(s[key2]) ppendsall.append(np.array( (s[key2][0, :], s[key2][-1, :]))) # first and last point cll # now remove from ssdf del s2[key2] ppallcenterlines = np.asarray(ppallcenterlines) centerlines = [None] * len(clusters) # Define callback functions def meshEnterEvent(event): event.owner.faceColor = selectColor def meshLeaveEvent(event): if event.owner.hitTest: # True event.owner.faceColor = faceColor else: event.owner.faceColor = 'b' def figureKeyEvent(event): if event.key == vv.KEY_ENTER: m = event.owner.underMouse if hasattr(m, 'faceColor'): m.faceColor = 'y' dialog_output = get_index_name() name = dialog_output model = clusters[m.index] # get pp corresponding to model ends = [] for n in sorted(model.nodes()): if model.degree(n) == 1: ends.append(n) if len(ends) > 2: raise RuntimeError( 'Centerline has more than 2 nodes with 1 neighbour') ends = np.asarray(ends, dtype='float32') # add selected cll to s2 if name in [ 'NelL', 'NelR', 'LRA', 'RRA', 'SMA', 'vLRA', 'vRRA', 'vSMA' ]: s2['model' + name] = model for i, ppend in enumerate( ppendsall): # pp for each centerline if ends[0] in ppend: # should not matter which end print('ppCenterline was added to s2') s2['ppCenterline' + name] = ppallcenterlines[i] m.hitTest = False else: print( "Name entered not known, give either NelL, NelR, LRA, RRA, SMA, 'vLRA', 'vRRA', 'vSMA'" ) if event.key == vv.KEY_ESCAPE: # Save ssdf filename = '%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, modelname + '_id') s3 = copy.deepcopy(s2) # do not change s2 for key in s3: if key.startswith('model'): s3[key] = s3[key].pack() vv.ssdf.save(os.path.join(basedir, ptcode, filename), s3) print("Finished, ssdf {} saved to disk".format(filename)) # fig.Destroy() # warning? # Visualize a = vv.gca() fig = a.GetFigure() for i, bm in enumerate(meshes): m = vv.mesh(bm) m.faceColor = faceColor m.eventEnter.Bind(meshEnterEvent) m.eventLeave.Bind(meshLeaveEvent) m.hitTest = True m.index = i # Bind event handlers to figure fig.eventKeyDown.Bind(figureKeyEvent) a.SetLimits() a.bgcolor = 'k' a.axis.axisColor = 'w' a.axis.visible = axVis a.daspect = 1, 1, -1 # Prevent the callback functions from going out of scope a._callbacks = meshEnterEvent, meshLeaveEvent, figureKeyEvent # Done return axes and s2 with new named centerlines return a, s2