cryptomatte#

This is the main entry point for loading and interacting with cryptomatte files and their associated data. It fully supports loading any number of cryptomattes from a given file and performs validation on the metadata, channels and masks to ensure correctness.

Cryptomattes are a special image type that stores ID masks with support for transparency. To do this it stores alternating rank and coverage channels where the rank channel is the ID of the pixel and the coverage channel is an additive value describing how much of that mask is stored in this rank-coverage pair.

This is to allow for transparent pixels by storing only one mask per pixel per rank-coverage pair and then storing further ids that lie on the same pixel in another rank-coverage pair. The cryptomatte channels are stored as follows:

{typename}.r    - deprecated -> may be skipped
{typename}.g    - deprecated (may contain filtered preview colors) -> may be skipped
{typename}.b    - deprecated (may contain filtered preview colors) -> may be skipped
{typename}00.r  - id rank channel 0
{typename}00.g  - coverage channel 0
{typename}00.b  - id rank channel 1
{typename}00.a  - coverage channel 1
{typename}01.r  - id rank channel 2
{typename}01.g  - coverage channel 2
{typename}01.b  - id rank channel 3
{typename}01.a  - coverage channel 3
...

Here typename can be anything, but usually it will be something along the lines of Cryptomatte, CryptoAsset, CryptoMaterial etc. Due to this cascading rank system you will typically find most data on the first rank-coverage pairs with the further pairs being used to resolve intersections on transparent pixels with diminishing returns.

In DCCs you will often find a setting allowing you to control the numer of levels, this is the number of rank-coverage pairs and dictates how many objects may overlap on a single pixel.

The cmatte::cryptomatte struct loads the above mentioned channels and performs mask computation on the fly. It allows you to either target a specific mask, multiple masks or all masks using the mask, masks or mask_compressed and masks_compressed functions (more on those later). This has the benefit of only loading the masks you need into memory, skipping over the rest.

As a rule of thumb however, you should always try to extract as many masks in one go as you need, as for each mask query we need to iterate all of the above channels.

Compression

This Cryptomatte implementation uses in-memory compression for the channels, and optionally also compresses the masks as they are being extracted. This is primarily to greatly reduce memory usage as masks typically compress quite well, but also for performance reasons (less allocations -> greater speed). For specifics please check out the benchmarking section in the documentation.

Note

In-memory compression for extracted masks is currently only supported for the c++ library.

loading a cryptomatte from disk#

This is a simple example of getting you up and running with the cryptomatte-api, loading a file from disk (which validates it) and then extract one or more masks from the image.

#include <cryptomatte/cryptomatte.h>

auto matte = cmatte::cryptomatte::load("from/disk/path", false /* load preview channels */);
auto mask = matte.mask("my_mask"); // will throw if 'my_mask' is not available
auto all_masks = matte.masks_compressed();
import cryptomatte_api as cmatte

matte = cmatte.Cryptomatte.load("from/disk/path", load_preview=False)
mask = matte.mask("my_mask") # will raise if 'my_mask' is not available
all_masks = matte.masks()

cryptomatte#

struct cryptomatte#

A cryptomatte file loaded from disk or memory storing the channels as compressed buffer.

default ctors, copy ctors etc.

cryptomatte() = default#
cryptomatte(cryptomatte&&) = default#
cryptomatte &operator=(cryptomatte&&) = default#
cryptomatte(const cryptomatte&) = delete#

delete copy ctor and copy assignment operator as compressed::channel is not copyable.

cryptomatte &operator=(const cryptomatte&) = delete#

create cryptomattes

cryptomatte(std::unordered_map<std::string, compressed::channel<float32_t>> channels, const cmatte::metadata &metadata)#

Construct a cryptomatte from a set of input channels and associated metadata.

This constructor initializes a cryptomatte instance by validating and organizing a set of compressed float32 channels. It filters and categorizes the provided channels into recognized cryptomatte channels and legacy channels based on the supplied metadata. All cryptomatte channels are required to have consistent encoding parameters (number of chunks, chunk size, resolution) for successful construction.

Parameters:
  • channels – A map of channel names to compressed float32 channel data. This must not be empty. Channels must conform to the encoding consistency required by cryptomatte.

  • metadata – Metadata used to validate and classify the provided channels into cryptomatte or legacy categories.

Throws:

std::invalid_argument – if the channel map is empty or if any cryptomatte channel has inconsistent encoding parameters compared to the others.

cryptomatte(std::unordered_map<std::string, std::vector<float32_t>> channels, size_t width, size_t height, const cmatte::metadata &metadata)#

Construct a cryptomatte from raw float32 image channel data and metadata.

This constructor initializes a cryptomatte instance by converting raw float32 vectors into compressed channels, using the specified image dimensions. Channels are classified as cryptomatte or legacy based on the provided metadata. All cryptomatte channels must have the same vector size, corresponding to the resolution (width × height).

Parameters:
  • channels – A map of channel names to raw float32 data vectors. The size of each vector must match width × height.

  • width – The width of the image in pixels.

  • height – The height of the image in pixels.

  • metadata – Metadata used to validate and classify the provided channels into cryptomatte or legacy categories.

Throws:

std::invalid_argument – if the channel list is empty or if any cryptomatte channel has a mismatched size.

static std::vector<cryptomatte> load(std::filesystem::path file, bool load_preview)#

Load a file containing cryptomattes into multiple cryptomattes.

These cryptomattes will be ordered by their name alphabetically.

Parameters:
  • file – The file path to load the image from. This must be an exr file.

  • load_preview – Whether to load the legacy preview channels: {typename}.r, {typename}.g, {typename}.b which may store a preview channel (but don’t have to). If this is set to false we will never load these channels speeding up loading.

Returns:

The detected and loaded cryptomattes, there may be multiple or none per-file.

Public Functions

size_t width() const#
size_t height() const#
bool has_preview() const#

Checks whether this cryptomatte contains the preview (legacy) channels.

These are classified by the specification to be the {typename}.r, {typename}.g, {typename}.b (as opposed to {typename}00.r etc. for the actual cryptomatte channels). These are legacy but often used to store a preview of all the mattes.

This function checks that these channels are present and loaded (the loading of them can be controlled via the load_preview flag of load()). To find out if a file contains them in the first place one can use the static versions cryptomatte::has_preview

Returns:

Whether the preview channels exist (and are loaded)

std::vector<std::vector<float32_t>> preview() const#

Returns a vector of the preview (legacy) channels.

These may not always be available or loaded so the function can return either 0 or 3 channels. These channels are the {typename}.r, {typename}.g, {typename}.b channels and may store a filtered preview image of all the mattes but these channels should not be used for computing masks. Please use the masks or masks_compressed functions for this instead.

Returns:

The legacy/preview channels (if present)

std::unordered_map<std::string, compressed::channel<float32_t>> extract_preview_compressed()#

Extracts the legacy/preview channels from the cryptomatte instance.

These may not always be available or loaded so the function can return either 0 or 3 channels. These channels are the {typename}.r, {typename}.g, {typename}.b channels and may store a filtered preview image of all the mattes but these channels should not be used for computing masks. Please use the masks or masks_compressed functions for this instead.

This overloads returns the channels in their compressed format which is ideal if you wish to operate on the compressed channels directly rather than paying the memory cost of decompressing them. After these have been extracted they are entirely in your control and extracting them again is not possible.

Returns:

The legacy/preview channels (if present)

std::vector<float32_t> mask(std::string name) const#

Extract the mask with the given name from the cryptomatte, computing the pixels as we go.

This function assumes that a valid cryptomatte manifest exists, if it doesn’t/or the name is not known to us this function will throw a std::invalid_argument.

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

name – The name as it is stored in the manifest, could e.g. be ‘bunny1’

Returns:

The decoded cryptomatte mask

std::vector<float32_t> mask(uint32_t hash) const#

Extract the mask with the given hash from the cryptomatte, computing the pixels as we go.

The hash here is the pixel hash of the mask you wish to extract. If the hash could not be found this function will return an empty mask (black)

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

hash – The hash of the mask

Returns:

The decoded cryptomatte mask

compressed::channel<float32_t> mask_compressed(std::string name) const#

Extract the mask with the given name from the cryptomatte as compressed channel, computing on the fly.

This function assumes that a valid cryptomatte manifest exists, if it doesn’t/or the name is not known to us this function will throw a std::invalid_argument.

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

name – The name as it is stored in the manifest, could e.g. be ‘bunny1’

Returns:

The decoded cryptomatte mask

compressed::channel<float32_t> mask_compressed(uint32_t hash) const#

Extract the mask with the given hash from the cryptomatte as compressed channel, computing on the fly.

The hash here is the pixel hash of the mask you wish to extract. If the hash could not be found this function will return an empty mask (black)

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

hash – The hash of the mask

Returns:

The decoded cryptomatte mask

std::unordered_map<std::string, std::vector<float32_t>> masks(std::vector<std::string> names) const#

Extract the masks with the given names from the cryptomatte, computing on the fly.

This function assumes that a valid cryptomatte manifest exists, if it doesn’t/or the names are not known to us this function will throw a std::invalid_argument.

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

names – The names to extract, could e.g. be {‘bunny1’, ‘car’, …}

Returns:

The decoded cryptomattes mapped by their name

std::unordered_map<std::string, std::vector<float32_t>> masks(std::vector<uint32_t> hashes) const#

Extract the masks with the given names from the cryptomatte, computing on the fly.

The hashes here are the pixel hashes of the masks you wish to extract. If a hash could not be found that mask will be skipped.

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

names – The hashes to extract, any non-valid hashes will be skipped and will also not appear in the output

Returns:

The decoded cryptomattes mapped by their name (if the manifest exists) or by their hashes in std::string form.

std::unordered_map<std::string, std::vector<float32_t>> masks() const#

Extract all of the cryptomatte masks computing them on the fly.

Returns:

The decoded cryptomattes mapped by their name (if the manifest exists) or by their hashes in std::string form.

std::unordered_map<std::string, compressed::channel<float32_t>> masks_compressed(std::vector<std::string> names) const#

Extract the masks with the given names from the cryptomatte into compressed buffers, computing on the fly.

This function assumes that a valid cryptomatte manifest exists, if it doesn’t/or the names are not known to us this function will throw a std::invalid_argument.

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

names – The names to extract, could e.g. be {‘bunny1’, ‘car’, …}

Returns:

The decoded cryptomattes mapped by their name

std::unordered_map<std::string, compressed::channel<float32_t>> masks_compressed(std::vector<uint32_t> hashes) const#

Extract the masks with the given hashes from the cryptomatte into compressed buffers, computing on the fly.

The hashes here are the pixel hashes of the masks you wish to extract. If a hash could not be found that mask will be skipped.

Note: For performance reasons it is often be desirable to extract as many masks as you need in one go rather than extracting them individually.

Parameters:

names – The hashes to extract, any non-valid hashes will be skipped and will also not appear in the output

Returns:

The decoded cryptomattes mapped by their name (if the manifest exists) or by their hashes in std::string form.

std::unordered_map<std::string, compressed::channel<float32_t>> masks_compressed() const#

Extract all of the cryptomatte masks into compressed buffers, computing them on the fly.

Returns:

The decoded cryptomattes mapped by their name (if the manifest exists) or by their hashes in std::string form.

size_t num_levels() const noexcept#

Retrieve the number of levels (rank-coverage pairs) the cryptomatte was encoded with. This may not be the level The cryptomatte was rendered with as sometimes DCCs will pad this number to the nearest multiple of two.

cmatte::metadata &metadata()#

Get the metadata associated with the cryptomatte file, this includes things such as the channel names, the unique key identifier and the cryptomatte manifest (a mapping of human-readable names to their hashes).

const cmatte::metadata &metadata() const#
class cryptomatte_api.Cryptomatte#

A cryptomatte file loaded from disk or memory storing the channels as compressed buffer

__init__(*args, **kwargs)#

Overloaded function.

  1. __init__(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte) -> None

Construct an empty Cryptomatte object.

  1. __init__(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte, channels: collections.abc.Mapping[str, typing.Annotated[numpy.typing.ArrayLike, numpy.float32]], width: typing.SupportsInt, height: typing.SupportsInt, metadata: cmatte::metadata) -> None

Construct a Cryptomatte from raw float32 image arrays.

Parameters:
  • channels – Mapping of channel names to float32 image arrays. Each array must be shaped (height, width).

  • width – Image width.

  • height – Image height.

  • metadata – Metadata used to validate and classify the provided channels.

Raises:

ValueError – If the channel map is empty or any array has mismatched shape.

has_preview(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte) bool#

Return whether preview (legacy .r/.g/.b) channels are available and loaded.

Returns:

True if preview channels are available, False otherwise.

height(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte) int#

Return the height of the cryptomatte in pixels.

Returns:

Height of the cryptomatte.

static load(file: Union[os.PathLike, str, bytes], load_preview: bool = False) list[cryptomatte_api.lib64.cryptomatte_api.Cryptomatte]#

Load cryptomatte(s) from an EXR file.

Parameters:
  • file – Path to an EXR file containing cryptomatte channels.

  • load_preview – Whether to load the legacy preview channels (.r/.g/.b).

Returns:

List of loaded Cryptomatte instances.

mask(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte, name_or_hash: Union[str, SupportsInt]) numpy.typing.NDArray[numpy.float32]#

Compute and return a decoded mask for the given object name.

Parameters:

name – Name from the manifest.

Returns:

np.float32 array mask.

masks(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte, names_or_hashes: Optional[Union[collections.abc.Sequence[str], collections.abc.Sequence[SupportsInt]]] = None) dict[str, numpy.typing.NDArray[numpy.float32]]#
metadata(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte) cmatte::metadata#

Return the metadata associated with this cryptomatte.

Returns:

Metadata object.

num_levels(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte) int#

Return the number of encoded rank-coverage levels.

Returns:

Number of levels.

preview(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte) list[numpy.typing.NDArray[numpy.float32]]#

Return the preview (legacy) image channels as float32 numpy arrays. This list may be empty if the cryptomatte was loaded without load_preview enabled.

Returns:

List of numpy arrays representing preview channels, may be empty

width(self: cryptomatte_api.lib64.cryptomatte_api.Cryptomatte) int#

Return the width of the cryptomatte in pixels.

Returns:

Width of the cryptomatte.