pyvista.ImageDataFilters.concatenate

pyvista.ImageDataFilters.concatenate#

ImageDataFilters.concatenate(
images: ImageData | Sequence[ImageData],
axis: _AxisOptions | None = None,
*,
mode: _ConcatenateModeOptions | None = None,
dtype_policy: _ConcatenateDTypePolicyOptions | None = None,
component_policy: _ConcatenateComponentPolicyOptions | None = None,
background_value: float | VectorLike[float] = 0.0,
resample_kwargs: dict[str, Any] | None = None,
)[source]#

Combine multiple images into one.

This filter uses vtkImageAppend to combine multiple images. By default, images are concatenated along the specified axis, and all images must have:

  1. identical dimensions except along the specified axis,

  2. the same scalar dtype, and

  3. the same number of scalar components.

Use mode for cases with mismatched dimensions, dtype_policy for cases with mismatched dtypes, and/or component_policy for cases with mismatched scalar components.

The output has the same origin and spacing as the first input. The origin and spacing of all other inputs are ignored.

Added in version 0.47.

Parameters:
imagesImageData | Sequence[ImageData]

The input image(s) to concatenate. The default active scalars are used for all images.

axisint | str, default: ‘x’

Axis along which the images are concatenated:

  • 0 or 'x': x-axis

  • 1 or 'y': y-axis

  • 2 or 'z': z-axis

modestr, default: ‘strict’

Concatenation mode to use. This determines how images are placed in the output. All modes operate along the specified axis except for 'preserve-extents'. Specify one of:

  • 'strict': all images must have identical dimensions except along the specified axis.

  • 'resample-off-axis': resample() off-axis dimensions of concatenated images to match the input. The on-axis dimension is not resampled.

  • 'resample-match': resample() all dimensions of concatenated images to match the input dimensions exactly. This is similar to 'resample-off-axis', except the on-axis dimension is also resampled.

  • 'resample-proportional': resample() concatenated images proportionally to preserve their aspect ratio(s).

  • 'crop-off-axis': crop() off-axis dimensions of concatenated images to match the input. The on-axis dimension is not cropped.

  • 'crop-match': Use crop() to center-crop concatenated images such that their dimensions match the input dimensions exactly. This is similar to 'crop-off-axis', except the on-axis dimension is also cropped.

  • 'preserve-extents': the extents of all images are preserved and used to place the images in the output. The whole extent of the output is the union of the input whole extents. The origin and spacing is taken from the first input. axis is not used by this mode.

Note

Images may be padded with background_value in some cases when there are mismatched dimensions.

dtype_policy‘strict’ | ‘promote’ | ‘match’, default: ‘strict’
  • 'strict': Do not cast any scalar array dtypes. All images being concatenated must have the same dtype, else a TypeError is raised.

  • 'promote': Use numpy.result_type() to compute the dtype of the output image scalars. This option safely casts all input arrays to a common dtype before concatenating.

  • 'match': Cast all array dtypes to match the input’s dtype. This casting is unsafe as it may downcast values and lose precision.

component_policy‘strict’ | ‘promote_rgba’, default: ‘strict’
  • 'strict': Do not modify the number of components of any scalars. All images being concatenated must have the same number of components, else a ValueError is raised.

  • 'promote_rgba': Increase the number of components if necessary. Grayscale scalars with one component may be promoted to RGB scalars by duplicating values, and RGB scalars may be promoted to RGBA scalars by including an opacity component. For integer dtypes, the opacity is set to the max int representable by the dtype; for floats it is set to 1.0.

background_valuefloat | VectorLike[float], default: 0

Value or multi-component vector to use as background. The output may be padded with this value for some modes when there are mismatched dimensions.

resample_kwargsdict, optional

Keyword arguments passed to resample() when using 'resample-off-axis' or 'resample-proportional' modes. Specify interpolation, border_mode or anti_aliasing options.

Returns:
ImageData

The concatenated image.

Examples

Load a 2D image: download_beach().

>>> import pyvista as pv
>>> from pyvista import examples
>>> beach = examples.download_beach()

Use select_values() to make a second version with white values converted to black to distinguish it from the original.

>>> white = [255, 255, 255]
>>> black = [0, 0, 0]
>>> beach_black = beach.select_values(white, fill_value=black, invert=True)

Concatenate them along the x-axis.

>>> concatenated = beach.concatenate(beach_black, axis='x')
>>> plot_kwargs = dict(
...     rgb=True,
...     lighting=False,
...     cpos='xy',
...     zoom='tight',
...     show_axes=False,
...     show_scalar_bar=False,
... )
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_00_00.png

Concatenate them along the y-axis.

>>> concatenated = beach.concatenate(beach_black, axis='y')
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_01_00.png

By default, concatenation requires that all off-axis dimensions match the input. Use the mode keyword to enable concatenation with mismatched dimensions.

Load a second 2D image with different dimensions: download_bird().

>>> bird = examples.download_bird()
>>> bird.dimensions
(458, 342, 1)
>>> beach.dimensions
(100, 100, 1)

Concatenate using 'resample-proportional' mode to preserve the aspect ratio of the concatenated image. Linear interpolation with antialiasing is used to avoid sampling artifacts.

>>> resample_kwargs = {'interpolation': 'linear', 'anti_aliasing': True}
>>> concatenated = beach.concatenate(
...     bird, mode='resample-proportional', resample_kwargs=resample_kwargs
... )
>>> concatenated.dimensions
(233, 100, 1)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_02_00.png

Use 'resample-proportional' again but concontenate along the z-axis instead. The bird’s aspect ratio is preserved and padded with zeros so that it can be stacked on top of beach.

>>> concatenated = beach.concatenate(
...     bird,
...     axis='z',
...     mode='resample-proportional',
...     resample_kwargs=resample_kwargs,
... )
>>> concatenated.dimensions
(100, 100, 2)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_03_00.png

Use 'resample-off-axis' to only resample off-axis dimensions. This option may distort the image.

>>> concatenated = beach.concatenate(
...     bird, mode='resample-off-axis', resample_kwargs=resample_kwargs
... )
>>> concatenated.dimensions
(558, 100, 1)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_04_00.png

Use 'resample-match' to resample all dimensions to match the input exactly. This option may also distort the image.

>>> concatenated = beach.concatenate(
...     bird, mode='resample-match', resample_kwargs=resample_kwargs
... )
>>> concatenated.dimensions
(200, 100, 1)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_05_00.png

Use the 'preserve-extents' mode. Using this mode naively may not produce the desired result, e.g. if we concatenate beach with bird, the beach image is completely overwritten since their extent fully overlap.

>>> beach.extent
(0, 99, 0, 99, 0, 0)
>>> bird.extent
(0, 457, 0, 341, 0, 0)
>>> concatenated = beach.concatenate(bird, mode='preserve-extents')
>>> concatenated.extent
(0, 457, 0, 341, 0, 0)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_06_00.png

Set the beach offset so that there is only partial overlap instead.

>>> beach.offset = (-50, -50, 0)
>>> beach.extent
(-50, 49, -50, 49, 0, 0)
>>> concatenated = beach.concatenate(bird, mode='preserve-extents')
>>> concatenated.extent
(-50, 457, -50, 341, 0, 0)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_07_00.png

Reverse the concatenation order, and use a green background value.

>>> green = pv.Color('green').int_rgb
>>> concatenated = bird.concatenate(
...     beach, mode='preserve-extents', background_value=green
... )
>>> concatenated.extent
(-50, 457, -50, 341, 0, 0)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_08_00.png

Use 'crop-off-axis' to only crop off-axis dimensions.

>>> concatenated = beach.concatenate(bird, mode='crop-off-axis')
>>> concatenated.dimensions
(558, 100, 1)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_09_00.png

Reverse the concatenation order.

>>> concatenated = bird.concatenate(beach, mode='crop-off-axis')
>>> concatenated.dimensions
(558, 342, 1)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_10_00.png

Use 'crop-match' to center-crop the images to match the input’s dimensions.

>>> concatenated = beach.concatenate(bird, mode='crop-match')
>>> concatenated.dimensions
(200, 100, 1)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_11_00.png

Reverse the concatenation order, and use a grey background value.

>>> concatenated = bird.concatenate(
...     beach, mode='crop-match', background_value=128
... )
>>> concatenated.dimensions
(558, 342, 1)
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_12_00.png

Load a binary image: download_yinyang().

>>> yinyang = examples.download_yinyang()

Use component_policy to concatenate grayscale images with RGB(A) images.

>>> concatenated = yinyang.concatenate(
...     beach, mode='resample-proportional', component_policy='promote_rgba'
... )
>>> concatenated.plot(**plot_kwargs)
../../../_images/pyvista-ImageDataFilters-concatenate-d25eb32358cc961f_13_00.png

The grayscale portion of the image is promoted to RGB in this case and the entire image has 3 components:

>>> concatenated.active_scalars.shape
(292068, 3)