예제 #1
0
def pointDensity(mesh,
                 dims=(40, 40, 40),
                 bounds=None,
                 radius=None,
                 computeGradient=False,
                 locator=None):
    """
    Generate a density field from a point cloud. Input can also be a set of 3D coordinates.
    Output is a ``Volume``.
    The local neighborhood is specified as the `radius` around each sample position (each voxel).
    The density is expressed as the number of counts in the radius search.

    :param int,list dims: numer of voxels in x, y and z of the output Volume.
    :param bool computeGradient: Turn on/off the generation of the gradient vector,
        gradient magnitude scalar, and function classification scalar.
        By default this is off. Note that this will increase execution time
        and the size of the output. (The names of these point data arrays are:
        "Gradient", "Gradient Magnitude", and "Classification".)

    :param vtkStaticPointLocator locator: can be assigned from a previous call for speed.

    See example script: |pointDensity.py|_
    """
    if not utils.isSequence(dims):
        dims = (dims, dims, dims)
    pdf = vtk.vtkPointDensityFilter()
    if utils.isSequence(mesh):  # user passing coords
        if len(mesh) == 3:
            mesh = np.c_[mesh[0], mesh[1], mesh[2]]
        poly = utils.buildPolyData(mesh)
        b = poly.GetBounds()
        diag = np.sqrt((b[1] - b[0])**2 + (b[3] - b[2])**2 + (b[5] - b[4])**2)
    else:
        poly = mesh.polydata()
        b = poly.GetBounds()
        diag = mesh.diagonalSize()
    pdf.SetInputData(poly)
    pdf.SetSampleDimensions(dims)
    pdf.SetDensityEstimateToFixedRadius()
    pdf.SetDensityFormToNumberOfPoints()
    if locator:
        pdf.SetLocator(locator)
    if radius is None:
        radius = diag / 15
    pdf.SetRadius(radius)
    if bounds is None:
        bounds = b
    pdf.SetModelBounds(bounds)
    pdf.SetComputeGradient(computeGradient)
    pdf.Update()
    img = pdf.GetOutput()
    vol = Volume(img)
    vol.name = "PointDensity"
    vol.info['radius'] = radius
    vol.locator = pdf.GetLocator()
    return vol
예제 #2
0
extract.SetImplicitFunction(sphere)
extract.SetThreshold(0.005)
extract.GenerateVerticesOn()

# Clip out some of the points with a plane; requires vertices
plane = vtk.vtkPlane()
plane.SetOrigin(sphere.GetCenter())
plane.SetNormal(1, 1, 1)

clipper = vtk.vtkClipPolyData()
clipper.SetInputConnection(extract.GetOutputPort())
clipper.SetClipFunction(plane)

# Generate density field from points
# Use fixed radius
dens0 = vtk.vtkPointDensityFilter()
dens0.SetInputConnection(clipper.GetOutputPort())
dens0.SetSampleDimensions(res, res, res)
dens0.SetDensityEstimateToFixedRadius()
dens0.SetRadius(0.05)
# dens0.SetDensityEstimateToRelativeRadius()
dens0.SetRelativeRadius(2.5)
# dens0.SetDensityFormToVolumeNormalized()
dens0.SetDensityFormToNumberOfPoints()
dens0.ComputeGradientOn()
dens0.Update()
vrange = dens0.GetOutput().GetPointData().GetArray("Gradient Magnitude").GetRange()

# Show the gradient magnitude
assign0 = vtk.vtkAssignAttribute()
assign0.SetInputConnection(dens0.GetOutputPort())
예제 #3
0
extract.SetImplicitFunction(sphere)
extract.SetThreshold(0.005)
extract.GenerateVerticesOn()

# Clip out some of the points with a plane; requires vertices
plane = vtk.vtkPlane()
plane.SetOrigin(sphere.GetCenter())
plane.SetNormal(1,1,1)

clipper = vtk.vtkClipPolyData()
clipper.SetInputConnection(extract.GetOutputPort())
clipper.SetClipFunction(plane);

# Generate density field from points
# Use fixed radius
dens0 = vtk.vtkPointDensityFilter()
dens0.SetInputConnection(clipper.GetOutputPort())
dens0.SetSampleDimensions(res,res,res)
dens0.SetDensityEstimateToFixedRadius()
dens0.SetRadius(0.05)
#dens0.SetDensityEstimateToRelativeRadius()
dens0.SetRelativeRadius(2.5)
#dens0.SetDensityFormToVolumeNormalized()
dens0.SetDensityFormToNumberOfPoints()
dens0.ComputeGradientOn()
dens0.Update()
vrange = dens0.GetOutput().GetPointData().GetArray("Gradient Magnitude").GetRange()

# Show the gradient magnitude
assign0 = vtk.vtkAssignAttribute()
assign0.SetInputConnection(dens0.GetOutputPort())
예제 #4
0
extract.SetImplicitFunction(sphere)
extract.SetThreshold(0.005)
extract.GenerateVerticesOn()

# Clip out some of the points with a plane; requires vertices
plane = vtk.vtkPlane()
plane.SetOrigin(sphere.GetCenter())
plane.SetNormal(1,1,1)

clipper = vtk.vtkClipPolyData()
clipper.SetInputConnection(extract.GetOutputPort())
clipper.SetClipFunction(plane);

# Generate density field from points
# Use fixed radius
dens0 = vtk.vtkPointDensityFilter()
dens0.SetInputConnection(clipper.GetOutputPort())
dens0.SetSampleDimensions(res,res,res)
dens0.SetDensityEstimateToFixedRadius()
dens0.SetRadius(0.05)
#dens0.SetDensityEstimateToRelativeRadius()
dens0.SetRelativeRadius(2.5)
dens0.SetDensityFormToVolumeNormalized()

# Time execution
timer = vtk.vtkTimerLog()
timer.StartTimer()
dens0.Update()
timer.StopTimer()
time = timer.GetElapsedTime()
print("Time to compute density field: {0}".format(time))
예제 #5
0
extract.SetImplicitFunction(sphere)
extract.SetThreshold(0.005)
extract.GenerateVerticesOn()

# Clip out some of the points with a plane; requires vertices
plane = vtk.vtkPlane()
plane.SetOrigin(sphere.GetCenter())
plane.SetNormal(1, 1, 1)

clipper = vtk.vtkClipPolyData()
clipper.SetInputConnection(extract.GetOutputPort())
clipper.SetClipFunction(plane)

# Generate density field from points
# Use fixed radius
dens0 = vtk.vtkPointDensityFilter()
dens0.SetInputConnection(clipper.GetOutputPort())
dens0.SetSampleDimensions(res, res, res)
dens0.SetDensityEstimateToFixedRadius()
dens0.SetRadius(0.05)
#dens0.SetDensityEstimateToRelativeRadius()
dens0.SetRelativeRadius(2.5)
dens0.SetDensityFormToVolumeNormalized()

# Time execution
timer = vtk.vtkTimerLog()
timer.StartTimer()
dens0.Update()
timer.StopTimer()
time = timer.GetElapsedTime()
print("Time to compute density field: {0}".format(time))
예제 #6
0
    def generateSurfaceModel(self, markupsNode, modelNode,
                             pointDistanceFactor):

        svnode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeNode')

        print('Generating a surface model from tracking data... ')

        ## Generate a scalar volume node
        # Get the bounding box
        print('Calculating bounding box... ')
        bounds = [0.0] * 6
        markupsNode.GetBounds(bounds)
        print(bounds)

        b = numpy.array(bounds)
        b = b.reshape((3, 2))
        origin = numpy.mean(b, axis=1)
        fov = numpy.abs(b[:, 1] - b[:, 0])
        fovMax = numpy.max(fov)
        boundingBoxRange = (
            fovMax * 1.5
        ) / 2.0  # 1.5 times larger than the bounding box; from the center to the end (1/2 of each dimension)
        b[:, 0] = origin - boundingBoxRange
        b[:, 1] = origin + boundingBoxRange
        bounds = b.reshape(-1)
        print(bounds)
        res = 256

        print('Converting fiducials to poly data...')
        poly = self.fiducialsToPoly(markupsNode)

        #Note: Altenatively, vtkImageEllipsoidSource may be used to generate a volume.
        # Generate density field from points
        # Use fixed radius
        print('Running vtkPointDensityFilter...')
        dens = vtk.vtkPointDensityFilter()
        dens.SetInputData(poly)

        # TODO - is the resolution good enoguh?
        dens.SetSampleDimensions(res, res, res)
        dens.SetDensityEstimateToFixedRadius()
        # TODO - Does this radius work for every case?
        pixelSize = boundingBoxRange * 2 / res

        # Note: the algorithm fails when the bounding box is too small..
        if pixelSize < 0.5:
            pixelSize = 0.5

        radius = pixelSize
        dens.SetRadius(radius)
        #dens.SetDensityEstimateToRelativeRadius()
        #dens.SetRelativeRadius(2.5)
        #dens.SetDensityFormToVolumeNormalized()
        dens.SetDensityFormToNumberOfPoints()
        dens.SetModelBounds(bounds)
        dens.ComputeGradientOn()
        dens.Update()

        print('Creating an image node...')
        # Crete an image node - geometric parameters (origin, spacing) must be moved to the node object
        #imnode = slicer.vtkMRMLScalarVolumeNode()
        imnode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeNode')
        imnode.SetName('MRTracking_SurfaceMap_tmp')
        imdata = dens.GetOutput()
        imnode.SetAndObserveImageData(imdata)
        imnode.SetOrigin(imdata.GetOrigin())
        imnode.SetSpacing(imdata.GetSpacing())
        #imdata.SetOrigin([0.0, 0.0, 0.0])
        #imdata.SetSpacing([1.0, 1.0, 1.0])
        slicer.mrmlScene.AddNode(imnode)

        print('Applying BinaryThreshold...')
        image = sitkUtils.PullVolumeFromSlicer(imnode.GetID())
        binImage = sitk.BinaryThreshold(image,
                                        lowerThreshold=1.0,
                                        upperThreshold=256,
                                        insideValue=1,
                                        outsideValue=0)

        # Calculate the radius parameter for dilation and erosion
        radiusInPixel = int(numpy.ceil(pointDistanceFactor / pixelSize))
        if radiusInPixel < 1.0:
            radiusInPixel = 1

        # Dilate the target label
        print('Dilating the image...')
        dilateFilter = sitk.BinaryDilateImageFilter()
        dilateFilter.SetBoundaryToForeground(False)
        dilateFilter.SetKernelRadius(radiusInPixel)
        dilateFilter.SetKernelType(sitk.sitkBall)
        dilateFilter.SetForegroundValue(1)
        dilateFilter.SetBackgroundValue(0)
        dilateImage = dilateFilter.Execute(binImage)

        # Fill holes in the target label
        print('Filling holes...')
        fillHoleFilter = sitk.BinaryFillholeImageFilter()
        fillHoleFilter.SetForegroundValue(1)
        fillHoleFilter.SetFullyConnected(True)
        fillHoleImage = fillHoleFilter.Execute(dilateImage)

        # Erode the label
        print('Eroding the image...')
        erodeFilter = sitk.BinaryErodeImageFilter()
        erodeFilter.SetBoundaryToForeground(False)
        erodeFilter.SetKernelType(sitk.sitkBall)
        erodeFilter.SetKernelRadius(
            radiusInPixel - 1)  # 1 pixel smaller than the radius for dilation.
        erodeFilter.SetForegroundValue(1)
        erodeFilter.SetBackgroundValue(0)
        erodeImage = erodeFilter.Execute(fillHoleImage)

        print('Pushing the volume to the MRML scene...')
        sitkUtils.PushVolumeToSlicer(erodeImage, imnode.GetName(), 0, True)
        imdata = imnode.GetImageData()

        imdata.SetOrigin(imnode.GetOrigin())
        imdata.SetSpacing(imnode.GetSpacing())

        print('Running marching cubes...')
        poly = self.marchingCubes(imdata)
        modelNode.SetAndObservePolyData(poly)

        slicer.mrmlScene.RemoveNode(imnode)
        print('Done.')