def __init__(self, main_win): super(VisVisWidget, self).__init__() # self.app = vv.use() self._vv_widget = vv.gcf() self._vv_widget._widget.show() self.main_win = main_win self.create_gui()
def clf(): """ clf() Clear current figure. """ f = vv.gcf() f.Clear() return f
def show_ctvolume(vol, graph=None, axis=None, showVol='MIP', clim=(0, 2500), isoTh=250, removeStent=True, climEditor=False, stripSize=6, stripSizeZ=None): """ Different ways to visualize the CT volume as reference For '2D' clim (-550,500) often good range """ import visvis as vv colormap = { 'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)] } if axis is None: axis = vv.gca() axis.MakeCurrent() if showVol == 'MIP': t = vv.volshow(vol, clim=clim, renderStyle='mip') elif showVol == 'ISO': if removeStent == True: vol = remove_stent_from_volume( vol, graph, stripSize=stripSize, stripSizeZ=stripSizeZ) # rings are removed for vis. t = vv.volshow(vol, clim=clim, renderStyle='iso') t.isoThreshold = isoTh t.colormap = colormap elif showVol == '2D': t = vv.volshow2(vol) t.clim = clim # bind ClimEditor to figure if climEditor: if showVol == 'ISO': c = _utils_GUI.IsoThEditor(axis) else: c = vv.ClimEditor(axis) c.position = (10, 50) # bind for show hide fig = vv.gcf() fig.eventKeyDown.Bind( lambda event: _utils_GUI.ShowHideSlider(event, c)) print('****') print('Use "s" to show/hide slider') print('****') return t
def volshow(*args, **kwargs): """ volshow(vol, clim=None, cm=CM_GRAY, axesAdjust=True, axes=None) Display a 3D image (a volume). This is a convenience function that calls either volshow3() or volshow2(). If the current system supports it (OpenGL version >= 2.0), displays a 3D rendering (volshow3). Otherwise shows three slices that can be moved interactively (volshow2). Parameters ---------- vol : numpy array The 3D image to visualize. Can be grayscale, RGB, or RGBA. If the volume is an anisotropic array (vv.Aaray), the appropriate scale and translate transformations are applied. clim : 2-element tuple The color limits to scale the intensities of the image. If not given, the im.min() and im.max() are used (neglecting nan and inf). cm : Colormap Set the colormap to apply in case the volume is grayscale. axesAdjust : bool If axesAdjust==True, this function will call axes.SetLimits(), and set the camera type to 3D. If daspectAuto has not been set yet, it is set to False. axes : Axes instance Display the image in this axes, or the current axes if not given. Any other keyword arguments are passed to either volshow2() or volshow3(). """ # Make sure that a figure exists vv.gcf() # Test and run if vv.settings.volshowPreference==3 and vv.misc.getOpenGlCapable(2.0): return vv.volshow3(*args, **kwargs) else: return vv.volshow2(*args, **kwargs)
def volshow(*args, **kwargs): """ volshow(vol, clim=None, cm=CM_GRAY, axesAdjust=True, axes=None) Display a 3D image (a volume). This is a convenience function that calls either volshow3() or volshow2(). If the current system supports it (OpenGL version >= 2.0), displays a 3D rendering (volshow3). Otherwise shows three slices that can be moved interactively (volshow2). Parameters ---------- vol : numpy array The 3D image to visualize. Can be grayscale, RGB, or RGBA. If the volume is an anisotropic array (vv.Aaray), the appropriate scale and translate transformations are applied. clim : 2-element tuple The color limits to scale the intensities of the image. If not given, the im.min() and im.max() are used (neglecting nan and inf). cm : Colormap Set the colormap to apply in case the volume is grayscale. axesAdjust : bool If axesAdjust==True, this function will call axes.SetLimits(), and set the camera type to 3D. If daspectAuto has not been set yet, it is set to False. axes : Axes instance Display the image in this axes, or the current axes if not given. Any other keyword arguments are passed to either volshow2() or volshow3(). """ # Make sure that a figure exists vv.gcf() # Test and run if vv.settings.volshowPreference == 3 and vv.misc.getOpenGlCapable(2.0): return vv.volshow3(*args, **kwargs) else: return vv.volshow2(*args, **kwargs)
def draw(figure=None, fast=False): """ draw(figure=None, fast=False) Makes the given figure (or the current figure if None) draw itself. If fast is True, some wobjects can draw itself faster at reduced quality. """ # Get figure if figure is None: figure = vv.gcf() # Draw! figure.Draw(fast)
def __init__(self, vol, direction, axes=None, clim=None): self.direction = direction # Store vol and init if self.direction == 0: self.vol = vol elif self.direction == 1: self.vol = np.transpose(vol, (1, 0, 2)) self.vol.origin = (vol.origin[1], vol.origin[0], vol.origin[2]) self.vol.sampling = (vol.sampling[1], vol.sampling[0], vol.sampling[2]) elif self.direction == 2: self.vol = np.transpose(vol, (2, 0, 1)) self.vol.origin = (vol.origin[2], vol.origin[0], vol.origin[1]) self.vol.sampling = (vol.sampling[2], vol.sampling[0], vol.sampling[1]) else: S('No valid input for direction, only 1,2 or 3 is possible') self.slice = 0 # Prepare figure and axex if axes is None: self.a = vv.gca() else: self.a = axes self.f = vv.gcf() # Create slice in 2D texture if clim: self.t = vv.imshow(self.vol[self.round_slice, :, :], clim=clim, axes=self.a) else: self.t = vv.imshow(self.vol[self.round_slice, :, :], axes=self.a) # Bind self.a.eventScroll.Bind(self.on_scroll) self.eventPositionUpdate = vv.events.BaseEvent(self) axes.eventMouseDown.Bind(self.on_click) # Fig properties self.a.bgcolor = [0, 0, 0] self.a.axis.visible = False self.a.showAxis = False
def draw(figure=None, fast=False): """ draw(figure=None, fast=False) Makes the given figure (or the current figure if None) draw itself. If fast is True, some wobjects can draw itself faster at reduced quality. This function is now more or less deprecated; visvis is designed to invoke a draw whenever necessary. """ # Get figure if figure is None: figure = vv.gcf() # Draw! figure.Draw(fast)
def gca(): """ gca() Get the current axes in the current figure. If there is no axes, an Axes instance is created. To make an axes current, use Axes.MakeCurrent(). See also gcf(), Figure.MakeCurrent(), Figure.currentAxes """ f = vv.gcf() a = f.currentAxes if not a: # create axes a = vv.Axes(f) #a.position = 2, 2, -4, -4 a.position = 10, 10, -20, -20 return a
def set_mesh(self, mesh): vv.clf() self._vv_widget = vv.gcf() self._vv_widget._widget.show() self.main_win.setCentralWidget(self.widget()) if mesh: v_mesh = mesh.to_visvis_mesh() v_mesh.faceColor = 'y' v_mesh.edgeShading = 'plain' v_mesh.edgeColor = (0, 0, 1) axes = vv.gca() if axes.daspectAuto is None: axes.daspectAuto = False axes.SetLimits() axes.legend = 'X', 'Y', 'Z' axes.axis.showGrid = True axes.axis.xLabel = 'X' axes.axis.yLabel = 'Y' axes.axis.zLabel = 'Z'
def __init__(self, fig=None, filename=None, dirsave=None, fileformat='avi', frameRate=None): """ fig or axes can be given. gif swf or avi possible framerate to save depends on graphics card pc. default is 10fps, if faster than real world, use 5-7fps """ # import os # import imageio # import visvis as vv # import datetime # from stentseg.utils.datahandling import select_dir # self.os = os # self.imageio = imageio # self.vv = vv # self.datetime = datetime self.r = None self.frameRate = frameRate if fig is None: self.fig = vv.gcf() else: self.fig = fig self.filename = filename self.fileformat = fileformat if dirsave is None: self.dirsave = select_dir(r'C:\Users\Maaike\Desktop', r'D:\Profiles\koenradesma\Desktop') else: self.dirsave = dirsave print( '"recordMovie" active, use r (rec), t (stop), y (continue), m (save), q (clear)' ) # Bind eventhandler record self.fig.eventKeyUp.Bind(self.record)
def subplot(*args): """ subplot(ncols, nrows, nr) Create or return axes in current figure. Note that subplot(322) is the same as subplot(3,2,2). Parameters ---------- ncols : int The number of columns to devide the figure in. nrows : int The number of rows to devide the figure in. nr : int The subfigure number on the grid specified by ncols and nrows. Should be at least one. subplot(221) is the top left. subplot(222) is the top right. Notes ----- It is checked whether (the center of) an axes is present at the specified grid location. If so, that axes is returned. Otherwise a new axes is created at that location. """ # parse input if len(args)==1: tmp = args[0] if tmp>999 or tmp<111: raise ValueError("Invalid cols/rows/nr specified.") rows = tmp // 100 tmp = tmp % 100 cols = tmp // 10 tmp = tmp % 10 nr = tmp elif len(args)==3: rows, cols, nr = args else: raise ValueError("Invalid number of cols/rows/nr specified.") # check if ok if nr<=0 or cols<=0 or rows<=0: raise ValueError("Invalid cols/rows/nr: all bust be >0.") if nr > cols*rows: raise ValueError("Invalid nr: there are not so many positions.") # init f = vv.gcf() nr = nr-1 # check if an axes is there for a in f._children: if isinstance(a, AxesContainer): n = laysin( cols, rows, getcenter(f, a) ) if n == nr: # make current and return a = a.GetAxes() f.currentAxes = a return a # create axes in container a = Axes(f) c = a.parent # calculate relative coordinates dx, dy = 1.0/cols, 1.0/rows y = int( nr / cols ) x = int( nr % cols ) # apply positions c.position = dx*x, dy*y, dx, dy a.position = 10, 10, -20, -20 # done return a
and exported to gif/swf/avi. This is not an interactive example, but a script. """ import visvis as vv # Create something to show, let's show a red teapot! mesh = vv.solidTeapot() mesh.faceColor = 'r' # Prepare Nangles = 36 a = vv.gca() f = vv.gcf() rec = vv.record(a) # Rotate camera for i in range(Nangles): a.camera.azimuth = 360 * float(i) / Nangles if a.camera.azimuth > 180: a.camera.azimuth -= 360 a.Draw() # Tell the axes to redraw f.DrawNow() # Draw the figure NOW, instead of waiting for GUI event loop # Export rec.Stop() rec.Export('teapot.gif') """ NOTES
D = {0:-3,1:-2,2:-1,3:None} slicey = slice(iy, D[iy]) slicex = slice(ix, D[ix]) # Get contribution and add to temp image imTmp += w * im2[slicey, slicex, :] # Store contributions D = [-1 for tmp in range(s)]; D.append(None) slicey = slice(dy,D[dy],s) slicex = slice(dx,D[dx],s) im3[slicey, slicex, :] = imTmp # Correct for overshoot im3[im3>1]=1 im3[im3<0]=0 # Store image to file if filename is not None: vv.imwrite(filename, im3, format) else: return im3 if __name__ == '__main__': # Make plot vv.plot([1,2,3,1,4,2,3], ms='.') # Take screenshot, twice enlarged, on a white background vv.screenshot('screenshot.jpg', vv.gcf(), sf=2, bg='w')
def screenshot(filename, ob=None, sf=2, bg=None, format=None, tension=-0.25): """ screenshot(filename, ob=None sf=2, bg=None, format=None) Make a screenshot and store it to a file, using cubic interpolation to increase the resolution (and quality) of the image. Parameters ---------- filename : string The name of the file to store the screenshot to. If filename is None, the interpolated image is returned as a numpy array. ob : Axes, AxesContainer, or Figure The object to take the screenshot of. The AxesContainer can be obtained using vv.gca().parent. It can be usefull to take a screeshot of an axes including thickmarks and labels. sf : integer The scale factor. The image is increased in size with this factor, using a high quality interpolation method. A factor of 2 or 3 is recommended; the image quality does not improve with higher factors. If using a sf larger than 1, the image is best saved in the jpg format. bg : 3-element tuple or char The color of the background. If bg is given, ob.bgcolor is set to bg before the frame is captured. format : string The format for the screenshot to be saved in. If not given, the format is deduced from the filename. Notes ----- Uses vv.getframe(ob) to obtain the image in the figure or axes. That image is interpolated with the given scale factor (sf) using bicubic interpolation. Then vv.imwrite(filename, ..) is used to store the resulting image to a file. Rationale --------- We'd prefer storing screenshots of plots as vector (eps) images, but the nature of OpenGl prevents this. By applying high quality interpolation (using a cardinal spline), the resolution can be increased, thereby significantly improving the visibility/smoothness for lines and fonts. Use this to produce publication quality snapshots of your plots. """ # The tension controls the # responsivenes of the filter. The more negative, the more overshoot, # but the more it is capable to make for example font glyphs smooth. # If tension is 0, the interpolator is a Catmull-Rom spline. # Scale must be integer s = int(sf) # Object given? if ob is None: ob = vv.gcf() # Get figure fig = ob if not hasattr(ob, 'DrawNow'): fig = ob.GetFigure() # Get object to set background of bgob = ob # Set background if bg and fig: bgOld = bgob.bgcolor bgob.bgcolor = bg fig.DrawNow() # Obtain image im1 = vv.getframe(ob) shape1 = im1.shape # Return background if bg and fig: bgob.bgcolor = bgOld fig.Draw() # Pad original image, so we have no trouble at the edges shape2 = shape1[0]+2, shape1[1]+2, 3 im2 = np.zeros(shape2, dtype=np.float32) # Also make float im2[1:-1,1:-1,:] = im1 im2[0,:,:] = im2[1,:,:] im2[-1,:,:] = im2[-2,:,:] im2[:,0,:] = im2[:,1,:] im2[:,-1,:] = im2[:,-2,:] # Create empty new image. It is sized by the scaleFactor, # but the last row is not. shape3 = (shape1[0]-1)*s+1, (shape1[1]-1)*s+1, 3 im3 = np.zeros(shape3, dtype=np.float32) # Fill in values! for dy in range(s+1): for dx in range(s+1): # Get interpolation fraction and coefs ty = float(dy)/s tx = float(dx)/s cy = getCardinalSplineCoefs(ty, tension) cx = getCardinalSplineCoefs(tx, tension) # Create tmp image to which we add the contributions # Note that this image is 1 pixel smaller in each dimension. # The last pixel is filled because dy and dx iterate INCLUDING s. shapeTmp = shape1[0]-1, shape1[1]-1, 3 imTmp = np.zeros(shapeTmp, dtype=np.float32) # Collect all 16 neighbours and weight them apropriately for iy in range(4): for ix in range(4): # Get weight w = cy[iy]*cx[ix] if w==0: continue # Get slice. Note that we start at 0,1,2,3 rather than # -1,0,1,2, because we padded the image. D = {0:-3,1:-2,2:-1,3:None} slicey = slice(iy, D[iy]) slicex = slice(ix, D[ix]) # Get contribution and add to temp image imTmp += w * im2[slicey, slicex, :] # Store contributions D = [-1 for tmp in range(s)]; D.append(None) slicey = slice(dy,D[dy],s) slicex = slice(dx,D[dx],s) im3[slicey, slicex, :] = imTmp # Correct for overshoot im3[im3>1]=1 im3[im3<0]=0 # Store image to file if filename is not None: vv.imwrite(filename, im3, format) else: return im3
# Create visvis application app = vv.use() app.Create() # Create main window frame and set a resolution. main_w = MainWindow() main_w.resize(700, 320) # Create the 3 D shape model as a mesh. verticesPerFace equals 3 since triangles define the # mesh's surface in this case shape_obj = vv.mesh(vertices=VERTICES, faces=faces, verticesPerFace=3) shape_obj.specular = 0.0 shape_obj.diffuse = 0.9 # Get figure figure = vv.gcf() # Get axes objects and set figure parameters axes = vv.gca() axes.bgcolor = (0, 0, 0) axes.axis.showGrid = False axes.axis.visible = False # Set camera settings # axes.camera = '3d' axes.camera.fov = 60 axes.camera.zoom = 0.1 # Turn off the main light axes.light0.Off()
def subplot(*args): """ subplot(ncols, nrows, nr) Create or return axes in current figure. Note that subplot(322) is the same as subplot(3,2,2). Parameters ---------- ncols : int The number of columns to devide the figure in. nrows : int The number of rows to devide the figure in. nr : int The subfigure number on the grid specified by ncols and nrows. Should be at least one. subplot(221) is the top left. subplot(222) is the top right. Notes ----- It is checked whether (the center of) an axes is present at the specified grid location. If so, that axes is returned. Otherwise a new axes is created at that location. """ # parse input if len(args) == 1: tmp = args[0] if tmp > 999 or tmp < 111: raise ValueError("Invalid cols/rows/nr specified.") rows = tmp // 100 tmp = tmp % 100 cols = tmp // 10 tmp = tmp % 10 nr = tmp elif len(args) == 3: rows, cols, nr = args else: raise ValueError("Invalid number of cols/rows/nr specified.") # check if ok if nr <= 0 or cols <= 0 or rows <= 0: raise ValueError("Invalid cols/rows/nr: all bust be >0.") if nr > cols * rows: raise ValueError("Invalid nr: there are not so many positions.") # init f = vv.gcf() nr = nr - 1 # check if an axes is there for a in f._children: if isinstance(a, AxesContainer): n = laysin(cols, rows, getcenter(f, a)) if n == nr: # make current and return a = a.GetAxes() f.currentAxes = a return a # create axes in container a = Axes(f) c = a.parent # calculate relative coordinates dx, dy = 1.0 / cols, 1.0 / rows y = int(nr / cols) x = int(nr % cols) # apply positions c.position = dx * x, dy * y, dx, dy a.position = 10, 10, -20, -20 # done return a
#vol[i,j,k] = (2.0/N)*(i-N/2)*(i-N/2) - (1/N)*(j-N/2)*(j-N/2) - (k-N/2) # Paraboloide hiperbolico #vol[i,j,k] = cos(i) + cos(j) + cos(k) # Triply periodic minimal surface (Schwarz) # show #impl_surf = vv.volshow(vol, renderStyle='iso') # try the differtent render styles, for examample # "t.renderStyle='iso'" or "t.renderStyle='ray'" # If the drawing hangs, your video drived decided to render in software mode. # This is unfortunately (as far as I know) not possible to detect. # It might help if your data is shaped a power of 2. #impl_surf.isoThreshold = 0.0 #impl_surf.colormap = vv.CM_WINTER # Create colormap editor wibject. #vv.ColormapEditor(axs) # # Graficación # axs = vv.gca() # "Get Current Axes" #axs.bgcolor = (0.0, 0.0, 0.0) axs.camera.fov = 60 fig = vv.gcf() # "Get Current Figure" fig._widget.showFullScreen() # Pantalla completa, para RaspberryPi app.Run() # Corre aplicación/ventana
def converge_to_centre(pp, c, nDirections=5, maxRadius=50, pauseTime=0): """ converge_to_centre(pp, c) Given a set of points and an initial center point c, will find a better estimate of the center. Returns (c, L), with L indices in pp that were uses to fit the final circle. """ # Shorter names N = nDirections pi = np.pi # Init point to return on error ce = Point(0,0) ce.r = 0 # Are there enough points? if len(pp) < 3: return ce, [] # Init a pointset of centers we've has so far cc = Pointset(2) # Init list with vis objects (to be able to delete them) showObjects = [] if pauseTime: fig = vv.gcf() while c not in cc: # Add previous center cc.append(c) # Calculate distances and angles dists = c.distance(pp) angs = c.angle2(pp) # Get index of closest points i, = np.where(dists==dists.min()) i = iClosest = int(i[0]) # Offset the angles with the angle relative to the closest point. refAng = angs[i] angs = subtract_angles(angs, refAng) # Init L, the indices to the closest point in each direction L = [] # Get closest point on N directions for angle in [float(angnr)/N*2*pi for angnr in range(N)]: # Get indices of points that are in this direction dangs = subtract_angles(angs, angle) I, = np.where(np.abs(dangs) < pi/N ) # Select closest if len(I): distSelection = dists[I] minDist = distSelection.min() J, = np.where(distSelection==minDist) if len(J) and minDist < maxRadius: L.append( int(I[J[0]]) ) # Check if ok if len(L) < 3: return ce, [] # Remove spurious points (points much furter away that the 3 closest) distSelection = dists[L] tmp = [d for d in distSelection] d3 = sorted(tmp)[2] # Get distance of 3th closest point I, = np.where(distSelection < d3*2) L = [L[i] for i in I] # Select points ppSelect = Pointset(2) for i in L: ppSelect.append(pp[i]) # Refit circle cnew = fit_cirlce(ppSelect,False) if cnew.r==0: return ce, [] # Show if pauseTime>0: # Delete for ob in showObjects: ob.Destroy() # Plot center and new center ob1 = vv.plot(c, ls='', ms='x', mc='r', mw=10, axesAdjust=0) ob2 = vv.plot(cnew, ls='', ms='x', mc='r', mw=10, mew=0, axesAdjust=0) # Plot selection points ob3 = vv.plot(ppSelect, ls='', ms='.', mc='y', mw=10, axesAdjust=0) # Plot lines dividing the directions tmpSet1 = Pointset(2) tmpSet2 = Pointset(2) for angle in [float(angnr)/N*2*pi for angnr in range(N)]: angle = -subtract_angles(angle, refAng) dx, dy = np.cos(angle), np.sin(angle) tmpSet1.append(c.x, c.y) tmpSet1.append(c.x+dx*d3*2, c.y+dy*d3*2) for angle in [float(angnr+0.5)/N*2*pi for angnr in range(N)]: angle = -subtract_angles(angle, refAng) dx, dy = np.cos(angle), np.sin(angle) tmpSet2.append(c.x, c.y) tmpSet2.append(c.x+dx*d3*2, c.y+dy*d3*2) ob4 = vv.plot(tmpSet1, lc='y', ls='--', axesAdjust=0) ob5 = vv.plot(tmpSet2, lc='y', lw=3, axesAdjust=0) # Store objects and wait showObjects = [ob1,ob2,ob3,ob4,ob5] fig.DrawNow() time.sleep(pauseTime) # Use new c = cnew # Done for ob in showObjects: ob.Destroy() return c, L
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
vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title('Overlay') a2.daspect = 1, 1, -1 a3 = vv.subplot(223) vv.volshow(volTr, clim=clim) vv.xlabel('x'), vv.ylabel('y'), vv.zlabel('z') vv.title( 'Im2:Original transformed (DataDressedInterpolated u_\magnitude {})' .format(mat2['u_magnitude'][0][0])) a3.daspect = 1, 1, -1 a4 = vv.subplot(224) a4.daspect = 1, 1, -1 c = vv.ClimEditor(vv.gcf()) a1.camera = a2.camera = a3.camera = a4.camera # Remove .mat for savename and loading below if fileTr.endswith('.mat'): fileTr = fileTr.replace('.mat', '') ## Do registration if True: t0 = time.time() # set final scale based on pixelwidth (scale should be =<0.5*pixelwidth) if max(sampling2) > 2: final_scale = max(sampling2) / 2
def screenshot(filename, ob=None, sf=2, bg=None, format=None, tension=-0.25): """ screenshot(filename, ob=None sf=2, bg=None, format=None) Make a screenshot and store it to a file, using cubic interpolation to increase the resolution (and quality) of the image. Parameters ---------- filename : string The name of the file to store the screenshot to. If filename is None, the interpolated image is returned as a numpy array. ob : Axes, AxesContainer, or Figure The object to take the screenshot of. The AxesContainer can be obtained using vv.gca().parent. It can be usefull to take a screeshot of an axes including thickmarks and labels. sf : integer The scale factor. The image is increased in size with this factor, using a high quality interpolation method. A factor of 2 or 3 is recommended; the image quality does not improve with higher factors. If using a sf larger than 1, the image is best saved in the jpg format. bg : 3-element tuple or char The color of the background. If bg is given, ob.bgcolor is set to bg before the frame is captured. format : string The format for the screenshot to be saved in. If not given, the format is deduced from the filename. Notes ----- Uses vv.getframe(ob) to obtain the image in the figure or axes. That image is interpolated with the given scale factor (sf) using bicubic interpolation. Then vv.imwrite(filename, ..) is used to store the resulting image to a file. Rationale --------- We'd prefer storing screenshots of plots as vector (eps) images, but the nature of OpenGl prevents this. By applying high quality interpolation (using a cardinal spline), the resolution can be increased, thereby significantly improving the visibility/smoothness for lines and fonts. Use this to produce publication quality snapshots of your plots. """ # The tension controls the # responsivenes of the filter. The more negative, the more overshoot, # but the more it is capable to make for example font glyphs smooth. # If tension is 0, the interpolator is a Catmull-Rom spline. # Scale must be integer s = int(sf) # Object given? if ob is None: ob = vv.gcf() # Get figure fig = ob if not hasattr(ob, 'DrawNow'): fig = ob.GetFigure() # Get object to set background of bgob = ob # Set background if bg and fig: bgOld = bgob.bgcolor bgob.bgcolor = bg fig.DrawNow() # Obtain image im1 = vv.getframe(ob) shape1 = im1.shape # Return background if bg and fig: bgob.bgcolor = bgOld fig.Draw() # Pad original image, so we have no trouble at the edges shape2 = shape1[0] + 2, shape1[1] + 2, 3 im2 = np.zeros(shape2, dtype=np.float32) # Also make float im2[1:-1, 1:-1, :] = im1 im2[0, :, :] = im2[1, :, :] im2[-1, :, :] = im2[-2, :, :] im2[:, 0, :] = im2[:, 1, :] im2[:, -1, :] = im2[:, -2, :] # Create empty new image. It is sized by the scaleFactor, # but the last row is not. shape3 = (shape1[0] - 1) * s + 1, (shape1[1] - 1) * s + 1, 3 im3 = np.zeros(shape3, dtype=np.float32) # Fill in values! for dy in range(s + 1): for dx in range(s + 1): # Get interpolation fraction and coefs ty = float(dy) / s tx = float(dx) / s cy = getCardinalSplineCoefs(ty, tension) cx = getCardinalSplineCoefs(tx, tension) # Create tmp image to which we add the contributions # Note that this image is 1 pixel smaller in each dimension. # The last pixel is filled because dy and dx iterate INCLUDING s. shapeTmp = shape1[0] - 1, shape1[1] - 1, 3 imTmp = np.zeros(shapeTmp, dtype=np.float32) # Collect all 16 neighbours and weight them apropriately for iy in range(4): for ix in range(4): # Get weight w = cy[iy] * cx[ix] if w == 0: continue # Get slice. Note that we start at 0,1,2,3 rather than # -1,0,1,2, because we padded the image. D = {0: -3, 1: -2, 2: -1, 3: None} slicey = slice(iy, D[iy]) slicex = slice(ix, D[ix]) # Get contribution and add to temp image imTmp += w * im2[slicey, slicex, :] # Store contributions D = [-1 for tmp in range(s)] D.append(None) slicey = slice(dy, D[dy], s) slicex = slice(dx, D[dx], s) im3[slicey, slicex, :] = imTmp # Correct for overshoot im3[im3 > 1] = 1 im3[im3 < 0] = 0 # Store image to file if filename is not None: vv.imwrite(filename, im3, format) else: return im3
tex3d.visible = False # VesselMeshes vesselVisMesh1 = axes1.wobjects[4] vesselVisMesh1.cullFaces = "front" # Show the back # vesselVisMesh2 = vv.Mesh(axes1, *vesselMesh.get_vertices_and_faces()) vesselVisMesh2 = vv.Mesh(axes1, np.zeros((6, 3), np.float32), np.zeros((3, 3), np.int32)) vesselVisMesh2.cullFaces = "back" vesselVisMesh2.faceColor = "red" # Show the centerline vv.plot(centerline, ms='.', ls='', mw=8, mc='b', alpha=0.5) # Initialize 2D view axes2 = vv.Axes(vv.gcf()) axes2.position = 0.65, 0.05, 0.3, 0.4 axes2.daspectAuto = False axes2.camera = '2d' axes2.axis.showGrid = True axes2.axis.axisColor = 'k' # Initialize axes to put widgets and labels in container = vv.Wibject(vv.gcf()) container.position = 0.65, 0.5, 0.3, 0.5 # Create labels to show measurements labelpool = [] for i in range(16): label = vv.Label(container) label.fontSize = 11
#Use the gradient operator on the velocity array: gradient(m)[0] #Makes the velocity be on the columns instead of rows. if(self.vMags == None): self.velocityMag() a = np.gradient(self.vels,1/self.fs)[0] self.aMags = np.linalg.norm(a,axis=1) return self.aMags def peakAccelMag(self): if(self.vMags == None): self.velocityMag() peakA = max(self.aMags) return peakA @staticmethod def resetSensorCount(): Sensor.numSensors = 0 if(__name__ == '__main__'): figure = vv.gcf() axes = vv.gca() audiofile = "C:/Data/05_ENGL_F_words6.wav" kinfile = "C:/Data/05_ENGL_F_words6_BPC.tsv" data = np.genfromtxt(unicode(kinfile), skip_header = 1, delimiter = '\t') newSensor = Sensor(data[:,14:21], axes, 'Upper Lip','UL', 400) newSensor.updateDataAndText(1000) newSensor.accelerationMag()
D = {0: -3, 1: -2, 2: -1, 3: None} slicey = slice(iy, D[iy]) slicex = slice(ix, D[ix]) # Get contribution and add to temp image imTmp += w * im2[slicey, slicex, :] # Store contributions D = [-1 for tmp in range(s)] D.append(None) slicey = slice(dy, D[dy], s) slicex = slice(dx, D[dx], s) im3[slicey, slicex, :] = imTmp # Correct for overshoot im3[im3 > 1] = 1 im3[im3 < 0] = 0 # Store image to file if filename is not None: vv.imwrite(filename, im3, format) else: return im3 if __name__ == '__main__': # Make plot vv.plot([1, 2, 3, 1, 4, 2, 3], ms='.') # Take screenshot, twice enlarged, on a white background vv.screenshot('screenshot.jpg', vv.gcf(), sf=2, bg='w')
# The full license can be found in 'license.txt'. from visvis import BaseFigure import visvis as vv def gcf(): """ gcf() Get the current figure. If there is no figure yet, figure() is called to create one. To make a figure current, use Figure.MakeCurrent(). See also gca() """ if not BaseFigure._figures: # no figure yet return vv.figure() nr = BaseFigure._currentNr if not nr in BaseFigure._figures: # erroneous nr nr = list(BaseFigure._figures.keys())[0] BaseFigure._currentNr = nr return BaseFigure._figures[nr] if __name__ == '__main__': fig = vv.gcf()
for deform in deforms_forward] # get backward mapping # Start vis f = vv.figure(nr) vv.clf() if nr == 1: f.position = 8.00, 30.00, 667.00, 690.00 else: f.position = 691.00, 30.00, 667.00, 690.00 a = vv.gca() a.axis.axisColor = 1, 1, 1 a.axis.visible = False a.bgcolor = 0, 0, 0 a.daspect = 1, 1, -1 vv.title('Model for LSPEAS %s - %s' % (ptcode[7:], ctcode)) vv.ColormapEditor(vv.gcf()) # Setup motion container dt = DeformableTexture3D(a, vol) dt.clim = 0, 3000 dt.isoThreshold = 300 dt.renderStyle = 'iso' # iso or mip work well dt.SetDeforms(*[list(reversed(deform)) for deform in deforms_backward]) dt.colormap = { 'g': [(0.0, 0.0), (0.33636364, 1.0)], 'b': [(0.0, 0.0), (0.49545455, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)], 'r': [(0.0, 0.0), (0.22272727, 1.0)] } # Set limits and play!
from visvis import BaseFigure import visvis as vv def gcf(): """ gcf() Get the current figure. If there is no figure yet, figure() is called to create one. To make a figure current, use Figure.MakeCurrent(). See also gca() """ if not BaseFigure._figures: # no figure yet return vv.figure() nr = BaseFigure._currentNr if not nr in BaseFigure._figures: # erroneous nr nr = list(BaseFigure._figures.keys())[0] BaseFigure._currentNr = nr return BaseFigure._figures[nr] if __name__ == '__main__': fig = vv.gcf()
app = vv.use() # Load volume vol = vv.volread("stent") # Create figure and make subplots with different renderers vv.figure(1) vv.clf() RS = ["mip", "iso", "edgeray", "ray", "litray"] a0 = None tt = [] for i in range(5): a = vv.subplot(3, 2, i + 2) t = vv.volshow(vol) vv.title("Renderstyle " + RS[i]) t.colormap = vv.CM_HOT t.renderStyle = RS[i] t.isoThreshold = 200 # Only used in iso render style tt.append(t) if a0 is None: a0 = a else: a.camera = a0.camera # Create colormap editor in first axes cme = vv.ColormapEditor(vv.gcf(), *tt[3:]) # Run app app.Create() app.Run()
# Zoom axes.SetLimits(margin=0.0) axes.SetLimits(margin=0.0, rangeX=(-1, 1)) # Control lighting #axes.bgcolor='k' # axes.light0.ambient = 0.0 # 0.2 is default for light 0 # axes.light0.diffuse = 0.0 # 1.0 is default axes.light0.Off() light1 = axes.lights[1] light1.On() light1.ambient = 0.8 light1.diffuse = 1.0 light1.isDirectional = True light1.position = (2, -4, 2, 0) rec = vv.record(vv.gcf()) # Timer for controlling rotation speed timer = vv.Timer(axes, 100, False) timer.Bind(onTimer) timer.Start(interval=1) app = vv.use() app.Run() # Output movie to gif rec.Stop() rec.Export('movie.gif') # Old code that used matplotlib, which is like 10 times slower, but left in # since visvis is discontinued
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
def record(ob): """ record(object) Take a snapshot of the given figure or axes after each draw. A Recorder instance is returned, with which the recording can be stopped, continued, and exported to GIF, SWF or AVI. """ # establish wheter we can record that if not isinstance(ob, (vv.BaseFigure, vv.Axes)): raise ValueError("The given object is not a figure nor an axes.") # create recorder return Recorder(ob) if __name__ == '__main__': import time l = vv.plot([1,2,3,1,4]) rec = vv.record(vv.gcf()) for i in range(20): l.SetYdata([1+i/10.0, 2,3,1,4]) vv.processEvents() # Process gui events time.sleep(0.1) # Export to swf, gif or avi fname = 'recordExample' # note: set location to an existing directory for ext in ['.swf', '.gif', '.avi']: try: rec.Export(fname+ext) except Exception: print('could not do %s' % ext)
app = vv.use() # Load volume vol = vv.volread('stent') # Create figure and make subplots with different renderers vv.figure(1) vv.clf() RS = ['mip', 'iso', 'edgeray', 'ray', 'litray'] a0 = None tt = [] for i in range(5): a = vv.subplot(3, 2, i + 2) t = vv.volshow(vol) vv.title('Renderstyle ' + RS[i]) t.colormap = vv.CM_HOT t.renderStyle = RS[i] t.isoThreshold = 200 # Only used in iso render style tt.append(t) if a0 is None: a0 = a else: a.camera = a0.camera # Create colormap editor in first axes cme = vv.ColormapEditor(vv.gcf(), *tt[3:]) # Run app app.Create() app.Run()
def cluster_points(pp, c, pauseTime=0, showConvergeToo=True): """ cluster_points(pp, c, pauseTime=0) Given a set of points, and the centreline position, this function returns a set of points, which is a subset of pp. The returned pointset is empty on error. This algorithm uses the chopstick clustering implementation. The first step is the "stick" method. We take the closest point from the centre and attach one end of a stick to it. The stick has the length of the radius of the fitted circle. We rotate the stick counterclockwise untill it hits a point, or untill we rotate too far without finding a point, thus failing. When it fails, we try again with a slighly larger stick. This is to close gaps of up to almost 100 degrees. When we reach a point were we've already been, we stop. Afterwards, the set of points is sorted by angle. In the second step we try to add points: we pick two subsequent points and check what other points are closer than "stick" to both these points, where "stick" is the distance between the points. We will break this stick in two and take the best point in the cluster, thus the name: chopstick. BUT ONLY if it is good enough! We draw two lines from the points under consideration to the centre. The angle that these two lines make is a reference for the allowed angle that the two lines may make that run from the two points to the new point. To be precise: ang > (180 - refang) - offset offset is a parameter to control the strictness. The third part of this step consists of removing points. We will only remove points that are closer to the centre than both neighbours. We check each point, comparing it with its two neighbours on each side, applying the same criterion as above. This will remove outliers that lie withing the stent, such as points found due to the contrast fluid... The latter two parts are repeated untill the set of points does not change. Each time the centre is recalculated by fitting a circle. """ # Get better center if showConvergeToo: c, I = converge_to_centre(pp, c, pauseTime=pauseTime) else: c, I = converge_to_centre(pp, c) if not I: return Pointset(2) # Init list with vis objects (to be able to delete them) showObjects = [] if pauseTime: fig = vv.gcf() # Short names pi = np.pi # Minimum and maximum angle that the stick is allowed to make with the line # to the circle-centre. Pretty intuitive... # it is a relative measure, we will multiply it with a ratio: # radius/distance_current_point_to_radius. This allows ellipses to be # segmented, while remaining strict for circles. difAng1_p = 0.0*pi difAng2_p = 0.7*pi ## Step 1, stick method to find an initial set of points # Select start point (3th point returned by converge_to_centre) icurr = I[2] # Init list L, at the beginning only contains icurr L = [icurr] # Largest amount of iterations that makes sense. Probably the loop # exits sooner. maxIter = len(pp) # Enter loop for iter in range(maxIter): # We can think of it as fixing the stick at one end at the current # point and then rotating it in a direction such that a point is # found in the clockwise direction of the current point. We thus # need the angle between the next and current point to be not much # more than the angle between the current point and the circle # cenrre + 90 deg. But it must be larger than the angle between the # current point and the circle centre. # Calculate distances dists = pp.distance(pp[icurr]) # Do the next bit using increasing stick length, untill success for stick in [c.r*1.0, c.r*1.5, c.r*2.0]: # Find subset of points that be "reached by the stick" Is, = np.where(dists<stick) # Calculate angle with circle centre refAng = c.angle2(pp[icurr]) # Culcuate angles with points that are in reach of the stick angs = pp[Is].angle2(pp[icurr]) # Select the points that are in the proper direction # There are TWO PARAMETERS HERE (one important) the second TH can # not be 0.5, because we allow an ellipse. # Use distance measure to make sure not to select the point itself. difAngs = subtract_angles(angs, refAng) difAng2 = difAng2_p # pp[icurr].distance(c) / c.r # Set current too really weid value icurr2, = np.where(Is==icurr) if len(icurr2): difAngs[icurr2] = 99999.0 # Select. If a selection, we're good! II, = np.where( (difAngs > difAng1_p) + (difAngs < difAng2)) if len(II): break else: # No success _objectClearer(showObjects) return Pointset(2) # Select the point with the smallest angle tmp = difAngs[II] inext, = np.where(tmp == tmp.min()) # inext is index in subset. Make it apply to global set inext = Is[ II[ inext[0] ] ] inext = int(inext) # Show if pauseTime>0: # Delete _objectClearer(showObjects) # Show center ob1 = vv.plot(c, ls='', ms='x', mc='r', mw=10, axesAdjust=0) # Show all points ob2 = vv.plot(pp, ls='', ms='.', mc='g', mw=6, axesAdjust=0) # Show selected points L ob3 = vv.plot(pp[L], ls='', ms='.', mc='y', mw=10, axesAdjust=0) # Show next ob4 = vv.plot(pp[inext], ls='', ms='.', mc='r', mw=12, axesAdjust=0) # Show stick vec = ( pp[inext]-pp[icurr] ).normalize() tmp = Pointset(2) tmp.append(pp[icurr]); tmp.append(pp[icurr]+vec*stick) ob5 = vv.plot(tmp, lw=2, lc='b') # Store objects and wait showObjects = [ob1,ob2,ob3,ob4,ob5] fig.DrawNow() time.sleep(pauseTime) # Check whether we completed a full round already if inext in L: break else: L.append(inext) # Prepare for next round icurr = inext # Sort the list by the angles tmp = zip( pp[L].angle2(c), L ) tmp.sort(key=lambda x:x[0]) L = [i[1] for i in tmp] # Clear visualization _objectClearer(showObjects) ## Step 2 and 3, chopstick algorithm to find more points and discard outliers # Init L = [int(i) for i in L] # Make Python ints Lp = [] round = 0 # Iterate ... while Lp != L and round < 20: round += 1 #print 'round', round # Clear list (but store previous) Lp = [i for i in L] L = [] # We need at least three points if len(Lp)<3: _objectClearer(showObjects) print('oops: len(LP)<3' ) return [] # Recalculate circle c = fit_cirlce(pp[Lp], False) if c.r == 0.0: print('oops: c.r==0' ) _objectClearer(showObjects) return [] # Step2: ADD POINTS for iter in range(len(Lp)): # Current point icurr = Lp[iter] if iter < len(Lp)-1: inext = Lp[iter+1] else: inext = Lp[0] # Prepare, get p1 and p2 p1 = pp[icurr] p2 = pp[inext] # Apply masks to points in pp M1, M2 = chopstick_criteria(c, p1, p2, pp) # Combine measures. I is now the subset (of p) of OK points I, = np.where(M1*M2) if not len(I): L.append(icurr) continue elif len(I)==1: ibetw = int(I) else: # Multiple candidates: find best match pptemp = pp[I] dists = p1.distance(pptemp) + p2.distance(pptemp) II, = np.where( dists==dists.min() ) ibetw = int( I[II[0]] ) # Add point L.append(icurr) if not ibetw in L: L.append(ibetw) # Check assert ibetw not in [icurr, inext] # Draw if pauseTime>0: # Delete _objectClearer(showObjects) # Show center ob1 = vv.plot(c, ls='', ms='x', mc='r', mw=10, axesAdjust=0) # Show all points ob2 = vv.plot(pp, ls='', ms='.', mc='g', mw=6, axesAdjust=0) # Show selected points L ob3 = vv.plot(pp[L], ls='', ms='.', mc='y', mw=10, axesAdjust=0) # Show between and vectors ob4 = vv.plot(pp[ibetw], ls='', ms='.', mc='r', mw=12, axesAdjust=0) ob5 = vv.plot(pp[[icurr, ibetw, inext]], ls='-', lc='g', axesAdjust=0) ob6 = vv.plot(pp[[icurr, inext]], ls=':', lc='g', axesAdjust=0) # Store objects and wait showObjects = [ob1,ob2,ob3,ob4,ob5,ob6] fig.DrawNow() time.sleep(pauseTime) # Lpp stores the set of points we have untill now, we will refill the # set L, maybe with less points Lpp = [int(i) for i in L] L = [] # Step3: REMOVE POINTS for iter in range(len(Lpp)): # Current point and neighbours ibetw = Lpp[iter] if iter<len(Lpp)-1: inext = Lpp[iter+1] else: inext = Lpp[0] if iter>0: icurr = Lpp[iter-1] else: icurr = Lpp[-1] # Test # print icurr, ibetw, inext assert ibetw not in [icurr, inext] # Prepare, get p1 and p2 and p3 p1 = pp[icurr] p2 = pp[inext] p3 = pp[ibetw] # Apply masks to points in pp M1, M2 = chopstick_criteria(c, p1, p2, p3) M = M1*M2 # Do we keep the point? if M.sum(): L.append(ibetw) # Draw if pauseTime>0 and not M.sum(): # Delete _objectClearer(showObjects) # Show center ob1 = vv.plot(c, ls='', ms='x', mc='r', mw=10, axesAdjust=0) # Show all points ob2 = vv.plot(pp, ls='', ms='.', mc='g', mw=6, axesAdjust=0) # Show selected points L ob3 = vv.plot(pp[L], ls='', ms='.', mc='y', mw=10, axesAdjust=0) # Show between and vectors ob4 = vv.plot(pp[ibetw], ls='', ms='.', mc='r', mw=12, axesAdjust=0) ob5 = vv.plot(pp[[icurr, ibetw, inext]], ls='-', lc='r', axesAdjust=0) ob6 = vv.plot(pp[[icurr, inext]], ls='-', lc='g', axesAdjust=0) # Store objects and wait showObjects = [ob1,ob2,ob3,ob4,ob5,ob6] fig.DrawNow() time.sleep(pauseTime) # Done if round == 20: print('Warning: chopstick seemed not to converge.') _objectClearer(showObjects) #print 'cluster end', len(L) return pp[L]
def showVolPhases(basedir, vols=None, ptcode=None, ctcode=None, cropname=None, showVol='iso', mipIsocolor=False, isoTh=310, slider=False, clim=(0,3000), clim2D=(-550, 500), fname=None): """ Show vol phases in motion container showVol= mip or iso or 2D; Provide either vols or location """ if vols is None: # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, 'phases', fname=fname) vols = [] for key in dir(s): if key.startswith('vol'): vols.append(s[key]) # Start vis f = vv.figure(1); vv.clf() f.position = 9.00, 38.00, 992.00, 944.00 a = vv.gca() a.daspect = 1, 1, -1 a.axis.axisColor = 1,1,1 a.axis.visible = False a.bgcolor = 0,0,0 if showVol=='mip': if not ptcode is None and not ctcode is None: vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode)) else: vv.title('Maximum intensity projection cine-loop of the original ECG-gated CT volumes ') else: if not ptcode is None and not ctcode is None: vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes of patient %s at %s ' % (ptcode[8:], ctcode)) else: vv.title('ECG-gated CT scan cine-loop of the original ECG-gated CT volumes ') # Setup data container container = vv.MotionDataContainer(a) for vol in vols: if showVol == '2D': t = vv.volshow2(vol, clim=clim2D) # -750, 1000 t.parent = container else: t = vv.volshow(vol, clim=clim, renderStyle = showVol) t.parent = container if showVol == 'iso': t.isoThreshold = isoTh # iso or mip work well t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} if mipIsocolor: t.colormap = {'r': [(0.0, 0.0), (0.17727272, 1.0)], 'g': [(0.0, 0.0), (0.27272728, 1.0)], 'b': [(0.0, 0.0), (0.34545454, 1.0)], 'a': [(0.0, 1.0), (1.0, 1.0)]} # bind ClimEditor to figure if slider: if showVol=='mip': c = vv.ClimEditor(vv.gcf()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) ) if showVol=='iso': c = IsoThEditor(vv.gcf()) c.position = (10, 50) f.eventKeyDown.Bind(lambda event: _utils_GUI.ShowHideSlider(event, c) ) f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, [a]) ) print('------------------------') print('Use keys 1, 2, 3, 4 and 5 for preset anatomic views') print('Use v for a default zoomed view') print('Use x to show and hide axis') print('------------------------') return t
removeStent=removeStent, showmodelavgreg=showmodelavgreg, showvol=showvol, phases=phases, colors=colors, meshWithColors=meshWithColors) vv.title('Model for LSPEAS %s - %s' % (ptcode[7:], ctcode3)) axes.append(ax) #bind view control f.eventKeyDown.Bind( lambda event: _utils_GUI.RotateView(event, axes, axishandling=False)) f.eventKeyDown.Bind(lambda event: _utils_GUI.ViewPresets(event, axes)) ## Set view # a1.SetView(view1) # a2.SetView(view2) # a3.SetView(view3) ## Use same camera #a1.camera = a2.camera = a3.camera if False: a = vv.gca() a.camera = ax.camera ## Save figure if False: vv.screenshot(r'D:\Profiles\koenradesma\Desktop\ZA3_phase90.jpg', vv.gcf(), sf=2) #phantom validation manuscript
def __init__(self, vol, a_transversal, a_coronal, a_sagittal, a_MIP, a_text, nr_of_stents, clim=None): self.nr_of_stents = nr_of_stents self.f = vv.gcf() self.vol = vol # Create empty list of endpoints self.endpoints = [] self.endpoints = ['xx,yy,zz'] * nr_of_stents * 2 self.endpointsindex = 0 # Create text objects self._labelcurrent = vv.Label(a_text) self._labelx = vv.Label(a_text) self._labelxslice = vv.Label(a_text) self._labely = vv.Label(a_text) self._labelyslice = vv.Label(a_text) self._labelz = vv.Label(a_text) self._labelzslice = vv.Label(a_text) self._labelcurrent.position = -250, 10 self._labelx.position = -250, 35 self._labelxslice.position = -200, 35 self._labely.position = -250, 55 self._labelyslice.position = -200, 55 self._labelz.position = -250, 75 self._labelzslice.position = -200, 75 self._labelendpointstext = [] self._labelendpointstext.append(vv.Label(a_text)) self._labelendpointstext[0].position = 100, -5 self._labelendpointstext.append(vv.Label(a_text)) self._labelendpointstext[1].position = 230, -5 for i in range(2, self.nr_of_stents + 2): self._labelendpointstext.append(vv.Label(a_text)) self._labelendpointstext[i].position = 40, 15 + (20 * (i - 2)) self._labelendpoints = [] for i in range(0, self.nr_of_stents * 2, 2): self._labelendpoints.append(vv.Label(a_text)) self._labelendpoints[i].position = 100, 15 + (20 * (i / 2)), 50, 20 self._labelendpoints.append(vv.Label(a_text)) self._labelendpoints[i + 1].position = 230, 15 + (20 * (i / 2)), 50, 20 # Create Select button self._select = False self._butselect = vv.PushButton(a_text) self._butselect.position = -110, 150 self._butselect.text = 'Select' # Create Back button self._back = False self._butback = vv.PushButton(a_text) self._butback.position = 10, 150 self._butback.text = 'Back' # Create Close button self._finished = False self._butclose = vv.PushButton(a_text) self._butclose.position = -50, 180 self._butclose.text = 'Finish' # Get short name for sampling if isinstance(vol, Aarray): self._sam = sam = vol.sampling else: self._sam = None sam = (1, 1, 1) # Display the slices and 3D MIP self.b1 = VolViewer(vol, 0, axes=a_transversal, clim=clim) self.b2 = VolViewer(vol, 1, axes=a_coronal, clim=clim) self.b3 = VolViewer(vol, 2, axes=a_sagittal, clim=clim) renderstyle = 'mip' a_MIP.daspect = 1, 1, -1 self.b4 = vv.volshow(vol, clim=(0, 2500), renderStyle=renderstyle, axes=a_MIP) c = vv.ClimEditor(a_MIP) c.position = (10, 50) # set axis settings for a in [a_transversal, a_coronal, a_sagittal, a_MIP]: a.bgcolor = [0, 0, 0] a.axis.visible = False a.showAxis = True # get current slice number Zslice = self.b1.GetCurrentSlice() Yslice = self.b2.GetCurrentSlice() Xslice = self.b3.GetCurrentSlice() size = vol.shape # create lines for position of x,y and z slices origin = vol.origin Zrange = (origin[0], (size[0] * sam[0]) + origin[0]) Xrange = (origin[1], (size[1] * sam[1]) + origin[1]) Yrange = (origin[2], (size[2] * sam[2]) + origin[2]) self.l11 = vv.Line(a_transversal, [(Yslice, Xrange[0]), (Yslice, Xrange[1])]) self.l12 = vv.Line(a_transversal, [(Yrange[0], Xslice), (Yrange[1], Xslice)]) self.l21 = vv.Line(a_coronal, [(Zslice, Zrange[0]), (Zslice, Zrange[1])]) self.l22 = vv.Line(a_coronal, [(Yrange[0], Xslice), (Yrange[1], Xslice)]) self.l31 = vv.Line(a_sagittal, [(Zslice, Zrange[0]), (Zslice, Zrange[1])]) self.l32 = vv.Line(a_sagittal, [(Xrange[0], Yslice), (Xrange[1], Yslice)]) # change color of the lines for i in [self.l11, self.l12, self.l21, self.l22, self.l31, self.l32]: i.lc = 'g' # create a point in the MIP figure for the current position self.mippoint = vv.Line(a_MIP, [(Zslice, Xslice, Yslice)]) self.mippoint.ms = 'o' self.mippoint.mw = 5 self.mippoint.mc = 'g' self.mippoint.alpha = 0.9 # Get list of all range wobjects self._volviewers = [self.b1, self.b2, self.b3] # Bind events fig = a_text.GetFigure() fig.eventClose.Bind(self._OnFinish) self._butclose.eventPress.Bind(self._OnFinish) self._butselect.eventPress.Bind(self._OnSelect) self._butback.eventPress.Bind(self._OnBack) for r in self._volviewers: r.eventPositionUpdate.Bind(self._OnMouseClickAxis) for s in range(len(self._labelendpoints)): self._labelendpoints[s].eventMouseDown.Bind( self._OnMouseClickEndpoint) # Almost done self._SetTexts() self.updatePosition()
and exported to gif/swf/avi. This is not an interactive example, but a script. """ import visvis as vv # Create something to show, let's show a red teapot! mesh = vv.solidTeapot() mesh.faceColor = 'r' # Prepare Nangles = 36 a = vv.gca() f = vv.gcf() rec = vv.record(a) # Rotate camera for i in range(Nangles): a.camera.azimuth = 360 * float(i) / Nangles if a.camera.azimuth>180: a.camera.azimuth -= 360 a.Draw() # Tell the axes to redraw f.DrawNow() # Draw the figure NOW, instead of waiting for GUI event loop # Export rec.Stop() rec.Export('teapot.gif')
vv.xlabel('x axis') vv.ylabel('y axis') vv.zlabel('z axis') # show print np.sum(data) t = vv.volshow(data,renderStyle='iso',axesAdjust=True) #t.isoThreshold = 0.5 # try the differtent render styles, for examample # "t.renderStyle='iso'" or "t.renderStyle='ray'" # If the drawing hangs, your video drived decided to render in software mode. # This is unfortunately (as far as I know) not possible to detect. # It might help if your data is shaped a power of 2. # Get axes and set camera to orthographic mode (with a field of view of 70) a = vv.gcf() f = vv.gca()#fqwang #a.camera.fov = 45 # Create colormap editor wibject. vv.ColormapEditor(a) rec = vv.record(f) # Rotate camera #fqwang Nangles = 36 for i in range(Nangles): f.camera.azimuth = 360 * float(i) / Nangles if f.camera.azimuth>180:
# Рисуем картинки plot_bg_image(image, z=j.start_level_value) ax = vv.gca() ax.bgcolor = ( 0.7, 0.7, 0.7 ) # We draw path in white by default, so we need a dark background. ax.light0.position = (200, 200, 200, 0) # draw_arcs(ax, j.start_level_value * 1.01, color=(0.5, 0.5, 0.5)) for path in long_normal_paths: if len(path) <= 3: # Для кубического сплайна нужно 4 точки. continue draw_smoothed_path(ax, path, radius=2, color=(1, 1, 1)) # draw_critical_points(ax, 2, level=(j.start_level_value * 1.01), color=(1, 1, 1)) # draw_critical_points(ax, 1, level=(j.start_level_value * 1.01), color=(1, 1, 1)) # draw_critical_points(ax, 0, level=(j.start_level_value * 1.01), color=(1, 1, 1)) # draw_top_points(ax, long_normal_paths, color=(1, 1, 1)) # ax.camera.azimuth = 0. # ax.camera.elevation = 90. ax.camera.azimuth = 45. ax.camera.elevation = 30. ax.camera.daspect = (1, 1, 4) # Увеличиваем масштаб по Z vv.gcf().relativeFontSize = 2.0 # import time # print("Wait for rendering...") # time.sleep(30) # vv.screenshot(args.output, ob=ax)