Detailed Resampling#

Download Python source code | Download Jupyter notebook

This example uses pyvista.DataObjectFilters.sample().

pyvista.DataObjectFilters.resample_to_image() samples onto a new ImageData in a single call.

pyvista.DataSetFilters.interpolate() is similar, and the two methods are compared in Compare Interpolation/Sampling Methods.

Resample one mesh’s point/cell arrays onto another mesh’s nodes.

This example will resample a volumetric mesh’s scalar data onto the surface of a sphere contained in that volume.

import pyvista as pv
from pyvista import examples

Simple Resample#

Query a grid’s points onto a sphere

mesh = pv.Sphere(center=(4.5, 4.5, 4.5), radius=4.5)
data_to_probe = examples.load_uniform()

Plot the two datasets

pl = pv.Plotter()
pl.add_mesh(mesh, color=True)
pl.add_mesh(data_to_probe, opacity=0.5)
pl.show()
resampling

Run the algorithm and plot the result

result = mesh.sample(data_to_probe)

# Plot result
name = 'Spatial Point Data'
result.plot(scalars=name, clim=data_to_probe.get_data_range(name))
resampling

resample_to_image() samples onto a new ImageData instead. Pass a reference_volume to give the output the geometry of an image which already exists.

ImageData (0x7f3199569720)
  N Cells:      729
  N Points:     1000
  X Bounds:     0.000e+00, 9.000e+00
  Y Bounds:     0.000e+00, 9.000e+00
  Z Bounds:     0.000e+00, 9.000e+00
  Dimensions:   10, 10, 10
  Spacing:      1.000e+00, 1.000e+00, 1.000e+00
  N Arrays:     2


Complex Resample#

Take a volume of data and create a grid of lower resolution to resample on

resample_to_image() does both steps in one call.

data_to_probe.resample_to_image(dimensions=(75, 75, 75))
ImageData (0x7f3199568b20)
  N Cells:      405224
  N Points:     421875
  X Bounds:     1.700e+00, 2.533e+02
  Y Bounds:     1.700e+00, 2.533e+02
  Z Bounds:     1.700e+00, 2.533e+02
  Dimensions:   75, 75, 75
  Spacing:      3.400e+00, 3.400e+00, 3.400e+00
  N Arrays:     2


To resample ImageData directly, use resample() instead.

data_to_probe.resample(dimensions=(75, 75, 75))
ImageData (0x7f3199569180)
  N Cells:      405224
  N Points:     421875
  X Bounds:     1.207e+00, 2.538e+02
  Y Bounds:     1.207e+00, 2.538e+02
  Z Bounds:     1.207e+00, 2.538e+02
  Dimensions:   75, 75, 75
  Spacing:      3.413e+00, 3.413e+00, 3.413e+00
  N Arrays:     1


Both meshes here are ImageData, and for that case reslice() is the closer fit than sample. It reads the image at the grid’s points just as sample does, but returns only the resampled array, where sample also carries the grid’s own arrays and the mask arrays probing adds, and it offers the border, interpolation, and anti-aliasing options an image needs. See Reslice Images.

ImageData (0x7f319956b880)
  N Cells:      405224
  N Points:     421875
  X Bounds:     0.000e+00, 2.550e+02
  Y Bounds:     0.000e+00, 2.550e+02
  Z Bounds:     0.000e+00, 2.550e+02
  Dimensions:   75, 75, 75
  Spacing:      3.446e+00, 3.446e+00, 3.446e+00
  N Arrays:     1


threshold = lambda m: m.threshold(75.0, scalars='SLCImage')
cpos = pv.CameraPosition(
    position=(468.9, -152.8, 152.1),
    focal_point=(121.7, 140.3, 112.3),
    viewup=(-0.1088, 0.006229, 0.994),
)
dargs = dict(clim=[0, 200], cmap='rainbow')

pl = pv.Plotter(shape=(1, 2))
pl.add_mesh(threshold(data_to_probe), **dargs)
pl.subplot(0, 1)
pl.add_mesh(threshold(result), **dargs)
pl.link_views()
pl.view_isometric()
pl.show(cpos=cpos)
resampling

Resample a Processed Volume#

Clipping an image returns an UnstructuredGrid, which image filters do not accept. resample_to_image() puts the processed volume back on a regular grid.

Start from a volumetric scan of a knee. Bone is the bright end of its intensity range, from 100 up.

knee = examples.download_knee_full()


knee.plot(volume=True, cmap='bone', clim=[100, 174])
resampling

Clip the scan to the bone, and keep the three largest pieces: the tibia, the femur, and the patella. connectivity() numbers the regions from the largest down and stores the numbers as 'RegionId'.

bone = knee.clip_scalar(scalars='SLCImage', value=100, invert=False)
bones = bone.connectivity('specified', [0, 1, 2])
bones.plot(scalars='RegionId', cmap='glasbey', categories=True)
resampling

Resample the labeled bones onto the scan’s own grid with reference_volume, so that a voxel of the output is a voxel of the scan. Sample the labels as categories to keep them whole, and blank the voxels which fall outside the bone.

labels = bones.resample_to_image(reference_volume=knee, categorical=True, mark_blank=True)

The labels sit on the points of the image, so render them as voxel cells with points_to_cells().

labels.points_to_cells().plot(scalars='RegionId', cmap='glasbey', categories=True)
resampling

Tags: filter

Total running time of the script: (0 minutes 9.757 seconds)

Gallery generated by Sphinx-Gallery