def _onSelect(self, event): """ """ coordinates = np.asarray(label2worldcoordinates(self.label), dtype=np.float32) # x,y,z n = tuple(coordinates.flat) self.points.append(n) scale = 0.25 alpha = 1 # create object sphere for point view = self.ax.GetView() #todo: plot instead of solidShere? better vis? # graph.Draw(mc='r', mw = 10, lc='y') # point = vv.plot(point[0], point[1], point[2], # mc = 'm', ms = 'o', mw = 8, alpha=0.5) node_point = vv.solidSphere(translation=(n), scaling=(scale, scale, scale)) node_point.faceColor = (0, 1, 0, alpha) # 'g' but with alpha node_point.visible = True node_point.node = n node_point.nr = self.pointindex self.ax.SetView(view) # store self.graph.add_node(n, number=self.pointindex) self.nodepoints.append(node_point) # update index of total selected points self.pointindex += 1 self._updateTextIndex()
def create_node_points_with_amplitude(graph, scale=0.4, **kwargs): """ create node objects for gui and calculate motion amplitude for each node """ from stentseg.motion.displacement import _calculateAmplitude pointsDeforms = [] node_points = [] for i, node in enumerate(sorted(graph.nodes())): node_point = vv.solidSphere(translation=(node), scaling=(scale, scale, scale)) node_point.faceColor = (0, 0, 1, alpha) # 'b' but with alpha node_point.visible = False node_point.node = node node_point.nr = i nodeDeforms = graph.node[node]['deforms'] dmax_xyz = _calculateAmplitude(nodeDeforms, dim='xyz') # [dmax, p1, p2] dmax_z = _calculateAmplitude(nodeDeforms, dim='z') dmax_y = _calculateAmplitude(nodeDeforms, dim='y') dmax_x = _calculateAmplitude(nodeDeforms, dim='x') pointsDeforms.append(nodeDeforms) node_point.amplXYZ = dmax_xyz # amplitude xyz = [0] node_point.amplZ = dmax_z node_point.amplY = dmax_y node_point.amplX = dmax_x node_points.append(node_point) return node_points, pointsDeforms
def test_gui(self): pp = Pointset(3) pp.append(0, 0, 0) pp.append(0, 1, 0) pp.append(1, 2, 0) pp.append(0, 2, 1) # Create all solids vv.solidBox((0, 0, 0)) sphere = vv.solidSphere((3, 0, 0)) cone = vv.solidCone((6, 0, 0)) # a cone with 4 faces is a pyramid pyramid = vv.solidCone((9, 0, 0), N=4) vv.solidCylinder((0, 3, 0), (1, 1, 2)) ring = vv.solidRing((3, 3, 0)) vv.solidTeapot((6, 3, 0)) vv.solidLine(pp+Point(9, 3, 0), radius=0.2) # Make the ring green ring.faceColor = 'g' # Make the sphere dull sphere.specular = 0 sphere.diffuse = 0.4 # Show lines in yellow pyramid pyramid.faceColor = 'r' pyramid.edgeShading = 'plain' # Colormap example N = cone._vertices.shape[0] cone.SetValues(np.linspace(0, 1, N)) cone.colormap = vv.CM_JET
def __init__(self, xy, v): #global w """:param xy: Initial position, :param v: Initial velocity. """ # cast inputs as 2-d numpy arrays self.xy = xy.reshape((1,3)) #np.array(xy) self.v = v.reshape((1,3)) #np.array(v) # generate sphere data and colors. self.object = vv.solidSphere(vv.Point(self.xy), scaling=(0.05, 0.05, 0.05)) self.object.faceColor = [random(), random(), random()] self.trans = self.object.transformations[0]
def interactive_node_points(graph, scale=0.4, **kwargs): """ create node objects for gui """ node_points = [] for i, node in enumerate(sorted(graph.nodes())): node_point = vv.solidSphere(translation=(node), scaling=(scale, scale, scale)) node_point.faceColor = (0, 0, 1, alpha) # 'b' but with alpha node_point.visible = False node_point.node = node node_point.nr = i node_points.append(node_point) return node_points
def show(self): for projection_name in self.rsa_assessment.projection_list(): rsa_projection = self.rsa_assessment.projection(projection_name) # projection = self.assessment.projection(i) # projector = self.projectors[i] self.plot_image_data(rsa_projection.image, rsa_projection.t, sampling=0.1) for image_segment_name in rsa_projection.image_segment_list(): try: rsa_image_segment = rsa_projection.image_segment( image_segment_name) except NotImplementedError: continue for line in rsa_projection.segment_point_lines( rsa_image_segment): ps = vv.Pointset(3) ps.append(*list(line.a[:3])) ps.append(*list(line.b[:3])) vl = vv.solidLine(ps, radius=self.lineSize, N=self.lineN) vl.faceColor = self.lineColor for scene_segment_name in self.rsa_assessment.scene_segment_list(): try: scene_segment = self.rsa_assessment.scene_segment( scene_segment_name) except NotImplementedError: continue scene_segment.match_crossing_lines() for i in range(len(scene_segment.points)): vs = vv.solidSphere(translation=tuple( scene_segment.points[i][:3]), scaling=([self.pointSize] * 3), N=self.sphereN, M=self.sphereM) vs.faceColor = self.pointColor # Enter main loop app = vv.use() app.Run()
if axes is None: axes = vv.gca() # Create mesh m = vv.OrientableMesh(axes, vertices, indices, normals, texcords, 4) # if translation is not None: m.translation = translation if scaling is not None: m.scaling = scaling if direction is not None: m.direction = direction if rotation is not None: m.rotation = rotation # Adjust axes if axesAdjust: if axes.daspectAuto is None: axes.daspectAuto = False axes.cameraType = '3d' axes.SetLimits() # Done axes.Draw() return m if __name__ == '__main__': m = vv.solidSphere(scaling=(1, 1, 1.5), direction=(1, 1, 3)) m.SetTexture(vv.imread('lena.png'))
def view(mol, viewer='native'): '''Render the molecule The mayavi backend doesn't work under python 3. The native backend uses visvis to render the molecule. This is very slow. It's better to use the molecular viewer. Args: mol (molecule.Molecule): The molecule instance to render viewer: The backend to use. Valid choices are 'native', 'maya' and, 'avogadro' (default: native). Rturns: None ''' # mayavi if viewer == 'maya': from mayavi import mlab for atom in mol.atoms: pts = mlab.points3d(atom.r[0], atom.r[1], atom.r[2], scale_factor=0.75, scale_mode='none', resolution=20, color=atom.color()) for i, j in mol.bonds(): mlab.plot3d([mol.atoms[i].r[0], mol.atoms[j].r[0]], [mol.atoms[i].r[1], mol.atoms[j].r[1]], [mol.atoms[i].r[2], mol.atoms[j].r[2]], tube_radius=0.1, tube_sides=20) mlab.show() # avogadro if viewer == 'avogadro': from subprocess import call write_xyz(mol, 'avogadro.xyz') call(['avogadro', 'avogadro.xyz']) call(['rm', 'avogadro.xyz']) # visvis if viewer == 'native': import visvis as vv for atom in mol.atoms: x, y, z = atom.r at = vv.solidSphere((x, y, z), atom.radius()*0.25) at.faceColor = atom.color() for bond in mol.bonds(): pp = vv.Pointset(3) pp.append(bond.atoms[0].r) pp.append(bond.atoms[1].r) vv.solidLine(pp, radius=0.15, N=16) pp = vv.Pointset(3) pp.append([3, 3, 3]) pp.append([4, 3, 3]) x = vv.solidLine(pp, radius=0.05) x.faceColor = 'r' conex = vv.solidCone([4, 3, 3], scaling=[0.1, 0.1, 0.1], direction=[1, 0, 0]) conex.faceColor = 'r' pp = vv.Pointset(3) pp.append([3, 3, 3]) pp.append([3, 4, 3]) y = vv.solidLine(pp, radius=0.05) y.faceColor = 'g' coney = vv.solidCone([3, 4, 3], scaling=[0.1, 0.1, 0.1], direction=[0, 1, 0]) coney.faceColor = 'g' pp = vv.Pointset(3) pp.append([3, 3, 3]) pp.append([3, 3, 4]) z = vv.solidLine(pp, radius=0.05) z.faceColor = 'b' conez = vv.solidCone([3, 3, 4], scaling=[0.1, 0.1, 0.1], direction=[0, 0, 1]) conez.faceColor = 'b' # Set axes settings axes = vv.gca() axes.SetLimits(rangeX=(-5, 5), rangeY=(-5, 5), rangeZ=(-5, 5)) vv.axis('off') app = vv.use() app.Run()
""" import numpy as np import visvis as vv from visvis import Point, Pointset vv.figure() a = vv.gca() # Define points for the line pp = Pointset(3) pp.append(0,0,0); pp.append(0,1,0); pp.append(1,2,0); pp.append(0,2,1) # Create all solids box = vv.solidBox((0,0,0)) sphere = vv.solidSphere((3,0,0)) cone = vv.solidCone((6,0,0)) pyramid = vv.solidCone((9,0,0), N=4) # a cone with 4 faces is a pyramid cylinder = vv.solidCylinder((0,3,0),(1,1,2)) ring = vv.solidRing((3,3,0)) teapot = vv.solidTeapot((6,3,0)) line = vv.solidLine(pp+Point(9,3,0), radius = 0.2) # Let's put a face on that cylinder # This works because 2D texture coordinates are automatically generated for # the sphere, cone, cylinder and ring. im = vv.imread('lena.png') cylinder.SetTexture(im) # Make the ring green ring.faceColor = 'g'
vv.title('Dynamic model for patient %s at %s ' % (ptcode[7:], ctcode)) # viewringcrop = {'daspect': (1.0, 1.0, -1.0), 'azimuth': 32.9516129032258, # 'elevation': 14.162658990412158, 'roll': 0.0, # 'loc': (166.79323747325407, 162.4692971514962, 52.28745470591859), # 'fov': 0.0, 'zoom': 0.026156241036960133} # m = vv.mesh(modelmesh) # # m.faceColor = 'g' # m.clim = 0, 5 # m.colormap = vv.CM_JET # Add motion pointsDeforms = [] node_points = [] for i, node in enumerate(sorted(model.nodes())): node_point = vv.solidSphere(translation = (node), scaling = (0.8,0.8,0.8)) node_point.faceColor = 'b' node_point.visible = False node_point.node = node node_point.nr = i if meshWithColors: nodeDeforms = model.node[node]['deforms'] dmax_xyz = _calculateAmplitude(nodeDeforms, dim='xyz') # [dmax, p1, p2] dmax_z = _calculateAmplitude(nodeDeforms, dim='z') dmax_y = _calculateAmplitude(nodeDeforms, dim='y') dmax_x = _calculateAmplitude(nodeDeforms, dim='x') pointsDeforms.append(nodeDeforms) node_point.amplXYZ = dmax_xyz # amplitude xyz = [0] node_point.amplZ = dmax_z node_point.amplY = dmax_y node_point.amplX = dmax_x
def plot_reference_sphere(theta=0, phi=0, isometric=True, ax=None, azimuth=None, elevation=None, degrees=True, labels=True, light_ambient=.6, zoom=1.4, arrow_color=(.25, .95, .8), close_figure=False): if azimuth is None: azimuth = DEFAULT_AZIMUTH if elevation is None: elevation = DEFAULT_ELEVATION import visvis as vv if ax is None: app = vv.use() fig = vv.figure() ax = vv.subplot(111) else: app = None fig = ax.GetFigure() ax.axis.visible = 0 ax.axis.xLabel = 'x' ax.axis.yLabel = 'y' ax.axis.zLabel = 'z' # coordinate system length = 1.4 cyl_diameter = .05 for i in range(3): direction = np.zeros((3, )) direction[i] = 1 cyl = vv.solidCylinder(translation=(0, 0, 0), scaling=(cyl_diameter, cyl_diameter, length), direction=tuple(direction), axesAdjust=False, axes=ax) cyl.faceColor = (.75, .75, .75) translation = np.zeros((3, )) translation[i] = length cone = vv.solidCone(translation=tuple(translation), scaling=(.1, .1, .2), direction=tuple(direction), axesAdjust=False, axes=ax) cone.faceColor = (.75, .75, .75) # example direction length = 1 shrink = .825 direction = sph2cart(1, theta, phi, degrees=degrees).ravel() cyl = vv.solidCylinder(translation=(0, 0, 0), scaling=(.05, .05, shrink * length), direction=tuple(direction), axesAdjust=False, axes=ax) cyl.faceColor = arrow_color translation = direction * shrink cone = vv.solidCone(translation=tuple(translation), scaling=(.1, .1, .2), direction=tuple(direction), axesAdjust=False, axes=ax) cone.faceColor = arrow_color # indicate unit sphere sphere = vv.solidSphere((0, 0, 0), N=100, M=100) sphere.faceColor = (.5, .5, .5, .25) # some lines on sphere indicating main axes phi = np.linspace(0, 2 * np.pi, 100) theta = np.ones_like(phi) * np.pi / 2. r = np.ones_like(phi) xyz = sph2cart(r, theta, phi, degrees=False) vv.plot(xyz[:, 0], xyz[:, 1], xyz[:, 2], lw=1, lc=(.5, .5, .5), ls="-", mc='b', axesAdjust=False, axes=ax) theta = np.linspace(-np.pi, np.pi, 100) phi = np.ones_like(theta) * 0 r = np.ones_like(phi) xyz = sph2cart(r, theta, phi, degrees=False) vv.plot(xyz[:, 0], xyz[:, 1], xyz[:, 2], lw=1, lc=(.5, .5, .5), ls="-", mc='b', axesAdjust=False, axes=ax) theta = np.linspace(-np.pi, np.pi, 100) phi = np.ones_like(theta) * np.pi / 2. r = np.ones_like(phi) xyz = sph2cart(r, theta, phi, degrees=False) vv.plot(xyz[:, 0], xyz[:, 1], xyz[:, 2], lw=1, lc=(.5, .5, .5), ls="-", mc='b', axesAdjust=False, axes=ax) # add pitch and roll axes aa = np.deg2rad(np.linspace(45, 315, 100) - 90) r = .25 + .025 d = 1.25 + .05 color = (.25, .25, .25) # pitch rotation (in x/z plane, i.e. around y-axis) xx = r * np.cos(aa) zz = r * np.sin(aa) yy = d * np.ones_like(xx) vv.plot(xx, yy, zz, lw=5, lc=color, ls="-", axesAdjust=False, axes=ax) translation = (xx[0], yy[0], zz[0]) direction = (xx[0] - xx[1], yy[0] - yy[1], zz[0] - zz[1]) cone = vv.solidCone(translation=translation, scaling=(.05, .05, .1), direction=direction, axesAdjust=False, axes=ax) cone.faceColor = color if labels: vv.Text(ax, 'Pitch', x=0, y=1.25 * d, z=.25, fontSize=28, color=color) # roll rotation (in y/z plane, i.e. around x-axis) yy = r * np.cos(aa) zz = r * np.sin(aa) xx = d * np.ones_like(xx) vv.plot(xx, yy, zz, lw=5, lc=color, ls="-", axesAdjust=False, axes=ax) translation = (xx[-1], yy[-1], zz[-1]) direction = (xx[-1] - xx[-2], yy[-1] - yy[-2], zz[-1] - zz[-2]) cone = vv.solidCone(translation=translation, scaling=(.05, .05, .1), direction=direction, axesAdjust=False, axes=ax) cone.faceColor = color if labels: vv.Text(ax, 'Roll', x=1.25 * d, y=-.8, z=0, fontSize=28, color=color) # set camera view zoom_ = vv.view()['zoom'] if isometric: vv.view(dict(azimuth=90 + ISO_AZIMUTH, elevation=ISO_ELEVATION), zoom=zoom * zoom_, axes=ax) else: vv.view(dict(azimuth=90 + azimuth, elevation=elevation), zoom=zoom * zoom_, _axes=ax) ax.light0.ambient = light_ambient ax.light0.specular = .5 fig.DrawNow() if app is not None: app.ProcessEvents() img = vv.screenshot(None, ob=ax, sf=2, bg=None, format=None) if close_figure: vv.close(fig) fig = None return fig, img
# light0 is always on, and is attached to the camera shining straight ahead a = vv.gca() a.light0.ambient = 0.2 # 0.2 is default for light 0 a.light0.diffuse = 1.0 # 1.0 is default # The other lights are off by default and are positioned at the origin light1 = a.lights[1] light1.On() light1.ambient = 0.0 # 0.0 is default for other lights light1.color = (1, 0, 0) # this light is red # Create spheres for i in range(len(shading)): for j in range(ndiffuse): s = vv.solidSphere((i, j, 0), (0.3, 0.3, 0.3)) s.faceShading, s.edgeShading = shading[i] s.faceColor = (0.8, 0.8, 1.0) s.edgeColor = (0.8, 0.8, 1.0) s.diffuse = float(j) / ndiffuse # Set settings for axes a = vv.gca() a.axis.xTicks = [str(x) for x in shading] a.axis.xLabel = 'face- and edgeshading' a.axis.yTicks = [str(float(j) / ndiffuse) for j in range(ndiffuse)] a.axis.yLabel = 'diffuse reflection' # Set back bg a.bgcolor = 'k' a.axis.axisColor = 'w'
def plot3d(self, img, bodies={ 'pose3d': np.empty((0, 13, 3)), 'pose2d': np.empty((0, 13, 2)) }, hands={ 'pose3d': np.empty((0, 21, 3)), 'pose2d': np.empty((0, 21, 2)) }, faces={ 'pose3d': np.empty((0, 84, 3)), 'pose2d': np.empty((0, 84, 2)) }, body_with_wrists=[], body_with_head=[], interactive=False): """ :param img: a HxWx3 numpy array :param bodies: dictionnaroes with 'pose3d' (resp 'pose2d') with the body 3D (resp 2D) pose :param faces: same with face pose :param hands: same with hand pose :param body_with_wrists: list with for each body, a tuple (left_hand_id, right_hand_id) of the index of the hand detection attached to this body detection (-1 if none) for left and right hands :parma body_with_head: list with for each body, the index of the face detection attached to this body detection (-1 if none) :param interactive: whether to open the viewer in an interactive manner or not """ # body pose do not use the same coordinate systems bodies['pose3d'][:, :, 0] *= -1 bodies['pose3d'][:, :, 1] *= -1 # Compute 3D scaled representation of each part, stored in "points3d" hands, bodies, faces = [copy.copy(s) for s in (hands, bodies, faces)] parts = (hands, bodies, faces) for part in parts: part['points3d'] = np.zeros_like(part['pose3d']) for part_idx in range(len(part['pose3d'])): points3d = scale_orthographic(part['pose3d'][part_idx], part['pose2d'][part_idx]) part['points3d'][part_idx] = points3d # Various display tricks to make the 3D visualization of full-body nice # (1) for faces, add a Z offset to faces to align them with the body for body_id, face_id in enumerate(body_with_head): if face_id != -1: z_offset = bodies['points3d'][body_id, 12, 2] - np.mean( faces['points3d'][face_id, :, 2]) faces['points3d'][face_id, :, 2] += z_offset # (2) for hands, add a 3D offset to put them at the wrist location for body_id, (lwrist_id, rwrist_id) in enumerate(body_with_wrists): if lwrist_id != -1: hands['points3d'][lwrist_id, :, :] = bodies['points3d'][ body_id, 7, :] - hands['points3d'][lwrist_id, 0, :] if rwrist_id != -1: hands['points3d'][rwrist_id, :, :] = bodies['points3d'][ body_id, 6, :] - hands['points3d'][rwrist_id, 0, :] img = np.asarray(img) height, width = img.shape[:2] fig = vv.figure(1) fig.Clear() fig._SetPosition(0, 0, self.figsize[0], self.figsize[1]) if not interactive: fig._enableUserInteraction = False axes = vv.gca() # Hide axis axes.axis.visible = False scaling_factor = 1.0 / height # Camera interaction is not intuitive along z axis # We reference every object to a parent frame that is rotated to circumvent the issue ref_frame = vv.Wobject(axes) ref_frame.transformations.append(vv.Transform_Rotate(-90, 1, 0, 0)) ref_frame.transformations.append( vv.Transform_Translate(-0.5 * width * scaling_factor, -0.5, 0)) # Draw image if self.display2d: # Display pose in 2D img = visu.visualize_bodyhandface2d(img, dict_poses2d={ 'body': bodies['pose2d'], 'hand': hands['pose2d'], 'face': faces['pose2d'] }, lw=2, max_padding=0, bgr=False) XX, YY = np.meshgrid([0, width * scaling_factor], [0, 1]) img_z_offset = 0.5 ZZ = img_z_offset * np.ones(XX.shape) # Draw image embedded_img = vv.surf(XX, YY, ZZ, img) embedded_img.parent = ref_frame embedded_img.ambientAndDiffuse = 1.0 # Draw a grid on the bottom floor to get a sense of depth XX, ZZ = np.meshgrid( np.linspace(0, width * scaling_factor, 10), img_z_offset - np.linspace(0, width * scaling_factor, 10)) YY = np.ones_like(XX) grid3d = vv.surf(XX, YY, ZZ) grid3d.parent = ref_frame grid3d.edgeColor = (0.1, 0.1, 0.1, 1.0) grid3d.edgeShading = 'plain' grid3d.faceShading = None # Draw pose for part in parts: for part_idx in range(len(part['points3d'])): points3d = part['points3d'][part_idx] * scaling_factor # Draw bones J = len(points3d) is_body = (J == 13) ignore_neck = False if not is_body else body_with_head[ part_idx] != -1 bones, bonecolors, pltcolors = visu._get_bones_and_colors( J, ignore_neck=ignore_neck) for (kpt_id1, kpt_id2), color in zip(bones, bonecolors): color = color[2], color[1], color[0] # BGR vs RGB p1 = visu._get_xyz(points3d, kpt_id1) p2 = visu._get_xyz(points3d, kpt_id2) pointset = vv.Pointset(3) pointset.append(p1) pointset.append(p2) # Draw bones as solid capsules bone_radius = 0.005 line = vv.solidLine(pointset, radius=bone_radius) line.faceColor = color line.ambientAndDiffuse = 1.0 line.parent = ref_frame # Draw keypoints, except for faces if J != 84: keypoints_to_plot = points3d if ignore_neck: # for a nicer display, ignore head keypoint keypoints_to_plot = keypoints_to_plot[:12, :] # Use solid spheres for i in range(len(keypoints_to_plot)): kpt_wobject = vv.solidSphere( translation=keypoints_to_plot[i, :].tolist(), scaling=1.5 * bone_radius) kpt_wobject.faceColor = (255, 0, 0) kpt_wobject.ambientAndDiffuse = 1.0 kpt_wobject.parent = ref_frame # Use just an ambient lighting axes.light0.ambient = 0.8 axes.light0.diffuse = 0.2 axes.light0.specular = 0.0 cam = vv.cameras.ThreeDCamera() axes.camera = cam #z axis cam.azimuth = -45 cam.elevation = 20 cam.roll = 0 # Orthographic camera cam.fov = 0 if self.camera_zoom is None: cam.zoom *= 1.3 # Zoom a bit more else: cam.zoom = self.camera_zoom if self.camera_location is not None: cam.loc = self.camera_location cam.SetView() if interactive: self.app.Run() else: fig._widget.update() self.app.ProcessEvents() img3d = vv.getframe(vv.gcf()) img3d = np.clip(img3d * 255, 0, 255).astype(np.uint8) # Crop gray borders img3d = img3d[10:-10, 10:-10, :] return img3d, img
if axes is None: axes = vv.gca() # Create mesh m = vv.OrientableMesh(axes, vertices, indices, normals, texcords, 4) # if translation is not None: m.translation = translation if scaling is not None: m.scaling = scaling if direction is not None: m.direction = direction if rotation is not None: m.rotation = rotation # Adjust axes if axesAdjust: if axes.daspectAuto is None: axes.daspectAuto = False axes.cameraType = '3d' axes.SetLimits() # Done axes.Draw() return m if __name__ == '__main__': m = vv.solidSphere(scaling=(1,1,1.5), direction=(1,1,3)) m.SetTexture( vv.imread('lena.png') )
#!/usr/bin/env python """ This example shows a ball that bounces on a surface and has two balls rotating around it. It illustrates the use of timers and how object hierarchy can be used to build (and move) complex models consisting of multiple simple objects. """ import visvis as vv # Create floor floor = vv.solidBox((0,0,-1.5), (6,6,1)) # Create hierachy objects sun = vv.solidSphere() earth = vv.solidSphere((2,0,0),(0.3,0.3,0.2)) moon = vv.solidSphere((2,0,0),scaling=(0.2, 0.2, 0.3)) moon.parent = earth earth.parent = sun # Add transformations sunTrans = sun.transformations[0] earthRot = vv.Transform_Rotate(20) moonRot = vv.Transform_Rotate(20) earth.transformations.insert(0,earthRot) moon.transformations.insert(0,moonRot) # Set appearance earth.faceColor = 'b' moon.faceColor = 'y' sun.faceColor = 'r'
# light0 is always on, and is attached to the camera shining straight ahead a = vv.gca() a.light0.ambient = 0.2 # 0.2 is default for light 0 a.light0.diffuse = 1.0 # 1.0 is default # The other lights are off by default and are positioned at the origin light1 = a.lights[1] light1.On() light1.ambient = 0.0 # 0.0 is default for other lights light1.color = (1,0,0) # this light is red # Create spheres for i in range(len(shading)): for j in range(ndiffuse): s = vv.solidSphere((i,j,0), (0.3, 0.3, 0.3)) s.faceShading, s.edgeShading = shading[i] s.faceColor = (0.8,0.8,1.0) s.edgeColor = (0.8,0.8,1.0) s.diffuse = float(j)/ndiffuse # Set settings for axes a = vv.gca() a.axis.xTicks = [str(s) for s in shading] a.axis.xLabel = 'face- and edgeshading' a.axis.yTicks = [str(float(j)/ndiffuse) for j in range(ndiffuse)] a.axis.yLabel = 'diffuse reflection' # Set back bg a.bgcolor = 'k' a.axis.axisColor = 'w'
#!/usr/bin/env python """ This example shows a ball that bounces on a surface and has two balls rotating around it. It illustrates the use of timers and how object hierarchy can be used to build (and move) complex models consisting of multiple simple objects. """ import visvis as vv # Create floor floor = vv.solidBox((0, 0, -1.5), (6, 6, 1)) # Create hierachy objects sun = vv.solidSphere() earth = vv.solidSphere((2, 0, 0), (0.3, 0.3, 0.2)) moon = vv.solidSphere((2, 0, 0), scaling=(0.2, 0.2, 0.3)) moon.parent = earth earth.parent = sun # Add transformations sunTrans = sun.transformations[0] earthRot = vv.Transform_Rotate(20) moonRot = vv.Transform_Rotate(20) earth.transformations.insert(0, earthRot) moon.transformations.insert(0, moonRot) # Set appearance earth.faceColor = 'b' moon.faceColor = 'y' sun.faceColor = 'r'
""" import numpy as np import visvis as vv from visvis import Point, Pointset vv.figure() a = vv.gca() # Define points for the line pp = Pointset(3) pp.append(0,0,0); pp.append(0,1,0); pp.append(1,2,0); pp.append(0,2,1) # Create all solids box = vv.solidBox((0,0,0)) sphere = vv.solidSphere((3,0,0)) cone = vv.solidCone((6,0,0)) pyramid = vv.solidCone((9,0,0), N=4) # a cone with 4 faces is a pyramid cylinder = vv.solidCylinder((0,3,0),(1,1,2)) ring = vv.solidRing((3,3,0)) teapot = vv.solidTeapot((6,3,0)) line = vv.solidLine(pp+Point(9,3,0), radius = 0.2) # Let's put a face on that cylinder # This works because 2D texture coordinates are automatically generated for # the sphere, cone, cylinder and ring. im = vv.imread('astronaut.png') cylinder.SetTexture(im) # Make the ring green ring.faceColor = 'g'
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)