def generateSpline(markers): aSplineX = vtk.vtkCardinalSpline() aSplineY = vtk.vtkCardinalSpline() aSplineZ = vtk.vtkCardinalSpline() for i, marker in enumerate(markers): center = Vec3f(marker.GetCenter()) if not isinstance(marker, Vec3f) else marker aSplineX.AddPoint(i, center.x) aSplineY.AddPoint(i, center.y) aSplineZ.AddPoint(i, center.z) # Generate the polyline for the spline. points = vtk.vtkPoints() scalars = vtk.vtkFloatArray() # Number of points on the spline splineRes = len(markers)*1 # Interpolate x, y and z by using the three spline filters and # create new points splineList = [] for i in range(splineRes): t = (len(markers)-1.0)/(splineRes-1.0)*i splineList.append((aSplineX.Evaluate(t), aSplineY.Evaluate(t), aSplineZ.Evaluate(t))) points.InsertPoint(i, splineList[-1][0], splineList[-1][1], splineList[-1][2]) scalars.InsertTuple1(i,t) return points, scalars, t, splineList
def resample(xyz, nb_pol=40): """ Resample a fiber with the input specified number of points using VTK. Parameters ---------- xyz: array-like shape (N,3) array representing x,y,z of N points in a track. nb_pol: int integer representing number of points (poles) we need along the curve. """ # Local import import vtk # Construct the VTK fiber interpolation material nb_samples = len(xyz) splinex = vtk.vtkCardinalSpline() spliney = vtk.vtkCardinalSpline() splinez = vtk.vtkCardinalSpline() samples = vtk.vtkPoints() for index in range(nb_samples): x, y, z = xyz[index] splinex.AddPoint(index, x) spliney.AddPoint(index, y) splinez.AddPoint(index, z) samples.InsertPoint(index, x, y, z) # Interpolate x, y and z by using the three spline filters points = [] for index in range(nb_pol): t = (nb_samples - 1.0) / (nb_pol - 1.0) * index points.append( (splinex.Evaluate(t), spliney.Evaluate(t), splinez.Evaluate(t))) return numpy.asarray(points)
def __init__(self, canv, line_color, ctf=None, color=None): """ Constructor. Input Arguments: canv -- The parent Tkinter canvas. line_color -- Line color to use for the piecewise function. ctf -- A vtkColorTransferFunction or a vtkPiecewiseFunction. Defaults to None where the piecewise function is set to a sane default. color -- The color to be used from the vtkColorTransferFunction this has to be one of ['red', 'green', 'blue']. If the color is None (default), then the ctf is treated as a vtkPiecewiseFunction. """ self.xLast = -1.0 self.yLast = -1.0 self.npoints = 101 self.dt = 1.0/(self.npoints - 1) self.canv = canv self.line_color = line_color self.Fxn = vtk.vtkCardinalSpline () self.initialize_ctf() if ctf: if color: self.load_vtkColorTransferFunction (ctf, color) else: self.load_vtkPiecewiseFunction (ctf)
def interpolate_tup3(tups): aSplineX = vtk.vtkCardinalSpline() aSplineY = vtk.vtkCardinalSpline() aSplineZ = vtk.vtkCardinalSpline() for i,tup in enumerate(tups): x,y,z = tup aSplineX.AddPoint(i, x) aSplineY.AddPoint(i, y) aSplineZ.AddPoint(i, z) pnts = [] for i in range(numOutPnts): t = (numInPnts-1.0)/(numOutPnts-1.0)*i pnts.append((aSplineX.Evaluate(t), aSplineY.Evaluate(t), aSplineZ.Evaluate(t))) return pnts
def _vtkspline(points, s, c, alpha, nodes, legend, res): numberOfOutputPoints = len(points) * res # Number of points on the spline numberOfInputPoints = len(points) # One spline for each direction. aSplineX = vtk.vtkCardinalSpline() # interpolate the x values aSplineY = vtk.vtkCardinalSpline() # interpolate the y values aSplineZ = vtk.vtkCardinalSpline() # interpolate the z values inputPoints = vtk.vtkPoints() for i in range(0, numberOfInputPoints): x = points[i][0] y = points[i][1] z = points[i][2] aSplineX.AddPoint(i, x) aSplineY.AddPoint(i, y) aSplineZ.AddPoint(i, z) inputPoints.InsertPoint(i, x, y, z) inputData = vtk.vtkPolyData() inputData.SetPoints(inputPoints) points = vtk.vtkPoints() profileData = vtk.vtkPolyData() for i in range(0, numberOfOutputPoints): t = (numberOfInputPoints - 1.) / (numberOfOutputPoints - 1.) * i x, y, z = aSplineX.Evaluate(t), aSplineY.Evaluate( t), aSplineZ.Evaluate(t) points.InsertPoint(i, x, y, z) lines = vtk.vtkCellArray() # Create the polyline. lines.InsertNextCell(numberOfOutputPoints) for i in range(0, numberOfOutputPoints): lines.InsertCellPoint(i) profileData.SetPoints(points) profileData.SetLines(lines) actline = vu.makeActor(profileData, c=c, alpha=alpha, legend=legend) actline.GetProperty().SetLineWidth(s) actline.GetProperty().SetInterpolationToPhong() if nodes: pts = vu.coordinates(inputData) actnodes = vs.points(pts, r=s * 1.5, c=c, alpha=alpha) ass = vu.makeAssembly([actline, actnodes], legend=legend) return ass else: return actline
def Resample(self, numberOfOutputPoints): sx = vtk.vtkCardinalSpline() sy = vtk.vtkCardinalSpline() counter = 0 for pt in self.points: sx.AddPoint(counter, pt[0]) sy.AddPoint(counter, pt[1]) counter += 1 numberOfInputPoints = len(self.points) ratio = (numberOfInputPoints-1.0) / (numberOfOutputPoints-1.0) spoints = [] for i in range(numberOfOutputPoints): t = ratio * i pt = [ sx.Evaluate(t), sy.Evaluate(t), 0] spoints.append(pt) return spoints
def Resample(self, numberOfOutputPoints): sx = vtk.vtkCardinalSpline() sy = vtk.vtkCardinalSpline() counter = 0 for pt in self.points: sx.AddPoint(counter, pt[0]) sy.AddPoint(counter, pt[1]) counter += 1 numberOfInputPoints = len(self.points) ratio = (numberOfInputPoints - 1.0) / (numberOfOutputPoints - 1.0) spoints = [] for i in range(numberOfOutputPoints): t = ratio * i pt = [sx.Evaluate(t), sy.Evaluate(t), 0] spoints.append(pt) return spoints
def InterpolateTwoCells(startCell, endCell, numberOfSplinePoints, additionalPointId, additionalPoint, type): points = vtk.vtkPoints() xspline = vtk.vtkCardinalSpline() yspline = vtk.vtkCardinalSpline() zspline = vtk.vtkCardinalSpline() numberOfStartCellPoints = startCell.GetNumberOfPoints() numberOfEndCellPoints = endCell.GetNumberOfPoints() endCellFirstId = numberOfSplinePoints - numberOfEndCellPoints for i in range(numberOfStartCellPoints): point = startCell.GetPoints().GetPoint(i) xspline.AddPoint(float(i), point[0]) yspline.AddPoint(float(i), point[1]) zspline.AddPoint(float(i), point[2]) if additionalPoint is not None: xspline.AddPoint(float(additionalPointId), additionalPoint[0]) yspline.AddPoint(float(additionalPointId), additionalPoint[1]) zspline.AddPoint(float(additionalPointId), additionalPoint[2]) for i in range(numberOfEndCellPoints): point = endCell.GetPoints().GetPoint(i) index = float(endCellFirstId + i) xspline.AddPoint(index, point[0]) yspline.AddPoint(index, point[1]) zspline.AddPoint(index, point[2]) xspline.Compute() yspline.Compute() zspline.Compute() points.SetNumberOfPoints(numberOfSplinePoints) for i in range(numberOfSplinePoints): points.SetPoint(i, xspline.Evaluate(float(i)), yspline.Evaluate(float(i)), zspline.Evaluate(float(i))) return points
def InterpolateTwoCells(startCell,endCell,numberOfSplinePoints,additionalPointId,additionalPoint): points = vtk.vtkPoints() xspline = vtk.vtkCardinalSpline() yspline = vtk.vtkCardinalSpline() zspline = vtk.vtkCardinalSpline() numberOfStartCellPoints = startCell.GetNumberOfPoints() numberOfEndCellPoints = endCell.GetNumberOfPoints() endCellFirstId = numberOfSplinePoints - numberOfEndCellPoints numberOfClippedCenterlinePoints = numberOfStartCellPoints + numberOfEndCellPoints for i in range(numberOfStartCellPoints): point = startCell.GetPoints().GetPoint(i) xspline.AddPoint(float(i),point[0]) yspline.AddPoint(float(i),point[1]) zspline.AddPoint(float(i),point[2]) if (useAdditionalInterpolationPoint == 1): xspline.AddPoint(float(additionalPointId),additionalPoint[0]) yspline.AddPoint(float(additionalPointId),additionalPoint[1]) zspline.AddPoint(float(additionalPointId),additionalPoint[2]) for i in range(numberOfEndCellPoints): point = endCell.GetPoints().GetPoint(i) index = endCellFirstId+i xspline.AddPoint(float(endCellFirstId + i),point[0]) yspline.AddPoint(float(endCellFirstId + i),point[1]) zspline.AddPoint(float(endCellFirstId + i),point[2]) xspline.Compute() yspline.Compute() zspline.Compute() points.SetNumberOfPoints(numberOfSplinePoints) for i in range(numberOfSplinePoints): points.SetPoint(i,xspline.Evaluate(float(i)),yspline.Evaluate(float(i)),zspline.Evaluate(float(i))) return points
def resample_points(poly): vs = vtk.vtkStripper() vs.SetInputData(poly) vs.JoinContiguousSegmentsOn() vs.Update() cpd2 = vtk.vtkCleanPolyData() cpd2.SetInputData(vs.GetOutput()) cpd2.Update() bc = cpd2.GetOutput().GetBounds() yl = bc[3] - bc[2] zl = bc[5] - bc[4] yzl = math.sqrt(yl**2 + zl**2) spline = vtk.vtkCardinalSpline() spline.SetLeftConstraint(2) spline.SetLeftValue(0) spline.SetRightConstraint(2) spline.SetRightValue(0) sp_filter = vtk.vtkSplineFilter() sp_filter.SetInputData(cpd2.GetOutput()) num_points = poly.GetNumberOfPoints() sp_filter.SetNumberOfSubdivisions(num_points * 40) sp_filter.SetSpline(spline) sp_filter.Update() def_tol = yzl / 100 print('bound diag = ', yzl) print('max p dist = ', def_tol) cpd = vtk.vtkCleanPolyData() cpd.SetInputData(sp_filter.GetOutput()) cpd.ToleranceIsAbsoluteOn() cpd.PointMergingOn() cpd.ConvertStripsToPolysOn() cpd.GetConvertLinesToPoints() cpd.ConvertPolysToLinesOn() cpd.ToleranceIsAbsoluteOn() cpd.SetAbsoluteTolerance(def_tol) cpd.Update() return cpd.GetOutput()
def ComputeSpline(startValue,endValue,numberOfPoints): averageValue = (startValue + endValue)/2.0 averageId = int(numberOfPoints/2) splineArray = vtk.vtkDoubleArray() splineArray.SetNumberOfComponents(1) splineArray.SetNumberOfTuples(numberOfPoints) splineArray.FillComponent(0,0.0) spline = vtk.vtkCardinalSpline() spline.AddPoint(float(0),startValue) spline.AddPoint(float(averageId),averageValue) spline.AddPoint(float(numberOfPoints),endValue) spline.Compute() for i in range(numberOfPoints): splineArray.SetTuple1(i,spline.Evaluate(float(i))) return splineArray
def ComputeSpline(startValue, endValue, numberOfPoints): averageValue = (startValue + endValue) / 2.0 averageId = int(numberOfPoints / 2) splineArray = vtk.vtkDoubleArray() splineArray.SetNumberOfComponents(1) splineArray.SetNumberOfTuples(numberOfPoints) splineArray.FillComponent(0, 0.0) spline = vtk.vtkCardinalSpline() spline.AddPoint(float(0), startValue) spline.AddPoint(float(averageId), averageValue) spline.AddPoint(float(numberOfPoints), endValue) spline.Compute() for i in range(numberOfPoints): splineArray.SetTuple1(i, spline.Evaluate(float(i))) return splineArray
def compute_orbit(fnames, gname, indir): st = "" for fname in fnames: print " -- Reading scene parameter file : " + fname # # Open input scene file # f = open(fname, "rt") lines = f.readlines() f.close() iline = 0 # # Read header # print " " + lines[iline].strip("\n") iline = iline + 1 sversion = float(lines[iline].strip("\n")) print " %f" % (sversion) iline = iline + 1 # # Read number of frames # print " " + lines[iline].strip("\n") iline = iline + 1 nframe = int(lines[iline]) print " %d" % (nframe) if nframe == 1: print "Single plot!" # # Get colormap filename # iline = iline + 1 print " " + lines[iline].strip("\n") iline = iline + 1 colormap = lines[iline] colormap = colormap.strip("\n") print " " + colormap # # Read camera positions, spline interpolate # iline = iline + 1 print " " + lines[iline].strip("\n") iline = iline + 1 # ncpos = int(lines[iline].strip("\n")) tline = string.splitfields(lines[iline].strip("\n")) ncpos = int(tline[0]) cposClosed = int(tline[1]) if ncpos == 1: circ = True print " Camera moves on circle" else: circ = False print " Camera follows interpolated based on point list" cpos = vtk.vtkPoints() cposSplineX = vtk.vtkCardinalSpline() cposSplineY = vtk.vtkCardinalSpline() cposSplineZ = vtk.vtkCardinalSpline() if circ: cposSplineX.SetClosed(True) cposSplineY.SetClosed(True) cposSplineZ.SetClosed(True) else: cposSplineX.SetClosed(cposClosed) cposSplineY.SetClosed(cposClosed) cposSplineZ.SetClosed(cposClosed) if circ: iline = iline + 1 xpos, ypos, zpos = circle.get_circ_points(lines[iline], nframe) for icpos in range(0, nframe): cpos.InsertPoint(icpos, xpos[icpos], ypos[icpos], zpos[icpos]) cposSplineX.AddPoint(icpos, xpos[icpos]) cposSplineY.AddPoint(icpos, ypos[icpos]) cposSplineZ.AddPoint(icpos, zpos[icpos]) else: for icpos in range(0, ncpos): iline = iline + 1 sline = string.splitfields(lines[iline].strip("\n")) cpos.InsertPoint(icpos, float(sline[0]), float(sline[1]), float(sline[2])) cposSplineX.AddPoint(icpos, float(sline[0])) cposSplineY.AddPoint(icpos, float(sline[1])) cposSplineZ.AddPoint(icpos, float(sline[2])) print " %d" % (icpos) + " : " + sline[0] + " , " + sline[ 1] + " , " + sline[2] # # Read camera focus points, spline interpolate # iline = iline + 1 print " " + lines[iline].strip("\n") iline = iline + 1 # nfpos = int(lines[iline].strip("\n")) tline = string.splitfields(lines[iline].strip("\n")) nfpos = int(tline[0]) fposClosed = int(tline[1]) fpos = vtk.vtkPoints() fposSplineX = vtk.vtkCardinalSpline() fposSplineY = vtk.vtkCardinalSpline() fposSplineZ = vtk.vtkCardinalSpline() fposSplineX.SetClosed(fposClosed) fposSplineY.SetClosed(fposClosed) fposSplineZ.SetClosed(fposClosed) for ifpos in range(0, nfpos): iline = iline + 1 sline = string.splitfields(lines[iline].strip("\n")) fpos.InsertPoint(ifpos, float(sline[0]), float(sline[1]), float(sline[2])) print " %d" % ( ifpos) + " : " + sline[0] + " , " + sline[1] + " , " + sline[2] fposSplineX.AddPoint(ifpos, float(sline[0])) fposSplineY.AddPoint(ifpos, float(sline[1])) fposSplineZ.AddPoint(ifpos, float(sline[2])) # # Read zoom, spline interpolate # iline = iline + 1 print " " + lines[iline].strip("\n") iline = iline + 1 # nzoom = int(lines[iline].strip("\n")) tline = string.splitfields(lines[iline].strip("\n")) nzoom = int(tline[0]) zoomClosed = int(tline[1]) zoom = vtk.vtkPoints() zoomSplineX = vtk.vtkCardinalSpline() zoomSplineX.SetClosed(zoomClosed) for izoom in range(0, nzoom): iline = iline + 1 zoom.InsertPoint(izoom, float(lines[iline]), 0.0, 0.0) print " %d" % (izoom) + " : " + lines[iline].strip("\n") zoomSplineX.AddPoint(izoom, float(lines[iline])) # # Read camera view up vector # iline = iline + 1 print " " + lines[iline].strip("\n") iline = iline + 1 # nvpos = int(lines[iline].strip("\n")) tline = string.splitfields(lines[iline].strip("\n")) nvpos = int(tline[0]) vposClosed = int(tline[1]) vpos = vtk.vtkPoints() vposSplineX = vtk.vtkCardinalSpline() vposSplineY = vtk.vtkCardinalSpline() vposSplineZ = vtk.vtkCardinalSpline() vposSplineX.SetClosed(vposClosed) vposSplineY.SetClosed(vposClosed) vposSplineZ.SetClosed(vposClosed) for ivpos in range(0, nvpos): iline = iline + 1 sline = string.splitfields(lines[iline].strip("\n")) vpos.InsertPoint(ivpos, float(sline[0]), float(sline[1]), float(sline[2])) vposSplineX.AddPoint(ivpos, float(sline[0])) vposSplineY.AddPoint(ivpos, float(sline[1])) vposSplineZ.AddPoint(ivpos, float(sline[2])) print " %d" % ( ivpos) + " : " + sline[0] + " , " + sline[1] + " , " + sline[2] # # Read file name and data file animation parameters # iline = iline + 1 print " " + lines[iline].strip("\n") iline = iline + 1 nstart = int(lines[iline]) print " nstart : " + lines[iline].strip("\n") iline = iline + 1 nstep = int(lines[iline]) print " nstep : " + lines[iline].strip("\n") iline = iline + 1 nfield = int(lines[iline].strip("\n")) print " nfield : " + lines[iline].strip("\n") iline = iline + 1 nend = int(lines[iline]) print " nend : " + lines[iline].strip("\n") iline = iline + 1 nrestart = int(lines[iline]) print " nrestart : " + lines[iline].strip("\n") iline = iline + 1 sname = string.splitfields(lines[iline], "*") # print "Length of sname string" + str(len(sname)) # if sname[0].strip("\n") == "none": # sname[0] = sname[0].strip("\n") # sname.extend(["\n"]) # else: # sname[1] = sname[1].strip("\n") # print " Name of field : " + str(sname) if len(sname) == 1: if sname[0].strip("\n") == "none": sname[0] = sname[0].strip("\n") sname.extend(["\n"]) else: sname[0] = sname[0].strip("\n") # sname.extend(["\n"]) else: sname[1] = sname[1].strip("\n") print " Name of field : " + str(sname) # # Read spline parameter (not used at the moment) # iline = iline + 1 print " " + lines[iline].strip("\n") iline = iline + 1 closedSpline = int(lines[iline].strip("\n")) # # Close spline curves # # if closedSpline: # fposSplineX.SetClosed(True) # fposSplineY.SetClosed(True) # fposSplineZ.SetClosed(True) # cposSplineX.SetClosed(True) # cposSplineY.SetClosed(True) # cposSplineZ.SetClosed(True) # zoomSplineX.SetClosed(True) # vposSplineX.SetClosed(True) # vposSplineY.SetClosed(True) # vposSplineZ.SetClosed(True) # else: # fposSplineX.SetClosed(False) # fposSplineY.SetClosed(False) # fposSplineZ.SetClosed(False) # cposSplineX.SetClosed(False) # cposSplineY.SetClosed(False) # cposSplineZ.SetClosed(False) # zoomSplineX.SetClosed(False) # vposSplineX.SetClosed(False) # vposSplineY.SetClosed(False) # vposSplineZ.SetClosed(False) # # Generate file name of data to be read # hname = [] ifile = nstart - nstep for iframe in range(0, nframe): if (iframe % nfield == 0): ifile = ifile + nstep if ifile > nend: ifile = nrestart print "Starting from first data field again..." if sname[0] == "none": nname = sname[0] elif len(sname) == 1: nname = indir + sname[0] else: nname = indir + sname[0] + "%(nnum)04d" % { 'nnum': ifile } + sname[1] # print "The name of the data file is " + nname hname.extend([nname]) # # Generate a polyline for the spline # cposPoints = vtk.vtkPoints() fposPoints = vtk.vtkPoints() zoomPoints = vtk.vtkPoints() vposPoints = vtk.vtkPoints() # # Interpolate x, y and z by using the three spline filters and # create new points # if (nframe > 1): cpos = [0.0, 0.0, 0.0] fpos = [0.0, 0.0, 0.0] zoom = [0.0] vpos = [0.0, 0.0, 0.0] for iframe in range(0, nframe): if circ: t = iframe else: if cposClosed: t = float(ncpos) / float(nframe) * iframe else: t = (ncpos - 1.0) / (nframe - 1.0) * iframe # print ":::: %f" %(t) + " ncpos %d" %(ncpos) cpos[0] = cposSplineX.Evaluate(t) cpos[1] = cposSplineY.Evaluate(t) cpos[2] = cposSplineZ.Evaluate(t) cposPoints.InsertPoint(iframe, cpos[0], cpos[1], cpos[2]) if fposClosed: t = float(nfpos) / float(nframe) * iframe else: t = (nfpos - 1.0) / (nframe - 1.0) * iframe fpos[0] = fposSplineX.Evaluate(t) fpos[1] = fposSplineY.Evaluate(t) fpos[2] = fposSplineZ.Evaluate(t) fposPoints.InsertPoint(iframe, fpos[0], fpos[1], fpos[2]) if zoomClosed: t = float(nzoom) / float(nframe) * iframe else: t = (nzoom - 1.0) / (nframe - 1.0) * iframe zoom[0] = zoomSplineX.Evaluate(t) zoomPoints.InsertPoint(iframe, zoom[0], 0.0, 0.0) if vposClosed: t = float(nvpos) / float(nframe) * iframe else: t = (nvpos - 1.0) / (nframe - 1.0) * iframe vpos[0] = vposSplineX.Evaluate(t) vpos[1] = vposSplineY.Evaluate(t) vpos[2] = vposSplineZ.Evaluate(t) vposPoints.InsertPoint(iframe, vpos[0], vpos[1], vpos[2]) st += str(cpos[0]) + " " + str(cpos[1]) + " " + str( cpos[2]) + " " st += str(fpos[0]) + " " + str(fpos[1]) + " " + str( fpos[2]) + " " st += str(zoom[0]) + " " st += str(vpos[0]) + " " + str(vpos[1]) + " " + str( vpos[2]) + " " st += hname[iframe] + " " + colormap + "\n" else: ccpos = cpos.GetPoint(0) ffpos = fpos.GetPoint(0) zzoom = zoom.GetPoint(0) vvpos = vpos.GetPoint(0) st += str(ccpos[0]) + " " + str(ccpos[1]) + " " + str( ccpos[2]) + " " st += str(ffpos[0]) + " " + str(ffpos[1]) + " " + str( ffpos[2]) + " " st += str(zzoom[0]) + " " st += str(vvpos[0]) + " " + str(vvpos[1]) + " " + str( vvpos[2]) + " " st += hname[iframe] + " " + colormap + "\n" # # Analyze trajectory file and count how many fields that are the same grouped together and add # that information in a new column. This is used to determine how many loops that should be # done before exit single_frame... and read in a new field # stlines = string.splitfields(st, "\n") nlines = len(stlines) print "Number of lines in trajectory file " + str(nlines) # neqlines_list = [] # iline = 0 # icolumn = 10 # while iline < nlines - 1: # split_string = string.splitfields(stlines[iline].strip("\n")," ") # column_string = split_string[icolumn] # neqlines = countLines(column_string,stlines[iline+1:],icolumn) # iline = iline + neqlines # neqlines_list.extend([neqlines]) #print ":::" + neqlines_list # # Add index column in the rightmost column # for istr in range(0, nlines - 1): stlines[istr] = stlines[istr] + " " + str(istr) + "\n" # # Write output file # g = open(gname, 'w') g.writelines(stlines) g.close()
def get_actors(args = None): # This will be used later to get random numbers. math = vtk.vtkMath() # Total number of points. numberOfInputPoints = 20 # One spline for each direction. aSplineX = vtk.vtkCardinalSpline() aSplineY = vtk.vtkCardinalSpline() aSplineZ = vtk.vtkCardinalSpline() # Generate random (pivot) points and add the corresponding # coordinates to the splines. # aSplineX will interpolate the x values of the points # aSplineY will interpolate the y values of the points # aSplineZ will interpolate the z values of the points inputPoints = vtk.vtkPoints() for i in range(0, numberOfInputPoints): x = math.Random(0, 1) y = math.Random(0, 1) z = math.Random(0, 1) aSplineX.AddPoint(i, x) aSplineY.AddPoint(i, y) aSplineZ.AddPoint(i, z) inputPoints.InsertPoint(i, x, y, z) # The following section will create glyphs for the pivot points # in order to make the effect of the spline more clear. # Create a polydata to be glyphed. inputData = vtk.vtkPolyData() inputData.SetPoints(inputPoints) # Use sphere as glyph source. balls = vtk.vtkSphereSource() balls.SetRadius(.01) balls.SetPhiResolution(10) balls.SetThetaResolution(10) glyphPoints = vtk.vtkGlyph3D() glyphPoints.SetInput(inputData) glyphPoints.SetSource(balls.GetOutput()) glyphMapper = vtk.vtkPolyDataMapper() glyphMapper.SetInputConnection(glyphPoints.GetOutputPort()) glyph = vtk.vtkActor() glyph.SetMapper(glyphMapper) glyph.GetProperty().SetDiffuseColor(tomato) glyph.GetProperty().SetSpecular(.3) glyph.GetProperty().SetSpecularPower(30) # Generate the polyline for the spline. points = vtk.vtkPoints() profileData = vtk.vtkPolyData() # Number of points on the spline numberOfOutputPoints = 400 # Interpolate x, y and z by using the three spline filters and # create new points for i in range(0, numberOfOutputPoints): t = (numberOfInputPoints-1.0)/(numberOfOutputPoints-1.0)*i points.InsertPoint(i, aSplineX.Evaluate(t), aSplineY.Evaluate(t), aSplineZ.Evaluate(t)) # Create the polyline. lines = vtk.vtkCellArray() lines.InsertNextCell(numberOfOutputPoints) for i in range(0, numberOfOutputPoints): lines.InsertCellPoint(i) profileData.SetPoints(points) profileData.SetLines(lines) # Add thickness to the resulting line. profileTubes = vtk.vtkTubeFilter() profileTubes.SetNumberOfSides(8) profileTubes.SetInput(profileData) profileTubes.SetRadius(.005) profileMapper = vtk.vtkPolyDataMapper() profileMapper.SetInputConnection(profileTubes.GetOutputPort()) profile = vtk.vtkActor() profile.SetMapper(profileMapper) profile.GetProperty().SetDiffuseColor(banana) profile.GetProperty().SetSpecular(.3) profile.GetProperty().SetSpecularPower(30) return (glyph, profile)
def DrawTrajectory(): nbrPoints = 1000 w0 = array([0.0, 1.0, 0.0]) time = linspace(0.0, 40.0, nbrPoints) trajectory = integrate.odeint(Lorenz, w0, time,args=()) # Total number of points. numberOfInputPoints = nbrPoints # One spline for each direction. aSplineX = vtk.vtkCardinalSpline() aSplineY = vtk.vtkCardinalSpline() aSplineZ = vtk.vtkCardinalSpline() inputPoints = vtk.vtkPoints() for i in range(0, numberOfInputPoints): x = trajectory[i,0] y = trajectory[i,1] z = trajectory[i,2] aSplineX.AddPoint(i, trajectory[i,0]) aSplineY.AddPoint(i, trajectory[i,1]) aSplineZ.AddPoint(i, trajectory[i,2]) inputPoints.InsertPoint(i, x, y, z) # The following section will create glyphs for the pivot points # in order to make the effect of the spline more clear. # Create a polydata to be glyphed. inputData = vtk.vtkPolyData() inputData.SetPoints(inputPoints) # Use sphere as glyph source. balls = vtk.vtkSphereSource() balls.SetRadius(.01) balls.SetPhiResolution(10) balls.SetThetaResolution(10) glyphPoints = vtk.vtkGlyph3D() glyphPoints.SetInputData(inputData) glyphPoints.SetSourceConnection(balls.GetOutputPort()) glyphMapper = vtk.vtkPolyDataMapper() glyphMapper.SetInputConnection(glyphPoints.GetOutputPort()) glyph = vtk.vtkActor() glyph.SetMapper(glyphMapper) glyph.GetProperty().SetDiffuseColor(tomato) glyph.GetProperty().SetSpecular(.3) glyph.GetProperty().SetSpecularPower(30) # Generate the polyline for the spline. points = vtk.vtkPoints() profileData = vtk.vtkPolyData() # Number of points on the spline numberOfOutputPoints = nbrPoints*10 # Interpolate x, y and z by using the three spline filters and # create new points for i in range(0, numberOfOutputPoints): t = (numberOfInputPoints-1.0)/(numberOfOutputPoints-1.0)*i points.InsertPoint(i, aSplineX.Evaluate(t), aSplineY.Evaluate(t), aSplineZ.Evaluate(t)) # Create the polyline. lines = vtk.vtkCellArray() lines.InsertNextCell(numberOfOutputPoints) for i in range(0, numberOfOutputPoints): lines.InsertCellPoint(i) profileData.SetPoints(points) profileData.SetLines(lines) # Add thickness to the resulting line. profileTubes = vtk.vtkTubeFilter() profileTubes.SetNumberOfSides(8) profileTubes.SetInputData(profileData) profileTubes.SetRadius(.05) profileMapper = vtk.vtkPolyDataMapper() profileMapper.SetInputConnection(profileTubes.GetOutputPort()) profile = vtk.vtkActor() profile.SetMapper(profileMapper) profile.GetProperty().SetDiffuseColor(gold) profile.GetProperty().SetSpecular(.3) profile.GetProperty().SetSpecularPower(30) return glyph, profile
renWin.AddRenderer(ren1) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) # math = vtk.vtkMath() numberOfInputPoints = 30 aKSplineX = vtk.vtkKochanekSpline() aKSplineX.ClosedOn() aKSplineY = vtk.vtkKochanekSpline() aKSplineY.ClosedOn() aKSplineZ = vtk.vtkKochanekSpline() aKSplineZ.ClosedOn() aCSplineX = vtk.vtkCardinalSpline() aCSplineX.ClosedOn() aCSplineY = vtk.vtkCardinalSpline() aCSplineY.ClosedOn() aCSplineZ = vtk.vtkCardinalSpline() aCSplineZ.ClosedOn() # add some points inputPoints = vtk.vtkPoints() x = -1.0 y = -1.0 z = 0.0 aKSplineX.AddPoint(0, x) aKSplineY.AddPoint(0, y) aKSplineZ.AddPoint(0, z) aCSplineX.AddPoint(0, x)
def main(): parser = OptionParser(usage="Usage: %prog [options] <tract.vtp>") parser.add_option("-s", "--scalar", dest="scalar", default="FA", help="Scalar to measure") parser.add_option("-n", "--num", dest="num", default=50, type='int', help="Number of subdivisions along centroids") parser.add_option("-l", "--local", dest="is_local", action="store_true", default=False, help="Measure from Quickbundle assigned streamlines. Default is to measure from all streamlines") parser.add_option("-d", "--dist", dest="dist", default=20, type='float', help="Quickbundle distance threshold") parser.add_option("--curvepoints", dest="curvepoints_file", help="Define a curve to use as centroid. Control points are defined in a csv file in the same space as the tract points. The curve is the vtk cardinal spline implementation, which is a catmull-rom spline.") parser.add_option('--yrange', dest='yrange') parser.add_option('--xrange', dest='xrange') parser.add_option('--reverse', dest='is_reverse', action='store_true', default=False, help='Reverse the centroid measure stepping order') parser.add_option('--pairplot', dest='pairplot',) parser.add_option('--noviz', dest='is_viz', action='store_false', default=True) parser.add_option('--hide-centroid', dest='show_centroid', action='store_false', default=True) parser.add_option('--config', dest='config') parser.add_option('--background', dest='bg_file', help='Background NIFTI image') parser.add_option('--annot', dest='annot') (options, args) = parser.parse_args() if len(args) == 0: parser.print_help() sys.exit(2) name_mapping = None if options.config: config = GtsConfig(options.config, configure=False) name_mapping = config.group_labels annotations = None if options.annot: with open(options.annot, 'r') as fp: annotations = yaml.load(fp) QB_DIST = options.dist QB_NPOINTS = options.num SCALAR_NAME = options.scalar LOCAL_POINT_ASSIGN = options.is_local filename = args[0] filebase = path.basename(filename).split('.')[0] reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(filename) reader.Update() polydata = reader.GetOutput() tract_ids = [] for i in range(polydata.GetNumberOfCells()): # get point ids in [[ids][ids...]...] format pids = polydata.GetCell(i).GetPointIds() ids = [pids.GetId(p) for p in range(pids.GetNumberOfIds())] tract_ids.append(ids) print 'tracks:', len(tract_ids) verts = vtk_to_numpy(polydata.GetPoints().GetData()) print 'verts:', len(verts) scalars = [] groups = [] subjects = [] pointdata = polydata.GetPointData() for si in range(pointdata.GetNumberOfArrays()): sname = pointdata.GetArrayName(si) print sname if sname == SCALAR_NAME: scalars = vtk_to_numpy(pointdata.GetArray(si)) if sname == 'group': groups = vtk_to_numpy(pointdata.GetArray(si)) groups = groups.astype(int) if sname == 'tid': subjects = vtk_to_numpy(pointdata.GetArray(si)) subjects = subjects.astype(int) streamlines = [] stream_scalars = [] stream_groups = [] stream_pids = [] stream_sids = [] for i in tract_ids: # index np.array by a list will get all the respective indices streamlines.append(verts[i]) stream_scalars.append(scalars[i]) stream_pids.append(i) stream_sids.append(subjects[i]) try: stream_groups.append(groups[i]) except Exception: # group might not exist pass streamlines = np.array(streamlines) stream_scalars = np.array(stream_scalars) stream_groups = np.array(stream_groups) stream_pids = np.array(stream_pids) stream_sids = np.array(stream_sids) # get total average direction (where majority point towards) avg_d = np.zeros(3) # for line in streams: # d = np.array(line[-1]) - np.array(line[0]) # d = d / la.norm(d) # avg_d += d # avg_d /= la.norm(avg_d) avg_com = np.zeros(3) avg_mid = np.zeros(3) strl_len = [len(l) for l in streamlines] stl_ori = np.array([np.abs(tm.mean_orientation(l)) for l in streamlines]) centroids = [] if options.curvepoints_file: LOCAL_POINT_ASSIGN = False cpoints = [] ctrlpoints = np.loadtxt(options.curvepoints_file, delimiter=',') # have a separate vtkCardinalSpline interpreter for x,y,z curve = [vtk.vtkCardinalSpline() for i in range(3)] for c in curve: c.ClosedOff() for pi, point in enumerate(ctrlpoints): for i, val in enumerate(point): curve[i].AddPoint(pi, point[i]) param_range = [0.0, 0.0] curve[0].GetParametricRange(param_range) t = param_range[0] step = (param_range[1] - param_range[0]) / (QB_NPOINTS - 1.0) while t < param_range[1]: cp = [c.Evaluate(t) for c in curve] cpoints.append(cp) t = t + step centroids.append(cpoints) centroids = np.array(centroids) else: """ Use quickbundles to find centroids """ # streamlines = newlines qb = QuickBundles(streamlines, dist_thr=QB_DIST, pts=QB_NPOINTS) # bundle_distance_mam centroids = qb.centroids clusters = qb.clusters() avg_d = np.zeros(3) avg_com = np.zeros(3) avg_mid = np.zeros(3) #unify centroid list orders to point in the same general direction for i, line in enumerate(centroids): ori = np.array(tm.mean_orientation(line)) #d = np.array(line[-1]) - np.array(line[0]) #print line[-1],line[0],d # get the unit vector of the mean orientation if i == 0: avg_d = ori #d = d / la.norm(d) dotprod = ori.dot(avg_d) print 'dotprod', dotprod if dotprod < 0: print 'reverse', dotprod centroids[i] = line[::-1] line = centroids[i] ori *= -1 avg_d += ori if options.is_reverse: for i, c in enumerate(centroids): centroids[i] = c[::-1] # prepare mayavi 3d viz if options.is_viz: bg_val = 0. fig = mlab.figure(bgcolor=(bg_val, bg_val, bg_val)) scene = mlab.gcf().scene fig.scene.render_window.aa_frames = 4 mlab.draw() if options.bg_file: mrsrc, bgdata = getNiftiAsScalarField(options.bg_file) orie = 'z_axes' opacity = 0.5 slice_index = 0 mlab.pipeline.image_plane_widget(mrsrc, opacity=opacity, plane_orientation=orie, slice_index=int( slice_index), colormap='black-white', line_width=0, reset_zoom=False) # prepare the plt plot len_cent = len(centroids) pal = sns.color_palette("bright", len_cent) DATADF = None """ CENTROIDS """ for ci, cent in enumerate(centroids): print '---- centroid:' if LOCAL_POINT_ASSIGN: """ apply centroid to only their point assignments through quickbundles """ ind = clusters[ci]['indices'] cent_streams = streamlines[ind] cent_scalars = stream_scalars[ind] cent_groups = stream_groups[ind] cent_pids = stream_pids[ind] cent_sids = stream_sids[ind] else: # apply each centriod to all the points # instead of only their centroid assignments cent_streams = streamlines cent_scalars = stream_scalars cent_groups = stream_groups cent_pids = stream_pids cent_sids = stream_sids cent_verts = np.vstack(cent_streams) cent_scalars = np.concatenate(cent_scalars) cent_groups = np.concatenate(cent_groups) cent_pids = np.concatenate(cent_pids) cent_sids = np.concatenate(cent_sids) cent_color = np.array(pal[ci]) c, labels = kmeans2(cent_verts, cent, iter=1) cid = np.ones(len(labels)) d = {'value': cent_scalars, 'position': labels, 'group': cent_groups, 'pid': cent_pids, 'sid': cent_sids} df = pd.DataFrame(data=d) if DATADF is None: DATADF = df else: pd.concat([DATADF, df]) UNIQ_GROUPS = df.group.unique() UNIQ_GROUPS.sort() # UNIQ_GROUPS = [0,1] grppal = sns.color_palette("Set2", len(UNIQ_GROUPS)) print '# UNIQ GROUPS', UNIQ_GROUPS # print df # df = df[df['sid'] != 15] # df = df[df['sid'] != 16] # df = df[df['sid'] != 17] # df = df[df['sid'] != 18] """ plot each group by their position """ fig = plt.figure(figsize=(14, 7)) ax1 = plt.subplot2grid((4, 3), (0, 0), colspan=3, rowspan=3) ax2 = plt.subplot2grid((4, 3), (3, 0), colspan=3, sharex=ax1) axes = [ax1, ax2] plt.xlabel('Position Index') if len(centroids) > 1: cent_patch = mpatches.Patch( color=cent_color, label='Centroid {}'.format(ci + 1)) cent_legend = axes[0].legend(handles=[cent_patch], loc=9) axes[0].add_artist(cent_legend) """ Perform stats """ if len(UNIQ_GROUPS) > 1: # df = resample_data(df, num_sample_per_pos=120) # print df pvalsDf = position_stats(df, name_mapping=name_mapping) logpvals = np.log(pvalsDf) * -1 # print logpvals pvals = logpvals.mask(pvalsDf >= 0.05) import matplotlib.ticker as mticker print pvals cmap = mcmap.Reds cmap.set_bad('w', 1.) axes[1].pcolormesh(pvals.values.T, cmap=cmap, vmin=0, vmax=10, edgecolors='face', alpha=0.8) #axes[1].yaxis.set_major_locator(mticker.MultipleLocator(base=1.0)) axes[1].set_yticks( np.arange(pvals.values.shape[1]) + 0.5, minor=False) axes[1].set_yticklabels( pvalsDf.columns.values.tolist(), minor=False) legend_handles = [] for gi, GRP in enumerate(UNIQ_GROUPS): print '-------------------- GROUP ', gi, '----------------------' subgrp = df[df['group'] == GRP] print len(subgrp) if options.xrange: x0, x1 = options.xrange.split(',') x0 = int(x0) x1 = int(x1) subgrp = subgrp[(subgrp['position'] >= x0) & (subgrp['position'] < x1)] posGrp = subgrp.groupby('position', sort=True) cent_stats = posGrp.apply(lambda x: stats_per_group(x)) if len(cent_stats) == 0: continue cent_stats = cent_stats.unstack() cent_median_scalar = cent_stats['median'].tolist() x = np.array([i for i in posGrp.groups]) # print x # print cent_stats['median'].tolist() mcolor = np.array(grppal[gi]) # if gi>0: # mcolor*= 1./(1+gi) cent_color = tuple(cent_color) mcolor = tuple(mcolor) if type(axes) is list: cur_axe = axes[0] else: cur_axe = axes cur_axe.set_ylabel(SCALAR_NAME) # cur_axe.yaxis.label.set_color(cent_color) # cur_axe.tick_params(axis='y', colors=cent_color) #cur_axe.fill_between(x, [s[0] for s in cent_ci], [t[1] for t in cent_ci], alpha=0.3, color=mcolor) # cur_axe.fill_between(x, [s[0] for s in cent_stats['whisk'].tolist()], # [t[1] for t in cent_stats['whisk'].tolist()], alpha=0.1, color=mcolor) qtile_top = np.array([s[0] for s in cent_stats['ci'].tolist()]) qtile_bottom = np.array([t[1] for t in cent_stats['ci'].tolist()]) x_new, qtop_sm = smooth(x, qtile_top) x_new, qbottom_sm = smooth(x, qtile_bottom) cur_axe.fill_between(x_new, qtop_sm, qbottom_sm, alpha=0.25, color=mcolor) # cur_axe.errorbar(x, cent_stats['median'].tolist(), yerr=[[s[0] for s in cent_stats['err'].tolist()], # [t[1] for t in cent_stats['err'].tolist()]], color=mcolor, alpha=0.1) x_new, median_sm = smooth(x, cent_stats['median']) hnd, = cur_axe.plot(x_new, median_sm, c=mcolor) legend_handles.append(hnd) # cur_axe.scatter(x,cent_stats['median'].tolist(), c=mcolor) if options.yrange: plotrange = options.yrange.split(',') cur_axe.set_ylim([float(plotrange[0]), float(plotrange[1])]) legend_labels = UNIQ_GROUPS if name_mapping is not None: legend_labels = [name_mapping[str(i)] for i in UNIQ_GROUPS] cur_axe.legend(legend_handles, legend_labels) if annotations: for key, val in annotations.iteritems(): # print key cur_axe.axvspan(val[0], val[1], fill=False, linestyle='dashed') axis_to_data = cur_axe.transAxes + cur_axe.transData.inverted() data_to_axis = axis_to_data.inverted() axpoint = data_to_axis.transform((val[0], 0)) # print axpoint cur_axe.text(axpoint[0], 1.02, key, transform=cur_axe.transAxes) """ Plot 3D Viz """ if options.is_viz: scene.disable_render = True # scene.renderer.render_window.set(alpha_bit_planes=1,multi_samples=0) # scene.renderer.set(use_depth_peeling=True,maximum_number_of_peels=4,occlusion_ratio=0.1) # ran_colors = np.random.random_integers(255, size=(len(cent),4)) # ran_colors[:,-1] = 255 mypts = mlab.points3d(cent_verts[:, 0], cent_verts[:, 1], cent_verts[:, 2], labels, opacity=0.3, scale_mode='none', scale_factor=2, line_width=2, colormap='blue-red', mode='point') # print mypts.module_manager.scalar_lut_manager.lut.table.to_array() # mypts.module_manager.scalar_lut_manager.lut.table = ran_colors # mypts.module_manager.scalar_lut_manager.lut.number_of_colors = len(ran_colors) delta = len(cent) - len(cent_median_scalar) if delta > 0: cent_median_scalar = np.pad( cent_median_scalar, (0, delta), mode='constant', constant_values=0) # calculate the displacement vector for all pairs uvw = cent - np.roll(cent, 1, axis=0) uvw[0] *= 0 uvw = np.roll(uvw, -1, axis=0) arrow_plot = mlab.quiver3d( cent[:, 0], cent[:, 1], cent[:, 2], uvw[:, 0], uvw[:, 1], uvw[:, 2], scalars=cent_median_scalar, scale_factor=1, #color=mcolor, mode='arrow') gsource = arrow_plot.glyph.glyph_source.glyph_source # for name, thing in inspect.getmembers(gsource): # print name arrow_plot.glyph.color_mode = 'color_by_scalar' #arrow_plot.glyph.scale_mode = 'scale_by_scalar' #arrow_plot.glyph.glyph.clamping = True #arrow_plot.glyph.glyph.scale_factor = 5 #print arrow_plot.glyph.glyph.glyph_source gsource.tip_length = 0.4 gsource.shaft_radius = 0.2 gsource.tip_radius = 0.3 if options.show_centroid: tube_plot = mlab.plot3d(cent[:, 0], cent[:, 1], cent[ :, 2], cent_median_scalar, color=cent_color, tube_radius=0.2, opacity=0.25) tube_filter = tube_plot.parent.parent.filter tube_filter.vary_radius = 'vary_radius_by_scalar' tube_filter.radius_factor = 10 # plot first and last def plot_pos_index(p): pos = cent[p] mlab.text3d(pos[0], pos[1], pos[2], str(p), scale=0.8) for p in xrange(0, len(cent - 1), 10): plot_pos_index(p) plot_pos_index(len(cent) - 1) scene.disable_render = False DATADF.to_csv( '_'.join([filebase, SCALAR_NAME, 'rawdata.csv']), index=False) outfile = '_'.join([filebase, SCALAR_NAME]) print 'save to {}'.format(outfile) plt.savefig('{}.pdf'.format(outfile), dpi=300) if options.is_viz: plt.show(block=False) mlab.show()
def Execute(self): if self.Centerlines == None: self.PrintError('Error: No input centerlines.') maskArray = self.Centerlines.GetPointData().GetArray( self.MaskArrayName) numberOfArrays = self.Centerlines.GetPointData().GetNumberOfArrays() for i in range(self.Centerlines.GetNumberOfCells()): cell = self.Centerlines.GetCell(i) xSpline = vtk.vtkCardinalSpline() ySpline = vtk.vtkCardinalSpline() zSpline = vtk.vtkCardinalSpline() aSplines = [] for j in range(numberOfArrays): aSplines.append(vtk.vtkCardinalSpline()) abscissaArray = vtk.vtkFloatArray() abscissa = 0.0 previousPoint = None for j in range(cell.GetNumberOfPoints()): pointId = cell.GetPointId(j) point = self.Centerlines.GetPoint(pointId) if previousPoint: abscissa += vtk.vtkDistance2BetweenPoints( point, previousPoint)**0.5 abscissaArray.InsertNextValue(abscissa) if not self.IsMasked(maskArray.GetTuple1(pointId)): xSpline.AddPoint(abscissa, point[0]) ySpline.AddPoint(abscissa, point[1]) zSpline.AddPoint(abscissa, point[2]) for k in range(numberOfArrays): array = self.Centerlines.GetPointData().GetArray(k) if array.GetNumberOfComponents() != 1: continue value = array.GetTuple1(pointId) aSplines[k].AddPoint(abscissa, value) previousPoint = point for j in range(cell.GetNumberOfPoints()): pointId = cell.GetPointId(j) if not self.IsMasked(maskArray.GetTuple1(pointId)): continue abscissa = abscissaArray.GetValue(pointId) point = [ xSpline.Evaluate(abscissa), ySpline.Evaluate(abscissa), zSpline.Evaluate(abscissa) ] self.Centerlines.SetPoint(pointId, point) for k in range(numberOfArrays): array = self.Centerlines.GetPointData().GetArray(k) if array.GetNumberOfComponents() != 1: continue value = aSplines[k].Evaluate(abscissa) array.SetTuple1(pointId, value)
#!/usr/bin/env python # This example demonstrates the use of vtkCardinalSpline. # It creates random points and connects them with a spline import vtk from vtk.util.colors import tomato, banana # This will be used later to get random numbers. math = vtk.vtkMath() # Total number of points. numberOfInputPoints = 10 # One spline for each direction. aSplineX = vtk.vtkCardinalSpline() aSplineY = vtk.vtkCardinalSpline() aSplineZ = vtk.vtkCardinalSpline() # Generate random (pivot) points and add the corresponding # coordinates to the splines. # aSplineX will interpolate the x values of the points # aSplineY will interpolate the y values of the points # aSplineZ will interpolate the z values of the points inputPoints = vtk.vtkPoints() for i in range(0, numberOfInputPoints): x = math.Random(0, 1) y = math.Random(0, 1) z = math.Random(0, 1) aSplineX.AddPoint(i, x) aSplineY.AddPoint(i, y)
def Execute(self): if self.Centerlines == None: self.PrintError('Error: No input centerlines.') maskArray = self.Centerlines.GetPointData().GetArray(self.MaskArrayName) numberOfArrays = self.Centerlines.GetPointData().GetNumberOfArrays() for i in range(self.Centerlines.GetNumberOfCells()): cell = self.Centerlines.GetCell(i) xSpline = vtk.vtkCardinalSpline() ySpline = vtk.vtkCardinalSpline() zSpline = vtk.vtkCardinalSpline() aSplines = [] for j in range(numberOfArrays): aSplines.append(vtk.vtkCardinalSpline()) abscissaArray = vtk.vtkFloatArray() abscissa = 0.0 previousPoint = None for j in range(cell.GetNumberOfPoints()): pointId = cell.GetPointId(j) point = self.Centerlines.GetPoint(pointId) if previousPoint: abscissa += vtk.vtkMath.Distance2BetweenPoints(point,previousPoint)**0.5 abscissaArray.InsertNextValue(abscissa) if not self.IsMasked(maskArray.GetTuple1(pointId)): xSpline.AddPoint(abscissa,point[0]) ySpline.AddPoint(abscissa,point[1]) zSpline.AddPoint(abscissa,point[2]) for k in range(numberOfArrays): array = self.Centerlines.GetPointData().GetArray(k) if array.GetNumberOfComponents() != 1: continue value = array.GetTuple1(pointId) aSplines[k].AddPoint(abscissa,value) previousPoint = point for j in range(cell.GetNumberOfPoints()): pointId = cell.GetPointId(j) if not self.IsMasked(maskArray.GetTuple1(pointId)): continue abscissa = abscissaArray.GetValue(pointId) point = [xSpline.Evaluate(abscissa), ySpline.Evaluate(abscissa), zSpline.Evaluate(abscissa)] self.Centerlines.SetPoint(pointId,point) for k in range(numberOfArrays): array = self.Centerlines.GetPointData().GetArray(k) if array.GetNumberOfComponents() != 1: continue value = aSplines[k].Evaluate(abscissa) array.SetTuple1(pointId,value)
def main(): parser = OptionParser(usage="Usage: %prog [options] <tract.vtp> <output.csv>") parser.add_option("-d", "--dist", dest="dist", default=20, type='float', help="Quickbundle distance threshold") parser.add_option("-n", "--num", dest="num", default=50, type='int', help="Number of subdivisions along centroids") parser.add_option("-s", "--scalar", dest="scalar", default="FA", help="Scalar to measure") parser.add_option("--curvepoints", dest="curvepoints_file", help="Define a curve to use as centroid. Control points are defined in a csv file in the same space as the tract points. The curve is the vtk cardinal spline implementation, which is a catmull-rom spline.") parser.add_option("-l", "--local", dest="is_local", action="store_true", default=False, help="Measure from Quickbundle assigned streamlines. Default is to measure from all streamlines") parser.add_option('--reverse', dest='is_reverse', action='store_true', default=False, help='Reverse the centroid measure stepping order') (options, args) = parser.parse_args() if len(args) == 0: parser.print_help() sys.exit(2) QB_DIST = options.dist QB_NPOINTS = options.num SCALAR_NAME = options.scalar LOCAL_POINT_ASSIGN = options.is_local filename= args[0] filebase = path.basename(filename).split('.')[0] reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(filename) reader.Update() polydata = reader.GetOutput() tract_ids = [] for i in range(polydata.GetNumberOfCells()): # get point ids in [[ids][ids...]...] format pids = polydata.GetCell(i).GetPointIds() ids = [ pids.GetId(p) for p in range(pids.GetNumberOfIds())] tract_ids.append(ids) print 'tracks:',len(tract_ids) verts = vtk_to_numpy(polydata.GetPoints().GetData()) print 'verts:',len(verts) scalars = [] groups = [] subjects = [] pointdata = polydata.GetPointData() for si in range(pointdata.GetNumberOfArrays()): sname = pointdata.GetArrayName(si) print sname if sname==SCALAR_NAME: scalars = vtk_to_numpy(pointdata.GetArray(si)) if sname=='group': groups = vtk_to_numpy(pointdata.GetArray(si)) groups = groups.astype(int) if sname=='tid': subjects = vtk_to_numpy(pointdata.GetArray(si)) subjects = subjects.astype(int) streamlines = [] stream_scalars = [] stream_groups = [] stream_pids = [] stream_sids = [] for i in tract_ids: # index np.array by a list will get all the respective indices streamlines.append(verts[i]) stream_scalars.append(scalars[i]) stream_groups.append(groups[i]) stream_pids.append(i) stream_sids.append(subjects[i]) streamlines = np.array(streamlines) stream_scalars = np.array(stream_scalars) stream_groups = np.array(stream_groups) stream_pids = np.array(stream_pids) stream_sids = np.array(stream_sids) # get total average direction (where majority point towards) avg_d = np.zeros(3) # for line in streams: # d = np.array(line[-1]) - np.array(line[0]) # d = d / la.norm(d) # avg_d += d # avg_d /= la.norm(avg_d) avg_com = np.zeros(3) avg_mid = np.zeros(3) strl_len = [len(l) for l in streamlines] stl_ori = np.array([np.abs(tm.mean_orientation(l)) for l in streamlines]) centroids = [] if options.curvepoints_file: LOCAL_POINT_ASSIGN = False cpoints = [] ctrlpoints = np.loadtxt(options.curvepoints_file, delimiter=',') # have a separate vtkCardinalSpline interpreter for x,y,z curve = [vtk.vtkCardinalSpline() for i in range(3)] for c in curve: c.ClosedOff() for pi, point in enumerate(ctrlpoints): for i,val in enumerate(point): curve[i].AddPoint(pi,point[i]) param_range = [0.0,0.0] curve[0].GetParametricRange(param_range) t = param_range[0] step = (param_range[1]-param_range[0])/(QB_NPOINTS) while t < param_range[1]: cp = [c.Evaluate(t) for c in curve] cpoints.append(cp) t = t + step centroids.append(cpoints) centroids = np.array(centroids) else: """ Use quickbundles to find centroids """ # streamlines = newlines qb = QuickBundles(streamlines, dist_thr=QB_DIST,pts=QB_NPOINTS) # bundle_distance_mam centroids = qb.centroids clusters = qb.clusters() avg_d = np.zeros(3) avg_com = np.zeros(3) avg_mid = np.zeros(3) #unify centroid list orders to point in the same general direction for i, line in enumerate(centroids): ori = np.array(tm.mean_orientation(line)) #d = np.array(line[-1]) - np.array(line[0]) #print line[-1],line[0],d # get the unit vector of the mean orientation if i==0: avg_d = ori #d = d / la.norm(d) dotprod = ori.dot(avg_d) print 'dotprod',dotprod if dotprod < 0: print 'reverse',dotprod centroids[i] = line[::-1] line = centroids[i] ori*=-1 avg_d += ori if options.is_reverse: for i,c in enumerate(centroids): centroids[i] = c[::-1] DATADF = None """ CENTROIDS """ for ci, cent in enumerate(centroids): print '---- centroid:' if LOCAL_POINT_ASSIGN: """ apply centroid to only their point assignments through quickbundles """ ind = clusters[ci]['indices'] cent_streams = streamlines[ind] cent_scalars = stream_scalars[ind] cent_groups = stream_groups[ind] cent_pids = stream_pids[ind] cent_sids = stream_sids[ind] else: # apply each centriod to all the points # instead of only their centroid assignments cent_streams = streamlines cent_scalars = stream_scalars cent_groups = stream_groups cent_pids = stream_pids cent_sids = stream_sids cent_verts = np.vstack(cent_streams) cent_scalars = np.concatenate(cent_scalars) cent_groups = np.concatenate(cent_groups) cent_pids = np.concatenate(cent_pids) cent_sids = np.concatenate(cent_sids) # cent_color = np.array(pal[ci]) c, labels = kmeans2(cent_verts, cent, iter=1) cid = np.ones(len(labels)) d = {'value':cent_scalars, 'position':labels, 'group':cent_groups, 'pid':cent_pids, 'sid':cent_sids, 'centroid':ci} df = pd.DataFrame(data=d) if DATADF is None: DATADF = df else: pd.concat([DATADF, df]) outfilename = '_'.join([filebase,SCALAR_NAME,'rawdata.csv']) if len(args) > 1: outfilename = args[1] if outfilename.endswith('.csv'): DATADF.to_csv(outfilename, index=False) if outfilename.endswith('.xls'): DATADF.to_excel(outfilename, index=False)
writer = vtk.vtkPolyDataWriter() writer.SetFileName(args.output + "contour_org.ply") writer.SetInputData(con.GetOutput()) writer.Update() writer.Write() vs = vtk.vtkStripper() vs.SetInputData(con.GetOutput()) vs.JoinContiguousSegmentsOn() vs.Update() cpd2 = vtk.vtkCleanPolyData() cpd2.SetInputData(vs.GetOutput()) cpd2.Update() spline = vtk.vtkCardinalSpline() spline.SetLeftConstraint(2) spline.SetLeftValue(0) spline.SetRightConstraint(2) spline.SetRightValue(0) spFilter = vtk.vtkSplineFilter() spFilter.SetInputData(cpd2.GetOutput()) conNumPoint = cpd2.GetOutput().GetNumberOfPoints() spFilter.SetNumberOfSubdivisions(conNumPoint * 10) spFilter.SetSpline(spline) spFilter.Update() bc = cpd2.GetOutput().GetBounds() yl = bc[3] - bc[2] zl = bc[5] - bc[4]