def test_calculate_normals(): import visvis as vv pp = vv.Pointset(3) pp.append((1, 2, 3)) pp.append((3, 1, 5)) pp.append((4, 4, 7)) pp.append((6, 7, 9)) m = vv.BaseMesh(pp, faces=[0, 1, 2, 0, 2, 3]) assert m._normals is None vv.processing.calculateNormals(m) normals1 = m._normals assert m._normals is not None assert m._normals.shape == (4, 3) vv.processing.calculateFlatNormals(m) normals2 = m._normals assert m._normals is not None assert m._normals.shape == (6, 3) assert normals1 is not normals2 assert normals1.shape != normals2.shape # because faces have been unwound
def isocontour(im, isovalue=None): """ isocontour(im, isovalue=None) Calculate the iso contours for the given 2D image. If isovalue is not given or None, a value between the min and max of the image is used. Returns a pointset in which each two subsequent points form a line piece. This van be best visualized using "vv.plot(result, ls='+')". """ # Check image if not isinstance(im, np.ndarray) or (im.ndim != 2): raise ValueError('im should be a 2D numpy array.') # Make sure its 32 bit float # todo: also allow bool and uint8 ? if im.dtype != np.float32: im = im.astype('float32') # Get isovalue if isovalue is None: isovalue = 0.5 * (im.min() + im.max()) isovalue = float(isovalue) # Will raise error if not float-like value given # Do the magic! data = marchingsquares_.marching_squares(im, isovalue, CONTOUR_CASES, EDGETORELATIVEPOSX, EDGETORELATIVEPOSY) # Return as pointset return vv.Pointset(data)
def arrows(points, vectors, head=(0.2, 1.0), **kwargs): if 'ls' in kwargs: raise ValueError('Cannot set line style for arrows.') ppd = vv.Pointset(pp.ndim) for i in range(len(points)): p1 = points[i] # source point v1 = vectors[i] # THE vector v1_norm = v1.norm() p2 = p1 + v1 # destination point if v1_norm: pn = v1.normal() * v1_norm * abs(head[0]) # normal vector else: pn = vv.Point(0, 0) ph1 = p1 + v1 * head[1] ph2 = ph1 - v1 * head[0] # Add stick ppd.append(p1) ppd.append(p2) # Add arrowhead ppd.append(ph1) ppd.append(ph2 + pn) ppd.append(ph1) ppd.append(ph2 - pn) return vv.plot(ppd, ls='+', **kwargs)
def __init__(self): # Create figure and axes vv.figure() self._a = a = vv.gca() vv.title("Hold mouse to draw lines. Use 'rgbcmyk' and '1-9' keys.") # Set axes a.SetLimits((0,1), (0,1)) a.cameraType = '2d' a.daspectAuto = False a.axis.showGrid = True # Init variables needed during drawing self._active = None self._pp = Pointset(2) # Create null and empty line objects self._line1 = None self._line2 = vv.plot(vv.Pointset(2), ls='+', lc='c', lw='2', axes=a) # Bind to events a.eventMouseDown.Bind(self.OnDown) a.eventMouseUp.Bind(self.OnUp) a.eventMotion.Bind(self.OnMotion) a.eventKeyDown.Bind(self.OnKey)
def _visualise_world_visvis(X, Y, Z, format="surf"): """ Legacy function to produce a surface render using visvis :param X: :param Y: :param Z: :param format: """ import visvis as vv # m2 = vv.surf(worldx[::detail], worldy[::detail], worldz[::detail]) app = vv.use() # prepare axes a = vv.gca() a.cameraType = '3d' a.daspectAuto = False # print("view", a.camera.GetViewParams()) # a.SetView(loc=(-1000,0,0)) # a.camera.SetView(None, loc=(-1000,0,0)) if format == "surf": l = vv.surf(X, Y, Z) a.SetLimits(rangeX=(-0.2, 0.2), rangeY=(-0.5, 0.5), rangeZ=(-0.5, 0), margin=0.02) else: # draw points pp = vv.Pointset( np.concatenate([X.flatten(), Y.flatten(), Z.flatten()], axis=0).reshape((-1, 3))) l = vv.plot(pp, ms='.', mc='r', mw='5', ls='', mew=0) l.alpha = 0.2 app.Run()
def calculateMotion(self, I): """ Given a mesh and the indices of vertices in the mesh, calculates the motion of all vertices. Returns a list of pointsets that contain the motion vectors. """ deltas = [] for delta in self._mverticesDeltas: dd = vv.Pointset(delta[I,:]) deltas.append(dd) return deltas
def test_line2mesh(): import visvis as vv pp = vv.Pointset(3) pp.append((1, 2, 3)) pp.append((3, 1, 5)) pp.append((4, 4, 7)) pp.append((6, 7, 9)) m = vv.processing.lineToMesh(pp, 3, 10) assert isinstance(m, vv.BaseMesh)
def _CalculateDonut(self, N=32, M=32, thickness=0.2): # Quick access pi2 = np.pi*2 cos = np.cos sin = np.sin sl = M+1 # Calculate vertices, normals and texcords vertices = vv.Pointset(3) normals = vv.Pointset(3) texcords = vv.Pointset(2) # Cone for n in range(N+1): v = float(n)/N a = pi2 * v # Obtain outer and center position of "tube" po = vv.Point(sin(a), cos(a), 0) pc = po * (1.0-0.5*thickness) # Create two vectors that span the the circle orthogonal to the tube p1 = (pc-po) p2 = vv.Point(0, 0, 0.5*thickness) # Sample around tube for m in range(M+1): u = float(m) / (M) b = pi2 * (u) dp = cos(b) * p1 + sin(b) * p2 vertices.append(pc+dp) normals.append(dp.normalize()) texcords.append(v,u) # Calculate indices indices = [] for j in range(N): for i in range(M): indices.extend([(j+1)*sl+i, (j+1)*sl+i+1, j*sl+i+1, j*sl+i]) # Make indices a numpy array indices = np.array(indices, dtype=np.uint32) return vertices, indices, normals, texcords
def _convertQuadsToTriangles(cls, mesh): """ STL only allows triangles, therefore we need a method to convert triangles to quads. """ if mesh._faces is not None: faces = mesh._GetFaces() vertices = mesh._vertices vv1 = vertices[faces[:, 0]] vv2 = vertices[faces[:, 1]] vv3 = vertices[faces[:, 2]] vv4 = vertices[faces[:, 3]] else: vv1 = mesh._vertices[0::4] vv2 = mesh._vertices[1::4] vv3 = mesh._vertices[2::4] vv4 = mesh._vertices[3::4] tri1 = vv.Pointset(vv1) tri2 = vv.Pointset(vv2) tri3 = vv.Pointset(vv3) # tri1.extend(vv.Pointset(vv3)) tri2.extend(vv.Pointset(vv4)) tri3.extend(vv.Pointset(vv1)) return tri1, tri2, tri3
def performMeasurements(self, z, quick=False): # Get points that are near the given z I1 = self.getIndicesNearZ(z, quick=quick) # Get contour I2 = self.getStentContourAtZ(z, I1) # Store self._I1, self._I2 = I1, I2 # Make points and calculate centre and radius pp = vv.Pointset(self._mvertices[I2,:]) pp2 = vv.Pointset(pp.data[:,:2]) c = fit_cirlce(pp2) # Show contour if self._line is None: self._line = vv.plot(pp, lw=4, mw=8, ms='.', axesAdjust=False, axes=self.GetAxes()) else: self._line.SetPoints(pp) # Translate the donut self.translation = c.x, c.y, z self.scaling = c.r*2.0, c.r*2.0, c.r*4.0 # Calculate motion if not quick: motions = self.calculateMotion(I2) minArea, maxArea, minCirc, maxCirc = self.calculatePulsation(pp, motions) distalMotion = self.calculateDistalMotion(pp, motions) motionMag = self.calculateMotionMagnitude(pp, motions) aMax, a75, a95 = self.calculateAngleChanges(I2) print('=== Ring measurements ===') print('Area change: %1.1f%%' % (100*maxArea/minArea)) #print('Circumference change: %1.1f%%' % (100*maxCirc/minCirc)) print('Distal motion: %1.2f mm' % distalMotion) print('Motion magnitude: %1.2f mm' % motionMag) print('Angular change: %1.2f / %1.2f / %1.2f degrees' % (aMax, a75, a95))
def onClick(event): if event.button == 2 and vv.KEY_SHIFT in event.modifiers: # Get clicked location in NDC w, h = event.owner.position.size x, y = 2 * event.x / w - 1, -2 * event.y / h + 1 # Apply inverse camera transform to get two points on the clicked line M = np.linalg.inv(get_camera_matrix(event.owner)) p1 = vv.Point(np.dot((x, y, -100, 1), M)[:3]) p2 = vv.Point(np.dot((x, y, +100, 1), M)[:3]) # Calculate center point and vector pm = 0.5 * (p1 + p2) vec = (p2 - p1).normalize() # Prepare for searching in two directions pp = [pm - vec, pm + vec] status = 0 if sample(vol, pm) is None else 1 status = [status, status] hit = None max_sample = -999999 step = min(vol.sampling) # Look in two directions simulaneously, search for volume, collect samples for i in range(10000): # Safe while-loop for j in (0, 1): if status[j] < 2: s = sample(vol, pp[j]) inside = s is not None if inside: if s > max_sample: max_sample, hit = s, pp[j] if status[j] == 0: status[j] = 1 status[ not j] = 2 # stop looking in other direction else: if status[j] == 1: status[j] = 2 pp[j] += (j * 2 - 1) * step * vec if status[0] == 2 and status[1] == 2: break else: print('Warning: ray casting to collect samples did not stop' ) # clicking outside the volume # Draw pp2 = vv.Pointset(3) text = 'No point inside volume selected.' if hit: pp2.append(hit) ii = vol.point_to_index(hit) text = 'At z=%1.1f, y=%1.1f, x=%1.1f -> X[%i, %i, %i] -> %1.2f' % ( hit.z, hit.y, hit.x, ii[0], ii[1], ii[2], max_sample) line.SetPoints(pp2) label.text = text return True # prevent default mouse action
def read(cls, fname, check=False): """ read(fname, check=False) This classmethod is the entry point for reading STL files. Parameters ---------- fname : string The name of the file to read. check : bool If check is True and the file is in ascii, some checks to the integrity of the file are done (which is a bit slower). """ # Open file f = open(fname, 'rb') try: # Read whitespace while not f.read(1).strip(): pass # Go one back f.seek(-1, 1) # Determine ascii or binary data = f.read(5).decode('ascii', 'ignore') if data == 'solid': # Pop rest of line (i.e. the name) and get reader object f.readline() reader = StlAsciiReader(f) else: # Pop rest if header (header has 80 chars) and get reader object f.read(75) reader = StlBinReader(f) # Read all vertices = vv.Pointset(3) while True: reader.readFace(vertices, check) except EOFError: pass finally: f.close() # Done return vv.BaseMesh(vertices)
def test_combine_meshes(): import visvis as vv pp = vv.Pointset(3) pp.append((1, 2, 3)) pp.append((3, 1, 5)) pp.append((4, 4, 7)) pp.append((6, 7, 9)) m = vv.BaseMesh(pp, faces=[0, 1, 2, 0, 2, 3]) assert m._vertices.shape == (4, 3) m2 = vv.processing.combineMeshes([m, m, m]) assert m2 is not m assert m2._vertices.shape == (12, 3)
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 calculateMotionMagnitude(self, contour, deltas): """ Calculate the mean motion magnitude (i.e. amplitude in principal direction). """ # Init a list that contains the mean z-position for each time unit # Note that this is a relative z-position, but that doesnt matter meanPositions = vv.Pointset(3) # delta is a pointset, there is such a pointsets for each time unit for delta in deltas: meanPosition = vv.Point(0,0,0) for p in delta: meanPosition += p meanPosition *= 1.0 / len(delta) meanPositions.append(meanPosition) return self._calculateMagnitude(meanPositions)
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()
def test_unwindfaces(): import visvis as vv pp = vv.Pointset(3) pp.append((1, 2, 3)) pp.append((3, 1, 5)) pp.append((4, 4, 7)) pp.append((6, 7, 9)) m = vv.BaseMesh(pp, faces=[0, 1, 2, 0, 2, 3]) assert m._faces is not None assert m._vertices.shape == (4, 3) vv.processing.unwindFaces(m) assert m._faces is None assert m._vertices.shape == (6, 3) assert tuple(m._vertices[0]) == tuple(pp[0]) assert tuple(m._vertices[1]) == tuple(pp[1]) assert tuple(m._vertices[2]) == tuple(pp[2]) assert tuple(m._vertices[3]) == tuple(pp[0]) assert tuple(m._vertices[4]) == tuple(pp[2]) assert tuple(m._vertices[5]) == tuple(pp[3])
def isocontour(im, isovalue=None): """ isocontour(im, isovalue=None) Uses scikit-image to calculate the iso contours for the given 2D image. If isovalue is not given or None, a value between the min and max of the image is used. Returns a pointset in which each two subsequent points form a line piece. This van be best visualized using "vv.plot(result, ls='+')". """ # Check image if not isinstance(im, np.ndarray) or (im.ndim != 2): raise ValueError('im should be a 2D numpy array.') # Get isovalue if isovalue is None: isovalue = 0.5 * (im.min() + im.max()) isovalue = float( isovalue) # Will raise error if not float-like value given # Get the contours data = find_contours(im, isovalue) # Build the contour as we used to return it. It is less rich, but easier # to visualize. data2 = [] for contour in data: n = contour.shape[0] * 2 - 2 contour2 = np.empty((n, 2), np.float32) contour2[0::2] = contour[:-1] contour2[1::2] = contour[1:] data2.append(np.fliplr(contour2)) # Return as pointset return vv.Pointset(np.row_stack(data2))
def __init__(self, im, grid_sampling=40): # Store image self._im = im # Setup visualization self._fig = fig = vv.figure() self._a1 = a1 = vv.subplot(231); self._a2 = a2 = vv.subplot(232); self._a3 = a3 = vv.subplot(233); self._a4 = a4 = vv.subplot(234); self._a5 = a5 = vv.subplot(235); self._a6 = a6 = vv.subplot(236); # Text objects self._text1 = vv.Label(fig) self._text1.position = 5, 2 self._text2 = vv.Label(fig) self._text2.position = 5, 20 # Move axes a1.parent.position = 0.0, 0.1, 0.33, 0.45 a2.parent.position = 0.33, 0.1, 0.33, 0.45 a3.parent.position = 0.66, 0.1, 0.33, 0.45 a4.parent.position = 0.0, 0.55, 0.33, 0.45 a5.parent.position = 0.33, 0.55, 0.33, 0.45 a6.parent.position = 0.66, 0.55, 0.33, 0.45 # Correct axes, share camera cam = vv.cameras.TwoDCamera() for a in [a1, a2, a3, a4, a5, a6]: a.axis.visible = False a.camera = cam # Show images im0 = im*0 self._t1 = vv.imshow(im, axes=a1) self._t2 = vv.imshow(im, axes=a2) self._t3 = vv.imshow(im, axes=a3) self._t4 = vv.imshow(im0, axes=a4) self._t5 = vv.imshow(im0, axes=a5) self._t6 = vv.imshow(im0, axes=a6) # Init pointsets self._pp1 = Pointset(2) self._pp2 = Pointset(2) self._active = None self._lines = [] # Init lines to show all deformations tmp = vv.Pointset(2) self._line1 = vv.plot(tmp, ls='', ms='.', mc='c', axes=a2) self._line2 = vv.plot(tmp, ls='+', lc='c', lw='2', axes=a2) # Init grid properties self._sampling = grid_sampling self._levels = 5 self._multiscale = True self._injective = 0.5 self._frozenedge = 1 self._forward = True # Init grid self.DeformationField = DeformationFieldForward self._field1 = self.DeformationField(FieldDescription(self._im)) self._field2 = self.DeformationField(FieldDescription(self._im)) # Bind to events a2.eventMouseDown.Bind(self.on_down) a2.eventMouseUp.Bind(self.on_up) a2.eventMotion.Bind(self.on_motion) fig.eventKeyDown.Bind(self.on_key_down) #a1.eventDoubleClick.Bind(self.OnDone) # Apply self.apply()
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
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)
deform.append(a) deform_backward = pirt.DeformationFieldBackward(deform) # Scale the deform deform_forward2 = deform_forward.scale(0.5) deform_backward2 = deform_backward.scale(0.5) # Apply the deform to the images im_forward = deform_forward.apply_deformation(im) im_forward2 = deform_forward2.apply_deformation(im) im_backward = deform_backward.apply_deformation(im) im_backward2 = deform_backward2.apply_deformation(im) # Calculate vectors vecstep = 20 pp = vv.Pointset(2) vvf, vvb = vv.Pointset(2), vv.Pointset(2) vvf2, vvb2 = vv.Pointset(2), vv.Pointset(2) for y in np.arange(0, im.shape[0], vecstep): for x in np.arange(0, im.shape[1], vecstep): # Center point p1 = vv.Point(x, y) pp.append(p1) # Vector for forward deform = deform_forward vvf.append(vv.Point(deform[1][y, x], deform[0][y, x])) deform = deform_forward2 vvf2.append(vv.Point(deform[1][y, x], deform[0][y, x])) # Vector for backward deform = deform_backward vvb.append(vv.Point(deform[1][y, x], deform[0][y, x]))
# check (note that we use the original order for calculation) p1, p2 = self._check_and_sort(self, p, 'cross') # calculate a, b = self, p data = np.zeros(p2.shape, np.float64) data[:, 0] = a[:, 1] * b[:, 2] - a[:, 2] * b[:, 1] data[:, 1] = a[:, 2] * b[:, 0] - a[:, 0] * b[:, 2] data[:, 2] = a[:, 0] * b[:, 1] - a[:, 1] * b[:, 0] # return return PointSet(data) if __name__ == '__main__': import visvis as vv a = PointSet(2, np.float32) b = vv.Pointset(2) pp = np.random.uniform(0, 1, (100, 2)) t0 = time.time() for i in range(len(pp)): a.append(pp[i]) print('numpy resize: %1.3f s' % (time.time() - t0)) t0 = time.time() for i in range(len(pp)): b.append(pp[i]) print('PointSet append: %1.3f s' % (time.time() - t0))
def pick3d(axes, vol): """ Enable picking intensities in a 3D volume. Given an Axes object and a volume (an Aarray), will show the value, index and position of the voxel with maximum intentity under the cursor when doing a SHIFT+RIGHTCLICK. Returns the label object, so that it can be re-positioned. Assumptions: * ThreeDCamera is in use and in orthographic mode (no perspective). * The volume does not have any transformations w.r.t the axes, except for the implicit transformations defined by its sampling and origin. """ assert hasattr(vol, 'sampling'), 'Vol must be an Aarray.' line = vv.plot(vv.Pointset(3), ms='o', mw=12, lc='c', mc='c', alpha=0.4, axesAdjust=False) label = vv.Label(axes) label.position = 0, 0, 1, 20 @axes.eventMouseDown.Bind def onClick(event): if event.button == 2 and vv.KEY_SHIFT in event.modifiers: # Get clicked location in NDC w, h = event.owner.position.size x, y = 2 * event.x / w - 1, -2 * event.y / h + 1 # Apply inverse camera transform to get two points on the clicked line M = np.linalg.inv(get_camera_matrix(event.owner)) p1 = vv.Point(np.dot((x, y, -100, 1), M)[:3]) p2 = vv.Point(np.dot((x, y, +100, 1), M)[:3]) # Calculate center point and vector pm = 0.5 * (p1 + p2) vec = (p2 - p1).normalize() # Prepare for searching in two directions pp = [pm - vec, pm + vec] status = 0 if sample(vol, pm) is None else 1 status = [status, status] hit = None max_sample = -999999 step = min(vol.sampling) # Look in two directions simulaneously, search for volume, collect samples for i in range(10000): # Safe while-loop for j in (0, 1): if status[j] < 2: s = sample(vol, pp[j]) inside = s is not None if inside: if s > max_sample: max_sample, hit = s, pp[j] if status[j] == 0: status[j] = 1 status[ not j] = 2 # stop looking in other direction else: if status[j] == 1: status[j] = 2 pp[j] += (j * 2 - 1) * step * vec if status[0] == 2 and status[1] == 2: break else: print('Warning: ray casting to collect samples did not stop' ) # clicking outside the volume # Draw pp2 = vv.Pointset(3) text = 'No point inside volume selected.' if hit: pp2.append(hit) ii = vol.point_to_index(hit) text = 'At z=%1.1f, y=%1.1f, x=%1.1f -> X[%i, %i, %i] -> %1.2f' % ( hit.z, hit.y, hit.x, ii[0], ii[1], ii[2], max_sample) line.SetPoints(pp2) label.text = text return True # prevent default mouse action return label