DataObjectFilters.resample_to_image

DataObjectFilters.resample_to_image#

DataObjectFilters.resample_to_image(
*,
reference_volume: ImageData | None = None,
dimensions: VectorLikeInt | None = None,
spacing: float | VectorLikeFloat | None = None,
target_n_points: int | None = None,
max_n_points: int | None = None,
rounding_func: Callable[[VectorLikeFloat], VectorLikeInt] | None = None,
cell_length_percentile: float | None = None,
cell_length_sample_size: int | None = None,
method: Literal['sample', 'interpolate'] | None = None,
null_value: float | None = None,
mark_blank: bool = False,
tolerance: float | None = None,
categorical: bool | None = None,
radius: float | None = None,
sharpness: float | None = None,
progress_bar: bool = False,
) → ImageData[source]#

Resample this mesh’s arrays onto a uniform grid.

The mesh’s arrays are resampled at the points of a new ImageData. Each point is the center of a voxel, and the voxels tile the input’s bounds, so the image’s points are inset half a spacing from those bounds. This is a one-line alternative to building the grid explicitly and calling sample() or interpolate() on it.

The output geometry can be controlled in several ways:

  1. Specify the output geometry using a reference_volume.

  2. Specify the spacing explicitly.

  3. Specify the dimensions explicitly.

  4. Specify the target_n_points. The spacing is isotropic and estimated so the output has approximately this many points.

  5. Specify the cell_length_percentile. The spacing is estimated from the mesh’s cells using the specified percentile.

Set max_n_points to cap the result of any of these. It differs from target_n_points, which is a resolution to aim for: a geometry specified explicitly raises if it exceeds the cap, while an estimated one is coarsened to fit.

Use reference_volume for full control of the output’s geometry. For all other options, the geometry is implicitly defined such that the generated voxels fit the bounds of the input mesh.

If no inputs are provided, cell_length_percentile=0.1 (tenth percentile) is used by default to estimate the spacing, so the input’s own cells set the resolution.

The values are resampled with one of two methods, chosen by method:

  1. 'sample' interpolates inside the input’s cells, and is the default for an input with volumetric cells. It is the only method which uses the input’s topology, and the only one which reads its cell data. It keeps the voxels whose centre lies inside a cell, so the result stops just inside a volumetric mesh’s surface.

  2. 'interpolate' interpolates from the input’s points within radius, and is the default otherwise, since a cell search misses most of a curved surface and all of a point cloud. It reads point data only. By default radius reaches across the input’s cells, so every voxel a cell crosses is filled and the result straddles the input.

Both write to the output’s point data, and resampling a solid therefore fills different voxels than resampling its surface.

A flat input is the exception: its voxels are centered on it, so 'sample' reaches every one of them and reproduces the values exactly.

Added in version 0.50.

Note

Voxels with no value are flagged with a 'vtkValidPointMask' point data array. Set mark_blank=True to also hide them with a 'vtkGhostType' array, so volume rendering the output shows those regions as transparent.

Note

A MultiBlock is resampled as a whole: one grid covers every block, a voxel takes its value from whichever block reaches it, and only the arrays every block has are kept. The method is chosen for the composite as a whole, so a surface among solids needs method='interpolate' to be filled.

Parameters:
reference_volumeImageData, optional

Volume to use as a reference. The output will have the same dimensions, origin, spacing, offset, and direction_matrix as the reference. Only this geometry is taken from it; its arrays are not read.

dimensionsVectorLikeInt, optional

Dimensions of the generated image. Set this value to control the dimensions explicitly. If unset, the dimensions are defined implicitly through other parameters. See summary and examples for details.

spacingfloat | VectorLikeFloat, optional

Approximate spacing to use for the generated image. Set this value to control the spacing explicitly. If unset, the spacing is defined implicitly through other parameters. See summary and examples for details.

target_n_pointsint, optional

Approximate number of points to generate. The spacing is isotropic and chosen so the output holds about this many points, distributed between the axes in proportion to the input’s bounds. An axis with no extent holds a single point and takes no part in the count. Rounding to whole voxels means the count is approached, not matched exactly. Cannot be set with reference_volume, dimensions, spacing, or the cell length options.

max_n_pointsint, optional

Strict upper bound on the number of points generated. Unlike target_n_points, which is only approached, this limit is never exceeded. How it is enforced depends on how the geometry is defined:

  • Geometry set explicitly, with reference_volume, dimensions, spacing or a cell length option, raises if it exceeds the limit.

  • target_n_points must not exceed the limit, and the grid estimated from it is coarsened if rounding would take it above.

  • Geometry left to the defaults is coarsened to fit, without raising.

rounding_funcCallable[VectorLikeFloat, VectorLikeInt], optional

Control how the dimensions are rounded to integers based on the provided or calculated spacing. Should accept a length-3 vector containing the dimension values along the three directions and return a length-3 vector. numpy.round() is used by default.

Rounding the dimensions implies rounding the actual spacing.

Cannot be set together with reference_volume or dimensions.

cell_length_percentilefloat, optional

Cell length percentage p to use for computing the default spacing. Default is 0.1 (tenth percentile) and must be between 0 and 1. The p-th percentile is computed from the lengths of the edges of the mesh’s own cells, with every block of a composite included. Up to cell_length_sample_size cells are used, drawn at random with a fixed seed, and degenerate edges with zero length are ignored.

The estimate is a single value which is used for all three axes, so an anisotropic input is resampled below its native spacing along its coarsest axis.

Has no effect if dimensions or reference_volume are specified.

cell_length_sample_sizeint, optional

Maximum number of cells to use when computing the cell_length_percentile. 100 000 cells are used by default.

method‘sample’ | ‘interpolate’, optional

Method used to compute each voxel’s value. 'sample' interpolates inside the input’s cells, and 'interpolate' interpolates from its points within radius. By default 'sample' is used for an input with volumetric cells and 'interpolate' is used otherwise. See summary for details.

'interpolate' reads point data only, so the input’s cell data is dropped and a warning is raised. Call cell_data_to_point_data() on the input to keep it. It writes every array as float32, so an integer array comes back as floats.

null_valuefloat, optional

Value given to the voxels which no value could be resampled for. Every array of the output takes it, and zero is used by default. Both methods accept it, though only method='interpolate' has it natively; under method='sample' this filter fills the voxels itself, and the value must fit the data type of the arrays it fills.

mark_blankbool, default: False

Hide the voxels which no value could be resampled for, by flagging them in a 'vtkGhostType' array. These are the voxels holding null_value. Every voxel is visible by default, and the blank ones can be filtered with the 'vtkValidPointMask' array instead.

tolerancefloat, optional

Requires method='sample', and is forwarded to sample(). Tolerance used when locating the cell a voxel is sampled from. The tolerance computed by vtkResampleWithDataSet is used by default.

categoricalbool, optional

Requires method='sample', and is forwarded to sample(). Control whether the source point data is to be treated as categorical. If True, the resampled point data will be determined by a nearest neighbor interpolation scheme. False by default.

radiusfloat, optional

Requires method='interpolate', and is forwarded to interpolate(). Distance from a voxel’s center within which the input’s points contribute to it. By default it is the 95th percentile of the length of the input’s cell edges, so that a cell’s points reach every voxel the cell crosses, and never less than half a voxel’s diagonal, which is what a point cloud gets.

sharpnessfloat, optional

Requires method='interpolate', and is forwarded to interpolate(). Sharpness of the Gaussian interpolation kernel, 2.0 by default. As this value increases, the weights of points far from a voxel’s center fall off faster.

progress_barbool, default: False

Display a progress bar to indicate progress.

Returns:
ImageData

Uniform grid with the input’s arrays sampled onto its points. The voxels are points, not VOXEL cells; points_to_cells() converts them and carries the blanking over. See Image Data Representations for the difference.

Examples#

Download Python source code | Download Jupyter notebook

Resample a solid sphere’s point data onto a uniform grid. The spacing is estimated from the mesh’s own cells.

>>> import pyvista as pv
>>> solid_sphere = pv.SolidSphere()
>>> solid_sphere['height'] = solid_sphere.points[:, 2]
>>> volume = solid_sphere.resample_to_image()

Volume render the result. Every voxel is visible, so the volume is a solid block.

>>> volume.plot(volume=True)
../../../_images/pyvista-DataObjectFilters-resample_to_image-7098cb92e6f4b5ac_00_00.png

Set mark_blank=True to hide the voxels no value could be resampled for.

>>> blanked = solid_sphere.resample_to_image(mark_blank=True)
>>> blanked.plot(volume=True)
../../../_images/pyvista-DataObjectFilters-resample_to_image-7098cb92e6f4b5ac_01_00.png

Set the dimensions or the spacing to control the resolution explicitly.

>>> solid_sphere.resample_to_image(spacing=0.05).dimensions
(20, 20, 20)

Compare the three kinds of input the sphere can be given as: a solid, the surface enclosing it, and its points alone.

>>> def resample_as_voxels(mesh):
...     image = mesh.resample_to_image(spacing=0.05, mark_blank=True)
...     return image.points_to_cells()
>>> surface = solid_sphere.extract_surface(algorithm=None)
>>> pointset = solid_sphere.cast_to_pointset()
>>> datasets = {
...     'solid': solid_sphere,
...     'solid voxels': resample_as_voxels(solid_sphere),
...     'surface': surface,
...     'surface voxels': resample_as_voxels(surface),
...     'pointset': pointset,
...     'pointset voxels': resample_as_voxels(pointset),
... }
>>> pv.plot_compare(datasets, shape=(3, 2), scalars='height')
../../../_images/pyvista-DataObjectFilters-resample_to_image-7098cb92e6f4b5ac_02_00.png

The solid is filled throughout, and the surface fills only the shell its cells occupy. The point cloud keeps the solid’s interior points, so it reaches the interior too, but only within radius of each point, which leaves gaps where the points are sparse.

Resample every block of a MultiBlock onto one grid.

>>> blocks = pv.MultiBlock([pv.Sphere(), pv.Sphere(center=(1.5, 0, 0))])
>>> for block in blocks:
...     block['height'] = block.points[:, 2]
>>> blocks.resample_to_image(target_n_points=20_000).dimensions
(50, 20, 20)

See Also#

pyvista.DataObjectFilters.sample

Filter used by method='sample'. Samples onto an existing mesh of any type, and exposes options this one does not.

pyvista.DataSetFilters.interpolate

Filter used by method='interpolate'. Interpolates onto an existing mesh of any type, and exposes options this one does not.

pyvista.ImageDataFilters.resample

Change the dimensions or spacing of an image which is already ImageData.

pyvista.DataSetFilters.voxelize_binary_mask

Voxelize the inside of a closed surface as a mask. Operates on a surface’s geometry and generates a new array instead of resampling existing ones. It places its voxels identically to this filter, and keeps essentially the same voxels that method='sample' keeps for the solid a surface encloses.

pyvista.create_grid

Create a uniform grid surrounding a dataset. Its points lie on the dataset’s bounds, whereas this filter’s voxels fit them.