def convert_cluster_to_volume_with_sz(inpd, volume, sampling_size=0.5): volume_shape = volume.get_data().shape new_voxel_data = numpy.zeros(volume_shape) resampler = vtk.vtkPolyDataPointSampler() resampler.GenerateEdgePointsOn() resampler.GenerateVertexPointsOff() resampler.GenerateInteriorPointsOff() resampler.GenerateVerticesOff() resampler.SetDistance(sampling_size) inpoints = inpd.GetPoints() inpd.GetLines().InitTraversal() for lidx in range(0, inpd.GetNumberOfLines()): ptids = vtk.vtkIdList() inpd.GetLines().GetNextCell(ptids) tmpPd = vtk.vtkPolyData() tmpPoints = vtk.vtkPoints() tmpCellPtIds = vtk.vtkIdList() tmpLines = vtk.vtkCellArray() for pidx in range(0, ptids.GetNumberOfIds()): point = inpoints.GetPoint(ptids.GetId(pidx)) idx_ = tmpPoints.InsertNextPoint(point) tmpCellPtIds.InsertNextId(idx_) tmpLines.InsertNextCell(tmpCellPtIds) tmpPd.SetLines(tmpLines) tmpPd.SetPoints(tmpPoints) if (vtk.vtkVersion().GetVTKMajorVersion() >= 6.0): resampler.SetInputData(tmpPd) else: resampler.SetInput(tmpPd) resampler.Update() sampledCellPts = resampler.GetOutput().GetPoints() sampledNpts = resampler.GetOutput().GetNumberOfPoints() line_tmp_voxel_data = numpy.zeros(volume_shape) for pidx in range(0, sampledNpts): point = sampledCellPts.GetPoint(pidx) point_ijk = apply_affine(numpy.linalg.inv(volume.affine), point) point_ijk = numpy.rint(point_ijk).astype(numpy.int32) line_tmp_voxel_data[(point_ijk[0], point_ijk[1], point_ijk[2])] += 1 new_voxel_data = new_voxel_data + line_tmp_voxel_data return new_voxel_data
def vtk_mesh_sampling(inputdata, distance=150, generate_vertex_points=True, generate_edge_points=True, generate_face_points=True, verbose=False): """Sample points on a mesh from vertices, edges and faces in a given distance Arguments: inputdata (vtk.vtkPolyData): ytk object containing vertices and simplices distance (float): Set the approximate distance between points. This is an absolute distance measure (default here 150 for safety reasons). generate_vertex_points (bool): Indicating whether cell vertex points should be output (default True). generate_edge_points (bool): Indicating whether cell edges should be sampled to produce output points (default True). generate_face_points (bool): Indicating whether cell interiors should be sampled to produce output points (default True). verbose (bool): Print out basic statistics (default False). Returns: decimatedPoly: vtkPolyData object or pandas.DataFrame of xyz coordinates (depends on input) """ if not isinstance(inputdata, vtkPolyData): raise TypeError( 'Unknown dtype for inputdata! vtk.vtkPolyData expected.') inputPoly = vtkPolyData() inputPoly.ShallowCopy(inputdata) sampler = vtkPolyDataPointSampler() sampler.SetInputData(inputPoly) # set parameters sampler.SetDistance(distance) sampler.SetGenerateVertexPoints(generate_vertex_points) sampler.SetGenerateEdgePoints(generate_edge_points) sampler.SetGenerateInteriorPoints(generate_face_points) sampler.Update() sampler_poly = vtkPolyData() sampler_poly.ShallowCopy(sampler.GetOutput()) if verbose: print('Points sampled:', sampler_poly.GetNumberOfPoints()) return sampler_poly
def __init__(self, parent=None): super(VTKFrame, self).__init__(parent) self.vtkWidget = QVTKRenderWindowInteractor(self) vl = QtGui.QVBoxLayout(self) vl.addWidget(self.vtkWidget) vl.setContentsMargins(0, 0, 0, 0) self.ren = vtk.vtkRenderer() self.ren.SetBackground(0.1, 0.2, 0.4) self.vtkWidget.GetRenderWindow().AddRenderer(self.ren) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() # Create source sphereSource = vtk.vtkSphereSource() sphereSource.SetPhiResolution(50) sphereSource.SetThetaResolution(50) sphereSource.Update() # Sample the sphere pointSampler = vtk.vtkPolyDataPointSampler() pointSampler.SetDistance(0.01) pointSampler.SetInputConnection(sphereSource.GetOutputPort()) pointSampler.Update() # Visualize sphereMapper = vtk.vtkPolyDataMapper() sphereMapper.SetInputConnection(sphereSource.GetOutputPort()) sphereActor = vtk.vtkActor() sphereActor.SetMapper(sphereMapper) sampleMapper = vtk.vtkPolyDataMapper() sampleMapper.SetInputConnection(pointSampler.GetOutputPort()) sampleActor = vtk.vtkActor() sampleActor.SetMapper(sampleMapper) sampleActor.GetProperty().SetColor(1, 0, 0) self.ren.AddActor(sphereActor) self.ren.AddActor(sampleActor) self.ren.ResetCamera() self._initialized = False
def __init__(self, parent = None): super(VTKFrame, self).__init__(parent) self.vtkWidget = QVTKRenderWindowInteractor(self) vl = QtGui.QVBoxLayout(self) vl.addWidget(self.vtkWidget) vl.setContentsMargins(0, 0, 0, 0) self.ren = vtk.vtkRenderer() self.ren.SetBackground(0.1, 0.2, 0.4) self.vtkWidget.GetRenderWindow().AddRenderer(self.ren) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() # Create source sphereSource = vtk.vtkSphereSource() sphereSource.SetPhiResolution(50) sphereSource.SetThetaResolution(50) sphereSource.Update() # Sample the sphere pointSampler = vtk.vtkPolyDataPointSampler() pointSampler.SetDistance(0.01) pointSampler.SetInputConnection(sphereSource.GetOutputPort()) pointSampler.Update() # Visualize sphereMapper = vtk.vtkPolyDataMapper() sphereMapper.SetInputConnection(sphereSource.GetOutputPort()) sphereActor = vtk.vtkActor() sphereActor.SetMapper(sphereMapper) sampleMapper = vtk.vtkPolyDataMapper() sampleMapper.SetInputConnection(pointSampler.GetOutputPort()) sampleActor = vtk.vtkActor() sampleActor.SetMapper(sampleMapper) sampleActor.GetProperty().SetColor(1, 0, 0) self.ren.AddActor(sphereActor) self.ren.AddActor(sampleActor) self.ren.ResetCamera() self._initialized = False
# Create a sphere implicit function sphere = vtk.vtkSphereSource() sphere.SetCenter(2, 0, 0) sphere.SetRadius(0.8) sphere.SetThetaResolution(96) sphere.SetPhiResolution(48) # Boolean (union) these together append = vtk.vtkAppendPolyData() append.AddInputConnection(cyl.GetOutputPort()) append.AddInputConnection(plane.GetOutputPort()) append.AddInputConnection(sphere.GetOutputPort()) # Extract points along sphere surface pts = vtk.vtkPolyDataPointSampler() pts.SetInputConnection(append.GetOutputPort()) pts.SetDistance(0.01) pts.Update() # Now generate normals from resulting points curv = vtk.vtkPCACurvatureEstimation() curv.SetInputConnection(pts.GetOutputPort()) curv.SetSampleSize(20) # Time execution timer = vtk.vtkTimerLog() timer.StartTimer() curv.Update() timer.StopTimer() time = timer.GetElapsedTime()
def compute_stat(inpd, volume, sampling_size=None): volume_data = volume.get_data() volume_shape = volume.get_data().shape voxel_size = volume.header.get_zooms() new_voxel_data = numpy.zeros(volume_shape) if sampling_size is not None: resampler = vtk.vtkPolyDataPointSampler() resampler.GenerateEdgePointsOn() resampler.GenerateVertexPointsOff() resampler.GenerateInteriorPointsOff() resampler.GenerateVerticesOff() resampler.SetDistance(sampling_size) value_list = [] inpoints = inpd.GetPoints() inpd.GetLines().InitTraversal() for lidx in range(0, inpd.GetNumberOfLines()): ptids = vtk.vtkIdList() inpd.GetLines().GetNextCell(ptids) if sampling_size is not None: # print '-- sampling with size', sampling_size tmpPd = vtk.vtkPolyData() tmpPoints = vtk.vtkPoints() tmpCellPtIds = vtk.vtkIdList() tmpLines = vtk.vtkCellArray() for pidx in range(0, ptids.GetNumberOfIds()): point = inpoints.GetPoint(ptids.GetId(pidx)) idx_ = tmpPoints.InsertNextPoint(point) tmpCellPtIds.InsertNextId(idx_) tmpLines.InsertNextCell(tmpCellPtIds) tmpPd.SetLines(tmpLines) tmpPd.SetPoints(tmpPoints) if (vtk.vtkVersion().GetVTKMajorVersion() >= 6.0): resampler.SetInputData(tmpPd) else: resampler.SetInput(tmpPd) resampler.Update() sampledCellPts = resampler.GetOutput().GetPoints() sampledNpts = resampler.GetOutput().GetNumberOfPoints() else: # print '-- No sampling' sampledCellPts = inpoints sampledNpts = inpd.GetNumberOfPoints() for pidx in range(0, sampledNpts): point = sampledCellPts.GetPoint(pidx) point_ijk = apply_affine(numpy.linalg.inv(volume.affine), point) point_ijk = numpy.rint(point_ijk).astype(numpy.int32) if point_ijk[0] > new_voxel_data.shape[0] or point_ijk[ 1] > new_voxel_data.shape[1] or point_ijk[ 2] > new_voxel_data.shape[2]: print('Warning: point', point_ijk, 'is outside the input volumetric map.') continue if new_voxel_data[(point_ijk[0], point_ijk[1], point_ijk[2])] == 0: new_voxel_data[(point_ijk[0], point_ijk[1], point_ijk[2])] = 1 value_list.append(volume_data[(point_ijk[0], point_ijk[1], point_ijk[2])]) if len(value_list) > 0: mean_v = numpy.mean(value_list) var_v = numpy.var(value_list) max_v = numpy.max(value_list) min_v = numpy.min(value_list) median_v = numpy.median(value_list) else: mean_v = numpy.nan var_v = numpy.nan max_v = numpy.nan min_v = numpy.nan median_v = numpy.nan num_voxels = len(value_list) volume_size = voxel_size[0] * voxel_size[1] * voxel_size[2] * num_voxels return new_voxel_data, mean_v, var_v, max_v, min_v, median_v, num_voxels, volume_size
# Create a sphere implicit function sphere = vtk.vtkSphereSource() sphere.SetCenter(2,0,0) sphere.SetRadius(0.8) sphere.SetThetaResolution(96) sphere.SetPhiResolution(48) # Boolean (union) these together append = vtk.vtkAppendPolyData() append.AddInputConnection(cyl.GetOutputPort()) append.AddInputConnection(plane.GetOutputPort()) append.AddInputConnection(sphere.GetOutputPort()) # Extract points along sphere surface pts = vtk.vtkPolyDataPointSampler() pts.SetInputConnection(append.GetOutputPort()) pts.SetDistance(0.025) pts.Update() # Now see if we can extract the three objects as separate clusters. extr = vtk.vtkEuclideanClusterExtraction() extr.SetInputConnection(pts.GetOutputPort()) extr.SetRadius(0.1) extr.ColorClustersOn() extr.SetExtractionModeToAllClusters() # Time execution timer = vtk.vtkTimerLog() timer.StartTimer() extr.Update()
def process(self): if not self.inputCurve: msg = "No curve." slicer.util.showStatusMessage(msg, 4000) slicer.app.processEvents() logging.info(msg) return # Don't do anything if there are 2 points only, already a line. if (self.inputCurve.GetNumberOfControlPoints() == 2): # Just signal widget to fill the table with results. if self.widgetCallback: self.widgetCallback() return # Generate a linear polydata from first and last control point. numberOfControlPoints = self.inputCurve.GetNumberOfControlPoints() lineSource = vtk.vtkLineSource() curveControlPoints = vtk.vtkPoints() self.inputCurve.GetControlPointPositionsWorld(curveControlPoints) firstControlPointPosition = curveControlPoints.GetPoint(0) lastControlPointPosition = curveControlPoints.GetPoint( numberOfControlPoints - 1) lineSource.SetPoint1(firstControlPointPosition) lineSource.SetPoint2(lastControlPointPosition) lineSource.Update() linePolyData = lineSource.GetOutput() # The polydata contains 2 points. Generate more points. polydataSampler = vtk.vtkPolyDataPointSampler() polydataSampler.SetInputData(linePolyData) polydataSampler.Update() # This is the reference line polydata. straightLinePolyData = polydataSampler.GetOutput() startPoint = curveControlPoints.GetPoint(0) cumulativeDistanceArray = [[0.0, startPoint]] # Iterate over all curve points, ignoring first and last. for pointIndex in range(1, numberOfControlPoints - 1): point = curveControlPoints.GetPoint(pointIndex) closestIdOnStraightLine = straightLinePolyData.FindPoint(point) closestPointOnStraightLine = straightLinePolyData.GetPoint( closestIdOnStraightLine) cumulativeDistanceOfClosestPoint = vtk.vtkMath.Distance2BetweenPoints( startPoint, closestPointOnStraightLine) cumulativeDistanceArray.append( [cumulativeDistanceOfClosestPoint, closestPointOnStraightLine]) """ Move each control point to the closest point on the virtual line. If we have n control points ABCD..., C can be pushed between A and B on the virtual line. The curve is still valid, though the points are in zig-zag order. Distances will be less or not meaningful. Sort the points by distance from start to avoid this. """ sortedCumulativeDistanceArray = sorted( cumulativeDistanceArray, key=lambda distance: distance[0]) for pointIndex in range(1, numberOfControlPoints - 1): self.inputCurve.SetNthControlPointPosition( pointIndex, sortedCumulativeDistanceArray[pointIndex][1]) # Signal widget to fill the table with results. if self.widgetCallback: self.widgetCallback()
def rasterizeFibers(self,fiberNode,labelNode,labelValue=1,samplingDistance=0.1): """Trace through the given fiber bundles and set the corresponding pixels in the given labelNode volume""" print('rasterizing...') rasToIJK = vtk.vtkMatrix4x4() labelNode.GetRASToIJKMatrix(rasToIJK) labelArray = slicer.util.array(labelNode.GetID()) polyData = fiberNode.GetPolyData() cellCount = polyData.GetNumberOfCells() selection = vtk.vtkSelection() selectionNode = vtk.vtkSelectionNode() selectionNode.SetFieldType(vtk.vtkSelectionNode.CELL) selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES) extractor = vtk.vtkExtractSelectedPolyDataIds() extractor.SetInputData(0, polyData) resampler = vtk.vtkPolyDataPointSampler() resampler.GenerateEdgePointsOn() resampler.GenerateVertexPointsOff() resampler.GenerateInteriorPointsOff() resampler.GenerateVerticesOff() resampler.SetDistance(samplingDistance) cellIds = vtk.vtkIdTypeArray() # as a compromise between memory blowup (for large fiberbundles) and not # eating time in the python loop, resample CELLS_TO_PROCESS at once. CELLS_TO_PROCESS = 100 for startCellId in xrange(0, cellCount, CELLS_TO_PROCESS): # generate list of cell Ids to sample cellIdsAr = numpy.arange(startCellId, min(cellCount, startCellId + CELLS_TO_PROCESS)) cellIds.SetVoidArray(cellIdsAr, cellIdsAr.size, 1) # update the selection node to extract those cells selectionNode.SetSelectionList(cellIds) selection.AddNode(selectionNode) selection.Modified() extractor.SetInputData(1, selection) extractor.Update() resampler.SetInputConnection(extractor.GetOutputPort()) resampler.Update() # get the resampler output # note: to test without resampling, just use # `pdSubset = extractor.GetOutput()` instead pdSubset = resampler.GetOutput() pointCount = pdSubset.GetNumberOfPoints() points = pdSubset.GetPoints() for pointIndex in xrange(pointCount): point = points.GetPoint(pointIndex) ijkFloat = rasToIJK.MultiplyPoint(point+(1,))[:3] # skip any negative indices to avoid wrap-around # to the other side of the image. if (any(coord < 0 for coord in ijkFloat)): continue ijk = [int(round(element)) for element in ijkFloat] ijk.reverse() try: # paint the voxels labelArray[tuple(ijk)] = labelValue except IndexError: pass # reset the selection node selection.RemoveAllNodes() labelNode.GetImageData().Modified() labelNode.Modified() print('finished')
def rasterizeFibers(self, fiberNode, labelNode, labelValue=1, samplingDistance=0.1): """Trace through the given fiber bundles and set the corresponding pixels in the given labelNode volume""" print('rasterizing...') rasToIJK = vtk.vtkMatrix4x4() labelNode.GetRASToIJKMatrix(rasToIJK) labelArray = slicer.util.array(labelNode.GetID()) polyData = fiberNode.GetPolyData() cellCount = polyData.GetNumberOfCells() selection = vtk.vtkSelection() selectionNode = vtk.vtkSelectionNode() selectionNode.SetFieldType(vtk.vtkSelectionNode.CELL) selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES) extractor = vtk.vtkExtractSelectedPolyDataIds() extractor.SetInputData(0, polyData) resampler = vtk.vtkPolyDataPointSampler() resampler.GenerateEdgePointsOn() resampler.GenerateVertexPointsOff() resampler.GenerateInteriorPointsOff() resampler.GenerateVerticesOff() resampler.SetDistance(samplingDistance) cellIds = vtk.vtkIdTypeArray() # as a compromise between memory blowup (for large fiberbundles) and not # eating time in the python loop, resample CELLS_TO_PROCESS at once. CELLS_TO_PROCESS = 100 for startCellId in xrange(0, cellCount, CELLS_TO_PROCESS): # generate list of cell Ids to sample cellIdsAr = numpy.arange(startCellId, min(cellCount, startCellId + CELLS_TO_PROCESS), dtype=vtk.util.numpy_support.ID_TYPE_CODE) cellIds.SetVoidArray(cellIdsAr, cellIdsAr.size, 1) # update the selection node to extract those cells selectionNode.SetSelectionList(cellIds) selection.AddNode(selectionNode) selection.Modified() extractor.SetInputData(1, selection) extractor.Update() resampler.SetInputConnection(extractor.GetOutputPort()) resampler.Update() # get the resampler output # note: to test without resampling, just use # `pdSubset = extractor.GetOutput()` instead pdSubset = resampler.GetOutput() pointCount = pdSubset.GetNumberOfPoints() points = pdSubset.GetPoints() for pointIndex in xrange(pointCount): point = points.GetPoint(pointIndex) ijkFloat = rasToIJK.MultiplyPoint(point + (1, ))[:3] # skip any negative indices to avoid wrap-around # to the other side of the image. if (any(coord < 0 for coord in ijkFloat)): continue ijk = [int(round(element)) for element in ijkFloat] ijk.reverse() try: # paint the voxels labelArray[tuple(ijk)] = labelValue except IndexError: pass # reset the selection node selection.RemoveAllNodes() labelNode.GetImageData().Modified() labelNode.Modified() print('finished')
ellipFunc.SetXRadius(a) ellipFunc.SetYRadius(b) ellipFunc.SetZRadius(c) ellipFunc.SetN1(N1) ellipFunc.SetN2(N2) ellip = vtk.vtkParametricFunctionSource() ellip.SetParametricFunction(ellipFunc) ellip.SetUResolution(50) ellip.SetVResolution(30) ellip.SetWResolution(30) ellip.SetScalarModeToNone() ellip.Update() d = np.pi / 15 * lam1 * a resample = vtk.vtkPolyDataPointSampler() resample.SetInputData(ellip.GetOutput()) resample.SetDistance(d) resample.Update() delaunay = vtk.vtkDelaunay3D() delaunay.SetInputData(resample.GetOutput()) delaunay.Update() geo = vtk.vtkGeometryFilter() geo.SetInputData(delaunay.GetOutput()) geo.Update() decim = vtk.vtkDecimatePro() decim.SetInputData(geo.GetOutput()) decim.SetTargetReduction(.2)