_images/logo.png

Welcome!

Welcome to Imagecat … simple, flexible tools for procedural image editing.

Documentation

_images/logo.png

Installation

Imagecat

To install the latest stable version of Imagecat and its dependencies, use pip:

$ pip install imagecat

… once it completes, you’ll be able to use all of Imagecat’s core features.

OpenEXR

To work with OpenEXR images, you’ll need to have the OpenEXR library, which can’t be installed via pip. If you use Conda (which we strongly recommend), you can install it as follows:

$ conda install -c conda-forge openexr-python

Once you have OpenEXR, you can install Imagecat with the necessary dependencies:

$ pip install imagecat[exr]

Documentation

We assume that you’ll normally access this documentation online, but if you want a local copy on your own computer, do the following:

First, you’ll need the pandoc universal document converter, which can’t be installed with pip … if you use Conda (which we strongly recommend), you can install it with the following:

$ conda install pandoc

Once you have pandoc, install Imagecat along with all of the dependencies needed to build the docs:

$ pip install imagecat[doc]

Next, do the following to download a tarball to the current directory containing all of the Imagecat source code, which includes the documentation:

$ pip download imagecat --no-binary=:all: --no-deps

Now, you can extract the tarball contents and build the documentation (adjust the following for the version you downloaded):

$ tar xzvf imagecat-0.6.1.tar.gz
$ cd imagecat-0.6.1/docs
$ make html
_images/logo.png

Design

Images

Unsurprisingly, the overwhelming majority of operators in Imagecat either generate, modify, or consume images, making them one of the most important datatypes in the library.

In Imagecat, an image is a container for a set of named layers, and a layer contains one or more channels. For example, an image loaded by the imagecat.load operator might contain a layer named “C” with three channels of RGB color data, and a layer “A” with a single channel of opacity information. More sophisticated workflows typical of 3D computer graphics might involve images containing dozens of layers containing color, depth, lighting, normal, object identity, velocity information, and more.

To accomodate this, every image in Imagecat is an instance of imagecat.data.Image containing a dict of str layer names as keys, and instances of imagecat.data.Layer containing the layer data as values. Any string is a valid layer name, although some names are more common by convention, such as “C” for RGB color information and “A” for alpha channels. Layer data is always stored using Numpy arrays, which always have three dimensions, in (row, column, channel) order. Most layer data contains half-precision floating point values with linear brightness, instead of the gamma-adjusted unsigned bytes with which you may be familiar. Note that the third dimension is present even for single-channel layers like alpha channels and masks, in which case its size will be one. When working with layers, be careful to keep in mind that (row, column) slicing is the opposite of the (x, y) ordering normally used in image processing. Finally, each layer has a imagecat.data.Role, which defines how the data in the layer will be used. For example, a layer with three channels might contain RGB color information, or XYZ coordinates in world space, or XYZ velocity vectors, or UVW coordinates in texture space. The layer role is what distinguishes among these cases, which is useful in visualization and I/O.

Graph

Imagecat operators are designed to be used with Graphcat, https://graphcat.readthedocs.io, with which they are organized into computational graphs that manage executing them at the right time and in the right order. Imagecat operators are compatible with all graphcat.graph.Graph derivatives, which include graphcat.StaticGraph, graphcat.DynamicGraph, and graphcat.StreamingGraph.

Named Inputs

Named inputs are the objects that Graphcat uses to pass inputs from one computational graph task to another; depending on the type of Graph that you’re using, your Imagecat operators will be called with one of graphcat.static.NamedInputs, graphcat.dynamic.NamedInputs, or graphcat.streaming.NamedInputs, which all have compatible APIs.

Note

Since every Graphcat task has the same parameters, the reference documentation for each Imagecat operator lists the named input parameters in a separate “Named Inputs” section.

User Guide

The User Guide includes detailed individual subjects covering how to use Imagecat effectively.

Colormap Operator

[1]:
import functools
import logging
logging.basicConfig(level=logging.INFO)

import graphcat.notebook
import imagecat.color.brewer
import imagecat.notebook

mapping = functools.partial(imagecat.color.linear_map, palette=imagecat.color.brewer.palette("BlueRed"))

graph = graphcat.StaticGraph()
imagecat.add_task(graph, "/load", imagecat.operator.load, path="Wood048_2K_Color.jpg")
imagecat.add_task(graph, "/remap", imagecat.operator.remap, mapping={"Y": {"selection": [("C", 0)], "role": imagecat.data.Role.LUMINANCE}})
imagecat.add_task(graph, "/colormap", imagecat.operator.color.colormap, mapping=mapping)
imagecat.add_links(graph, "/load", ("/remap", "image"))
imagecat.add_links(graph, "/remap", ("/colormap", "image"))


graphcat.notebook.display(graph)
image = graph.output("/remap")
_images/user-guide_colormap_1_0.svg
INFO:imagecat.operator:Task /load load:
INFO:imagecat.operator:  layers: *
INFO:imagecat.operator:  path: Wood048_2K_Color.jpg
INFO:imagecat.operator:  output: Image(C: Layer(Role.RGB 2048x2048x3 float16))
INFO:imagecat.operator:Task Y remap:
INFO:imagecat.operator:  mapping: {'Y': {'selection': [('C', 0)], 'role': <Role.LUMINANCE: 10>}}
INFO:imagecat.operator:  output: Image(Y: Layer(Role.LUMINANCE 2048x2048x1 float16))
[2]:
image.layers["Y"]
[2]:
_images/user-guide_colormap_2_0.png
[3]:
image = graph.output("/colormap")
INFO:imagecat.operator.color:Task /colormap colormap:
INFO:imagecat.operator.color:  inlayer: None
INFO:imagecat.operator.color:  mapping: functools.partial(<function linear_map at 0x7fd547fd0950>, palette=<imagecat.color.Palette object at 0x7fd546f7c2d0>)
INFO:imagecat.operator.color:  outlayer: C
INFO:imagecat.operator.color:  output: Image(C: Layer(Role.RGB 2048x2048x3 float64))
[4]:
image.layers["C"]
[4]:
_images/user-guide_colormap_4_0.png

Cryptomatte Decoder

[1]:
import logging
logging.basicConfig(level=logging.DEBUG)

import graphcat.notebook
import imagecat
[2]:
mapping = {
    "CryptoPreview": {"role": imagecat.data.Role.RGB, "selection": ["uCryptoMaterial.red", "uCryptoMaterial.green", "uCryptoMaterial.blue"]},
}

graph = graphcat.DynamicGraph()
imagecat.add_task(graph, "/load", imagecat.operator.load, path="bunny_CryptoMaterial.exr")
imagecat.add_task(graph, "/preview", imagecat.operator.remap, mapping=mapping)
imagecat.add_links(graph, "/load", ("/preview", "image"))

graphcat.notebook.display(graph)
image = graph.output("/preview")
_images/user-guide_cryptomatte_2_0.svg
INFO:imagecat.operator:Task /load load:
INFO:imagecat.operator:  layers: *
INFO:imagecat.operator:  path: bunny_CryptoMaterial.exr
INFO:imagecat.operator:  output: Image(uCryptoMaterial.blue: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial.green: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial.red: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial00.alpha: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial00.blue: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial00.green: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial00.red: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial01.alpha: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial01.blue: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial01.green: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial01.red: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial02.alpha: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial02.blue: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial02.green: Layer(Role.NONE 1280x720x1 float32), uCryptoMaterial02.red: Layer(Role.NONE 1280x720x1 float32))
INFO:imagecat.operator:Task CryptoPreview remap:
INFO:imagecat.operator:  mapping: {'CryptoPreview': {'role': <Role.RGB: 1>, 'selection': ['uCryptoMaterial.red', 'uCryptoMaterial.green', 'uCryptoMaterial.blue']}}
INFO:imagecat.operator:  output: Image(CryptoPreview: Layer(Role.RGB 1280x720x3 float32))
[3]:
image.layers["CryptoPreview"]
[3]:
_images/user-guide_cryptomatte_3_0.png
[4]:
graph.output("/load").metadata
[4]:
{'CameraFilmApertureHorizontal': 1.0,
 'CameraFilmApertureVertical': 0.5625,
 'CameraFocalLength': 0.9890166521072388,
 'arnold/AA_samples': 10,
 'arnold/auto_transparency_depth': 10,
 'arnold/diffuse_depth': 1,
 'arnold/diffuse_samples': 0,
 'arnold/glossy_depth': 1,
 'arnold/glossy_samples': 0,
 'arnold/host/hw': '2 x Intel(R) Xeon(R) CPU E5645 @ 2.40GHz (12 cores, 24 logical) with 24567MB',
 'arnold/host/name': 'NYMRNDR108',
 'arnold/host/os': 'Windows 7 Professional Service Pack 1 (version 6.1, build 7601)',
 'arnold/reflection_depth': 2,
 'arnold/refraction_depth': 2,
 'arnold/refraction_samples': 0,
 'arnold/sss_samples': 3,
 'arnold/stats/date': 'Tue Mar 01 19:29:05 2016',
 'arnold/stats/geo/curve_segments': 1095000.0,
 'arnold/stats/geo/triangles': 125766.0,
 'arnold/stats/memory/peak': 8468.72265625,
 'arnold/stats/memory/start': 367.5078125,
 'arnold/stats/rays/all/pixel': 1062.9029541015625,
 'arnold/stats/rays/all/total': 1043855808.0,
 'arnold/stats/rays/camera/pixel': 96.8963851928711,
 'arnold/stats/rays/camera/total': 95160000.0,
 'arnold/stats/time/render': 591.790771484375,
 'arnold/stats/time/setup': 6.202756881713867,
 'arnold/texture_max_memory_MB': 999999.0,
 'arnold/threads': 24,
 'arnold/total_depth': 10,
 'arnold/version': 'Arnold 4.2.11.1 windows icc-14.0.2 oiio-1.5.20 rlm-11.3.1 2015/11/18 13:42:29',
 'arnold/volume_depth': 0,
 'arnold/volume_samples': 0,
 'capDate': '2016:03:01 19:29:05',
 'channels': {'uCryptoMaterial.blue': ['FLOAT', 1, 1],
  'uCryptoMaterial.green': ['FLOAT', 1, 1],
  'uCryptoMaterial.red': ['FLOAT', 1, 1],
  'uCryptoMaterial00.alpha': ['FLOAT', 1, 1],
  'uCryptoMaterial00.blue': ['FLOAT', 1, 1],
  'uCryptoMaterial00.green': ['FLOAT', 1, 1],
  'uCryptoMaterial00.red': ['FLOAT', 1, 1],
  'uCryptoMaterial01.alpha': ['FLOAT', 1, 1],
  'uCryptoMaterial01.blue': ['FLOAT', 1, 1],
  'uCryptoMaterial01.green': ['FLOAT', 1, 1],
  'uCryptoMaterial01.red': ['FLOAT', 1, 1],
  'uCryptoMaterial02.alpha': ['FLOAT', 1, 1],
  'uCryptoMaterial02.blue': ['FLOAT', 1, 1],
  'uCryptoMaterial02.green': ['FLOAT', 1, 1],
  'uCryptoMaterial02.red': ['FLOAT', 1, 1]},
 'compression': 'ZIPS_COMPRESSION',
 'compressionName': 'Zip (1 scanline)',
 'cryptomatte/xc7bccc/conversion': 'uint32_to_float32',
 'cryptomatte/xc7bccc/hash': 'MurmurHash3_32',
 'cryptomatte/xc7bccc/manifest': '{"Material10":"83ae4666","Material11":"8131354e","Material12":"758b1edb","Material7":"b5c7aeb6","Material8":"dd5dc347","Material9":"d1d42e32","ai_bad_shader":"b3e5341b","bunny_porcelain_mat":"b24b26d4","flowerA_petal":"4f6ba831","flowerB_petal":"be02d5cc","flowerStem_mat":"7f0f6696","grass_mat":"41c3eaf9","ground_mat":"ee25e74e","smallLeaf_mat":"c607dc0c","smallStalk_mat":"7ec9f550"}',
 'cryptomatte/xc7bccc/name': 'uCryptoMaterial',
 'dataWindow': [0, 0, 1279, 719],
 'displayWindow': [0, 0, 1279, 719],
 'lineOrder': 'INCREASING_Y',
 'nuke/full_layer_names': 0,
 'nuke/node_hash': '52b1af4c323e1b16',
 'nuke/version': '10.0v5',
 'pixelAspectRatio': 1.0,
 'screenWindowCenter': [0.0, 0.0],
 'screenWindowWidth': 1.0,
 'type': 'scanlineimage',
 'version': 1,
 'worldToCamera': None,
 'worldToNDC': None}
[5]:
imagecat.add_task(graph, "/cryptomatte", imagecat.operator.cryptomatte.decoder, clown=False, mattes=["bunny_porcelain_mat"])
imagecat.add_links(graph, "/load", ("/cryptomatte", "image"))

graphcat.notebook.display(graph)
image = graph.output("/cryptomatte")
_images/user-guide_cryptomatte_5_0.svg
INFO:imagecat.operator.cryptomatte:Task /cryptomatte cryptomatte.decode:
INFO:imagecat.operator.cryptomatte:  clown: False
INFO:imagecat.operator.cryptomatte:  cryptomatte: None
INFO:imagecat.operator.cryptomatte:  layer: M
INFO:imagecat.operator.cryptomatte:  mattes: ['bunny_porcelain_mat']
INFO:imagecat.operator.cryptomatte:  output: Image(M: Layer(Role.MATTE 1280x720x1 float32))
[6]:
image.layers["M"]
[6]:
_images/user-guide_cryptomatte_6_0.png
[7]:
graph.set_task("/cryptomatte/mattes", graphcat.constant(["flowerA_petal", "flowerB_petal"]))
image = graph.output("/cryptomatte")
INFO:imagecat.operator.cryptomatte:Task /cryptomatte cryptomatte.decode:
INFO:imagecat.operator.cryptomatte:  clown: False
INFO:imagecat.operator.cryptomatte:  cryptomatte: None
INFO:imagecat.operator.cryptomatte:  layer: M
INFO:imagecat.operator.cryptomatte:  mattes: ['flowerA_petal', 'flowerB_petal']
INFO:imagecat.operator.cryptomatte:  output: Image(M: Layer(Role.MATTE 1280x720x1 float32))
[8]:
image.layers["M"]
[8]:
_images/user-guide_cryptomatte_8_0.png
[9]:
graph.set_task("/cryptomatte/clown", graphcat.constant(True))
graph.set_task("/cryptomatte/mattes", graphcat.constant(["bunny_porcelain_mat","flowerA_petal","flowerB_petal","flowerStem_mat","grass_mat","ground_mat","smallLeaf_mat","smallStalk_mat"]))
image = graph.output("/cryptomatte")
INFO:imagecat.operator.cryptomatte:Task /cryptomatte cryptomatte.decode:
INFO:imagecat.operator.cryptomatte:  clown: True
INFO:imagecat.operator.cryptomatte:  cryptomatte: None
INFO:imagecat.operator.cryptomatte:  layer: M
INFO:imagecat.operator.cryptomatte:  mattes: ['bunny_porcelain_mat', 'flowerA_petal', 'flowerB_petal', 'flowerStem_mat', 'grass_mat', 'ground_mat', 'smallLeaf_mat', 'smallStalk_mat']
INFO:imagecat.operator.cryptomatte:  output: Image(M: Layer(Role.RGB 1280x720x3 float32))
[10]:
image.layers["M"]
[10]:
_images/user-guide_cryptomatte_10_0.png

Dot Operator

[1]:
import logging
logging.basicConfig(level=logging.INFO)

import graphcat.notebook
import imagecat.notebook

graph = graphcat.StaticGraph()
imagecat.add_task(graph, "/load", imagecat.operator.load, path="Wood048_2K_Color.jpg")
imagecat.add_task(graph, "/dot", imagecat.operator.color.dot, matrix=[[0.6], [0.6], [0.1]])
imagecat.add_links(graph, "/load", ("/dot", "image"))


graphcat.notebook.display(graph)
image = graph.output("/load")
_images/user-guide_dot_1_0.svg
INFO:imagecat.operator:Task /load load:
INFO:imagecat.operator:  layers: *
INFO:imagecat.operator:  path: Wood048_2K_Color.jpg
INFO:imagecat.operator:  output: Image(C: Layer(Role.RGB 2048x2048x3 float16))
[2]:
image.layers["C"]
[2]:
_images/user-guide_dot_2_0.png
[3]:
image = graph.output("/dot")
INFO:imagecat.operator.color:Task /dot dot:
INFO:imagecat.operator.color:  inlayer: None
INFO:imagecat.operator.color:  matrix: [[0.6]
 [0.6]
 [0.1]]
INFO:imagecat.operator.color:  outdtype: float16
INFO:imagecat.operator.color:  outlayer: Y
INFO:imagecat.operator.color:  outrole: Role.LUMINANCE
INFO:imagecat.operator.color:  output: Image(Y: Layer(Role.LUMINANCE 2048x2048x1 float16))
[4]:
image.layers["Y"]
[4]:
_images/user-guide_dot_4_0.png

Fill Operator

[1]:
import logging
logging.basicConfig(level=logging.INFO)

import graphcat
import imagecat

# Create a color fill.
graph = graphcat.StaticGraph()
imagecat.add_task(graph, "/fill", imagecat.operator.color.fill, values=[1, 0.5, 0])
image = graph.output("/fill")
INFO:imagecat.operator.color:Task /fill fill:
INFO:imagecat.operator.color:  layer: C
INFO:imagecat.operator.color:  res: [256 256]
INFO:imagecat.operator.color:  role: Role.RGB
INFO:imagecat.operator.color:  values: [1.  0.5 0. ]
INFO:imagecat.operator.color:  output: Image(C: Layer(Role.RGB 256x256x3 float16))
[2]:
image.layers["C"]
[2]:
_images/user-guide_fill_2_0.png
[3]:
# Create a grayscale fill.
imagecat.add_task(graph, "/fill2", imagecat.operator.color.fill, layer="A", values=[0], role=imagecat.data.Role.ALPHA)
image = graph.output("/fill2")
INFO:imagecat.operator.color:Task /fill2 fill:
INFO:imagecat.operator.color:  layer: A
INFO:imagecat.operator.color:  res: [256 256]
INFO:imagecat.operator.color:  role: Role.ALPHA
INFO:imagecat.operator.color:  values: [0]
INFO:imagecat.operator.color:  output: Image(A: Layer(Role.ALPHA 256x256x1 float16))
[4]:
image.layers["A"]
[4]:
_images/user-guide_fill_4_0.png

Gaussian Operator

[1]:
import logging
logging.basicConfig(level=logging.INFO)

import graphcat.notebook
import imagecat.notebook

graph = graphcat.StaticGraph()
imagecat.add_task(graph, "/text", imagecat.operator.render.text, string="Blur!")
imagecat.add_task(graph, "/gaussian", imagecat.operator.blur.gaussian, radius=["5px", "5px"])
imagecat.set_links(graph, "/text", ("/gaussian", "image"))

graphcat.notebook.display(graph)
image = graph.output("/gaussian")
_images/user-guide_gaussian_1_0.svg
INFO:imagecat.operator.render:Task /text text:
INFO:imagecat.operator.render:  anchor: mm
INFO:imagecat.operator.render:  fontindex: 0
INFO:imagecat.operator.render:  fontname: /Users/tshead/src/imagecat/imagecat/LeagueSpartan-SemiBold.ttf
INFO:imagecat.operator.render:  fontsize: 0.33h
INFO:imagecat.operator.render:  layer: A
INFO:imagecat.operator.render:  position: ('0.5w', '0.5h')
INFO:imagecat.operator.render:  res: [256 256]
INFO:imagecat.operator.render:  string: Blur!
INFO:imagecat.operator.render:  output: Image(A: Layer(Role.ALPHA 256x256x1 float16))
INFO:imagecat.operator.blur:Task /gaussian gaussian:
INFO:imagecat.operator.blur:  layer: None
INFO:imagecat.operator.blur:  radius: ['5px', '5px']
INFO:imagecat.operator.blur:  output: Image(A: Layer(Role.ALPHA 256x256x1 float16))
[2]:
image.layers["A"]
[2]:
_images/user-guide_gaussian_2_0.png

Offset Operator

[1]:
import logging
logging.basicConfig(level=logging.INFO)

import graphcat.notebook
import imagecat.notebook

graph = graphcat.StaticGraph()
imagecat.add_task(graph, "/text", imagecat.operator.render.text, string="Offset!")
imagecat.add_task(graph, "/offset", imagecat.operator.transform.offset, offset=("0.5w", 0))
imagecat.set_links(graph, "/text", ("/offset", "image"))

graphcat.notebook.display(graph)
image = graph.output("/offset")
_images/user-guide_offset_1_0.svg
INFO:imagecat.operator.render:Task /text text:
INFO:imagecat.operator.render:  anchor: mm
INFO:imagecat.operator.render:  fontindex: 0
INFO:imagecat.operator.render:  fontname: /Users/tshead/src/imagecat/imagecat/LeagueSpartan-SemiBold.ttf
INFO:imagecat.operator.render:  fontsize: 0.33h
INFO:imagecat.operator.render:  layer: A
INFO:imagecat.operator.render:  position: ('0.5w', '0.5h')
INFO:imagecat.operator.render:  res: [256 256]
INFO:imagecat.operator.render:  string: Offset!
INFO:imagecat.operator.render:  output: Image(A: Layer(Role.ALPHA 256x256x1 float16))
INFO:imagecat.operator.transform:Task /offset offset:
INFO:imagecat.operator.transform:  layers: *
INFO:imagecat.operator.transform:  offset: ('0.5w', 0)
INFO:imagecat.operator.transform:  output: Image(A: Layer(Role.ALPHA 256x256x1 float16))
[2]:
image.layers["A"]
[2]:
_images/user-guide_offset_2_0.png

Text Operator

[1]:
import logging
logging.basicConfig(level=logging.INFO)

import graphcat
import imagecat

graph = graphcat.StaticGraph()
imagecat.add_task(graph, "/text", imagecat.operator.render.text)
image = graph.output("/text")
INFO:imagecat.operator.render:Task /text text:
INFO:imagecat.operator.render:  anchor: mm
INFO:imagecat.operator.render:  fontindex: 0
INFO:imagecat.operator.render:  fontname: /Users/tshead/src/imagecat/imagecat/LeagueSpartan-SemiBold.ttf
INFO:imagecat.operator.render:  fontsize: 0.33h
INFO:imagecat.operator.render:  layer: A
INFO:imagecat.operator.render:  position: ('0.5w', '0.5h')
INFO:imagecat.operator.render:  res: [256 256]
INFO:imagecat.operator.render:  string: Text!
INFO:imagecat.operator.render:  output: Image(A: Layer(Role.ALPHA 256x256x1 float16))
[2]:
image.layers["A"]
[2]:
_images/user-guide_text_2_0.png

Uniform Noise Operator

[1]:
import logging
logging.basicConfig(level=logging.INFO)

import graphcat
import imagecat

# Create grayscale noise.
graph = graphcat.StaticGraph()
imagecat.add_task(graph, "/uniform", imagecat.operator.noise.uniform)
image = graph.output("/uniform")
INFO:imagecat.operator.noise:Task /uniform uniform:
INFO:imagecat.operator.noise:  high: 1.0
INFO:imagecat.operator.noise:  layer: Y
INFO:imagecat.operator.noise:  low: 0.0
INFO:imagecat.operator.noise:  res: [256 256]
INFO:imagecat.operator.noise:  role: Role.LUMINANCE
INFO:imagecat.operator.noise:  seed: 1234
INFO:imagecat.operator.noise:  output: Image(Y: Layer(Role.LUMINANCE 256x256x1 float16))
[2]:
image.layers["Y"]
[2]:
_images/user-guide_uniform_2_0.png
[3]:
# Create color noise.
imagecat.add_task(graph, "/uniform2", imagecat.operator.noise.uniform, layer="C", role=imagecat.data.Role.RGB)
image = graph.output("/uniform2")
INFO:imagecat.operator.noise:Task /uniform2 uniform:
INFO:imagecat.operator.noise:  high: 1.0
INFO:imagecat.operator.noise:  layer: C
INFO:imagecat.operator.noise:  low: 0.0
INFO:imagecat.operator.noise:  res: [256 256]
INFO:imagecat.operator.noise:  role: Role.RGB
INFO:imagecat.operator.noise:  seed: 1234
INFO:imagecat.operator.noise:  output: Image(C: Layer(Role.RGB 256x256x3 float16))
[4]:
image.layers["C"]
[4]:
_images/user-guide_uniform_4_0.png
_images/logo.png

Development

Getting Started

If you haven’t already, you’ll want to get familiar with the Imagecat repository at http://github.com/shead-custom-design/imagecat … there, you’ll find the Imagecat source code, issue tracker, discussions, and wiki.

You’ll need to install Graphviz and pandoc, neither of which can be installed via pip. If you use Conda (which we strongly recommend), you can install them as follows:

$ conda install graphviz pandoc

You’ll also need OpenEXR which also can’t be installed via pip. With Conda (again - strongly recommended), do the following:

$ conda install -c conda-forge openexr-python

Next, you’ll need to install all of the extra dependencies needed for Imagecat development:

$ pip install imagecat[all]

Then, you’ll be ready to obtain Imagecat’s source code and install it using “editable mode”. Editable mode is a feature provided by pip that links the Imagecat source code into the install directory instead of copying it … that way you can edit the source code in your git sandbox, and you don’t have to keep re-installing it to test your changes:

$ git clone https://github.com/shead-custom-design/imagecat.git
$ cd imagecat
$ pip install --editable .

Versioning

Imagecat version numbers follow the Semantic Versioning standard.

Coding Style

The Imagecat source code follows the PEP-8 Style Guide for Python Code.

Running Regression Tests

To run the Imagecat test suite, simply run regression.py from the top-level source directory:

$ cd imagecat
$ python regression.py

The tests will run, providing feedback on successes / failures.

Test Coverage

When you run the test suite with regression.py, it also automatically generates code coverage statistics. To see the coverage results, open .cover/index.html in a web browser.

Building the Documentation

To build the documentation, run:

$ cd imagecat/docs
$ make html

Once the documentation is built, you can view it by opening docs/_build/html/index.html in a web browser.

_images/logo.png

API Reference

Contents:

imagecat module

Image processing functionality based on Graphcat computational graphs, http://graphcat.readthedocs.io.

Add links between tasks in a graphcat.Graph.

This function calls-through to graphcat.Graph.add_links(), and is provided for symmetry with add_task().

imagecat.add_task(graph, name, fn, **parameters)[source]

Simplify setting-up graphcat tasks with parameters.

Virtually all non-trivial Imagecat operations have parameters that affect their operation. Because individually creating parameter tasks and linking them with the main task is tiresome and verbose, use this function instead.

Parameters
  • graph (graphcat.Graph, required) – The Graphcat graph where the new task will be created.

  • name (str, required) – The name of the new task.

  • fn (callable, required) – The Imagecat operation to use for the new task.

  • parameters (additional keyword arguments, optional) – Each extra keyword argument will be turned into a parameter task and linked with the main task. Each parameter name is created by concatenating name with the keyword name, separated by a slash “/”.

Returns

name – Name of the newly-created operation, which may be different than name.

Return type

str

imagecat.set_expression(graph, name, expression, locals={})[source]

Setup an expression task in a graphcat.Graph.

This function calls-through to graphcat.Graph.set_expression(), but provides a library of Imagecat-specific functionality that can be used by expressions.

Set links between tasks in a graphcat.Graph.

This function calls-through to graphcat.Graph.set_links(), and is provided for symmetry with add_task().

imagecat.unique_name(graph, name)[source]

Return name, modified to be unique within graph.

Parameters
  • graph (graphcat.Graph, required) – The graph where name will be used.

  • name (str, required) – Task name to be adjusted.

imagecat.color module

Functionality for color mapping and colorspace conversion.

class imagecat.color.Palette(colors, reverse=False)[source]

Bases: object

Storage for an ordered collection of colors.

A palette is an ordered collection of colors. Typically, palettes are used to define color mappings.

See also

srgb_to_linear()

Useful for converting colors from other sources into linear space.

Parameters
  • colors (numpy.ndarray, required) – \(M \times N\) matrix containing \(M\) colors with \(N\) channels each. Note that while three channels for colors is typical, any number of channels is allowed. The color channels must be in linear space, not sRGB.

  • reverse (boolean, optional) – If True, reverse the order of colors.

property colors

Color data stored by this palette.

Returns

\(M \times N\) matrix containing \(M\) colors with \(N\) channels each.

Return type

numpy.ndarray

imagecat.color.categorical_map(data, palette)[source]

Convert scalar data to color data using a categorical map.

Integer input values will be used to lookup colors in palette. Modulo arithmetic ensures that colors are repeated for negative or out-of-bound colors. Floating point values are truncated using “floor” prior to lookup.

Parameters
  • data (numpy.ndarray, required) – The data to be mapped.

  • palette (Palette, required) – The palette of colors to use for the categorical mapping.

Returns

mapped – Mapped data with the same shape as data, but an extra dimension added.

Return type

numpy.ndarray

imagecat.color.linear_map(data, palette, min=None, max=None)[source]

Convert scalar data to color data using a linear map.

Input values between min and max will be linearly mapped to the colors in palette. If min or max are None, the corresponding value will be computed from the data.

Parameters
  • data (numpy.ndarray, required) – The data to be mapped.

  • palette (Palette, required) – The palette of colors to use for the linear mapping.

  • min (number, optional) – If None (the default) uses the minimum value in data.

  • max (number, optional) – If None (the default) uses the maximum value in data.

Returns

mapped – Mapped data with the same shape as data, but an extra dimension added.

Return type

numpy.ndarray

imagecat.color.linear_to_srgb(data)[source]

Convert linear color data to sRGB.

Acessed from https://entropymine.com/imageworsener/srgbformula

Parameters

data (numpy.ndarray, required) – Array of any shape containing linear data to be converted to sRGB.

Returns

converted – Array with the same shape as data containing values in sRGB space.

Return type

numpy.ndarray

imagecat.color.srgb_to_linear(data)[source]

Convert sRGB data to linear color.

Acessed from https://entropymine.com/imageworsener/srgbformula

Parameters

data (numpy.ndarray, required) – Array of any shape containing sRGB data to be converted to linear.

Returns

converted – Array with the same shape as data containing values in linear space.

Return type

numpy.ndarray

imagecat.color.basic module

Functionality for working with high quality color maps.

imagecat.color.basic.palette(name, reverse=False)[source]

Factory for imagecat.color.Palette instances based on a set of high quality color palettes.

Currently, the palettes “Blockbody”, “ExtendedBlackbody”, “Kindlmann”, and “ExtendedKindlemann” are supported.

Parameters
  • name (str, required) – The name of the palette to use.

  • reverse (bool, optional) – If True, reverse the order of the colors.

Returns

palette – Palette with the requested colors.

Return type

imagecat.color.Palette

imagecat.color.brewer module

Functionality for working with Color Brewer color maps, https://colorbrewer2.org.

imagecat.color.brewer.linear_map(name, count=None, reverse=False)[source]

Warning

function ‘imagecat.color.brewer.linear_map’ undocumented

imagecat.color.brewer.palette(name, count=None, reverse=False)[source]

Factory for imagecat.color.Palette instances using Color Brewer 2 palettes.

Parameters
  • name (str, required) – The name of the Color Brewer palette to use.

  • count (int, optional) – Selects the Color Brewer palette with the given number of colors, or the maximum number of colors if None (the default).

  • reverse (bool, optional) – If True, reverse the order of the colors.

Returns

palette – Palette with the given color brewer colors.

Return type

imagecat.color.Palette

imagecat.data module

Functionality for manipulating images and related data structures.

class imagecat.data.Image(layers=None, metadata=None)[source]

Bases: object

Storage for a multi-layer bitmap image.

An Imagecat Image is composed of zero-to-many layers, which are instances of Layer. Each layer is named, and all layer names must be unique.

Parameters
  • layers (dict, optional) – Dictionary mapping str layer names to Layer instances that contain the data for each layer. If None (the default), creates an empty (no layers) image.

  • metadata (dict, optional) – Arbitrary user-defined metadata for the image. This could be populated by image loaders, modified in operators, and subsets saved by writers. An example of real-world metadata is Cryptomatte information loaded from an EXR file.

See also

Images

For an in-depth discussion of how images are stored in Imagecat.

copy(layers=None, metadata=None)[source]

return a shallow copy of the image, with optional modifications.

Returns a new instance of Image that can be altered without modifying the original. Note that the new image will references the same layers as the original, unless a new set of layers are supplied as an argument.

Parameters

layers (dict, optional) – Dictionary mapping str layer names to Layer instances that contain the data for each layer. Replaces the original layers if not None (the default).

Returns

image – The new image instance with optional modifications.

Return type

Image

property layers

dict containing image layers.

Returns

layers – Dictionary mapping str layer names to Layer instances that contain the data for each layer.

Return type

dict

match_layer_names(patterns)[source]

Return layer names in this image that match the given patterns.

See match_layer_names() for a description of the pattern syntax.

Parameters

patterns (str, required) – Patterns to match against this image’s layer names.

Returns

layers – Layer names in this image that match patterns.

Return type

sequence of str

property metadata

dict containing image metadata.

Returns

metadata – Dictionary containing arbitrary image metadata.

Return type

dict

class imagecat.data.Layer(*, data, role=None)[source]

Bases: object

Storage for one layer in a bitmap image.

An Imagecat Layer contains the data and metadata that describe a single layer in an Imagecat Image. This includes the raw data itself, plus an enumerated role that describes the semantic purpose of the layer.

Parameters
  • data (numpy.ndarray, required) – A three dimensional \(M \times N \times C\) array containing the layer data, organized into \(M\) rows in top-to-bottom order, \(N\) columns in left-to-right order, and \(C\) channels. The array dtype should be numpy.float16 for most data, with numpy.float32 and numpy.int32 reserved for special cases such as depth maps and object id maps, respectively.

  • role (Role, optional) – Semantic purpose of the layer. If None (the default), the role will default to Role.NONE.

See also

Images

For an in-depth discussion of how images are stored in Imagecat.

copy(data=None, role=None)[source]

Return a shallow copy of the layer, with optional modifications.

This method returns a new instance of Layer that can be altered without modifying the original. Note that the new layer still references the same data as the original, unless a new data array is supplied as an argument.

Parameters
  • data (numpy.ndarray, optional) – Replaces the existing data array in the new layer, if not None (the default).

  • role (Role, optional) – Replaces the existing role in the new layer, if not None (the default).

Returns

layer – The new layer instance with modifications.

Return type

Layer

property dtype

Numpy dtype of the underlying data array.

Returns

dtype

Return type

numpy.dtype

property res

Layer resolution in x and y.

Returns

res – The resolution of the layer, ignoring the number of channels.

Return type

(width, height) tuple

property shape

Shape of the underlying data array.

Returns

shape

Return type

(rows, columns, channels) tuple

class imagecat.data.Role(value)[source]

Bases: Enum

Semantic description of how Layer data should be interpreted.

Because Imagecat allows an image to contain an arbitrary number of layers with arbitray names, and a layer can contain one of many different types of data - not just color information - Role is used to indicate how the data in a given layer will be used. The layer role can influence many operations in Imagecat, including visualization and file IO.

See also

Images

For an in-depth discussion of how images are stored in Imagecat.

ALPHA = 8

Layer with one channel of alpha (opacity) information.

BLUE = 7

Layer with one channel of blue color information.

DEPTH = 11

Layer with one channel of depth (distance from viewer) information.

GREEN = 6

Layer with one channel of green color information.

GREENBLUE = 3

Layer with two channels of green-blue color information.

LUMINANCE = 10

Layer with one channel of luminance (intensity) information.

MATTE = 9

Layer with one channel of matte (selection / mask) information.

NONE = 0

General purpose layer with an unknown role and any number of channels.

NORMAL = 16

Layer with three channels of normal vector information.

RED = 5

Layer with one channel of red color information.

REDBLUE = 4

Layer with two channels of red-blue color information.

REDGREEN = 2

Layer with two channels of red-green color information.

RGB = 1

Layer with three channels of red-green-blue color information.

RGBA = 12

Layer with three channels of red-green-blue color and one channel of alpha (opacity) information.

UV = 13

Layer with two channels of texture coordinate information.

VELOCITY = 15

Layer with three channels of velocity information.

XYZ = 14

Layer with three channels of position information.

imagecat.data.channels(role)[source]

Return a set of standard channel names for a given role.

Parameters

role (Role, required) –

Returns

channels

Return type

list of str

imagecat.data.default_font()[source]

Path to a default font file included with Imagecat.

Returns

path – Absolute path to the default Imagecat font.

Return type

str

imagecat.data.depth(role)[source]

Returns the number of channels (depth) for the given role.

Parameters

role (Role, required) –

Returns

depth

Return type

int

imagecat.data.from_array(data, role=None, name=None)[source]

Warning

function ‘imagecat.data.from_array’ undocumented

imagecat.data.match_layer_names(names, patterns)[source]

Match image layer names against a pattern.

Use this function to implement operators that operate on multiple image layers. patterns is a str that can contain multiple whitespace delimited patterns. Patterns can include "*" which matches everything, "?" to match a single character, "[seq]" to match any character in seq, and "[!seq]" to match any character not in seq.

Parameters
  • names (Sequence of str, required) – The image layer names to be matched.

  • pattern (str, required) – Whitespace delimited collection of patterns to match against layer names.

Returns

names

Return type

sequence of str layer names that match patterns.

imagecat.data.to_pil(layer)[source]

Convert a Layer to a PIL.Image.

This is useful for visualization and disk IO.

Parameters

layer (Layer, required) – The layer to be converted

Returns

pil_image – PIL image containing the layer data.

Return type

PIL.Image

imagecat.expression module

Helper functions providing Imagecat-specific functionality for expression tasks.

The following builtin functions can be used in Imagecat expression tasks:

imagecat.expression.graph()
imagecat.expression.out(name)
imagecat.expression.res(name)
imagecat.expression.shape(name)
imagecat.expression.builtins(graph)[source]

Return a dict containing functions that can be used in expressions.

Parameters

graph (graphcat.Graph, required) – Graph that will contain the expression task to be executed.

Returns

builtins – Dict containing functions that can be used in expressions.

Return type

dict

imagecat.io module

Helpers for implementing Imagecat I/O.

imagecat.io.loaders = [<function pickle_loader>, <function pil_loader>]

List of available loader plugins. In-house plugins may be prepended to this list for use with imagecat.operator.load().

imagecat.io.openexr_loader(task, path, layers)[source]

Image loader plugin for OpenEXR (.exr) files.

Implemented using https://www.excamera.com/sphinx/articles-openexr.html

Use imagecat.operator.load() to load images in an Imagecat workflow.

imagecat.io.openexr_saver(task, image, layers, path)[source]

Image saver plugin for OpenEXR (.exr) files.

Implemented using https://www.excamera.com/sphinx/articles-openexr.html

Use imagecat.operator.save() to save images in an Imagecat workflow.

imagecat.io.pickle_loader(task, path, layers)[source]

Image loader plugin for Imagecat Pickle (.icp) files.

The .icp format serializes an Imagecat image as a gzip2-compressed Python pickle object. It is primarily used in testing, and is not recommended for general use.

Use imagecat.operator.load() to load images in an Imagecat workflow.

imagecat.io.pickle_saver(task, image, layers, path)[source]

Image saver plugin for Imagecat Pickle (.icp) files.

The .icp format serializes an Imagecat image as a gzip2-compressed Python pickle object. It is primarily used in testing, and is not recommended for general use.

Use imagecat.operator.save() to save images in an Imagecat workflow.

imagecat.io.pil_loader(task, path, layers)[source]

Image loader plugin that uses Pillow for file I/O.

Loads any file format supported by Pillow, https://pillow.readthedocs.io.

Use imagecat.operator.load() to load images in an Imagecat workflow.

imagecat.io.pil_saver(task, image, layers, path)[source]

Image saver plugin that uses Pillow for file I/O.

Saves any file format supported by Pillow, https://pillow.readthedocs.io.

Use imagecat.operator.save() to save images in an Imagecat workflow.

imagecat.io.savers = [<function pickle_saver>, <function pil_saver>]

List of available saver plugins. In-house plugins may be prepended to this list for use with imagecat.operator.save().

imagecat.notebook module

Integration with Jupyter notebooks, https://jupyter.org

imagecat.notebook.display(image, layers='*', width=None, height=None)[source]

Display image inline in a Jupyter notebook.

Parameters
  • image (dict, required) – Image to be displayed.

  • layers (str, optional) – Names of the image layers to display. Use “*” (the default) to display all layers.

  • width (str, optional) – Optional HTML width for each image.

  • height (str, optional) – Optional HTML height for each image.

imagecat.operator module

Functions that produce, consume, and modify Imagecat images.

imagecat.operator.delete(graph, name, inputs)[source]

Delete layers from an image.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image with layers to be deleted.

  • layers (str, optional) – Pattern matching the image layers are deleted. Default: “*”, which deletes all layers.

Returns

image – A copy of the input image with some layers deleted.

Return type

imagecat.data.Image

imagecat.operator.load(graph, name, inputs)[source]

Load an image from a file.

The file loader plugins in imagecat.io are used to load specific file formats. See that module for details, and to write loaders of your own.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs

path (str, required) – Filesystem path of the file to be loaded.

Returns

image – Image loaded from the file.

Return type

imagecat.data.Image

imagecat.operator.merge(graph, name, inputs)[source]

Merge multiple images into one.

This operator merges the layers from multiple images into a single image. The images must all have the same resolution. Upstream inputs are merged in order, sorted by input name. Later image layers with duplicate names will overwrite earlier layers. Callers can prevent this by renaming layers upstream with the rename() operator.

See also

imagecat.operator.transform.composite()

Composites one image over another using a mask.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs

every input (imagecat.data.Image, optional) – Images to be merged.

Returns

image – New image containing the union of all input layers.

Return type

imagecat.data.Image

imagecat.operator.remap(graph, name, inputs)[source]

Merge and split layers from an image.

Parameters
  • graph (Graph, required) – Graphcat graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image containing image layers and channels to be mapped.

  • mapping (dict, optional) – Maps existing layers and channels to the output. Default: {}, which returns an empty image.

Returns

image – A new image containing only the mapped layers and channels.

Return type

imagecat.data.Image

imagecat.operator.rename(graph, name, inputs)[source]

Rename layers within an image.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image containing layers to be renamed.

  • changes (dict, optional) – Maps existing names to new names. Default: {}, which does nothing.

Returns

image – A copy of the input image with some layers renamed.

Return type

imagecat.data.Image

imagecat.operator.save(graph, name, inputs)[source]

Save an image to a file.

The file saver plugins in imagecat.io are used to save specific file formats. See that module for details, and to write savers of your own.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this function, including:

Named Inputs
  • image (imagecat.data.Image, required) – Image to be saved.

  • path (str, required) – Filesystem path of the file to be saved.

  • layers (str, optional) – Pattern matching the layers to be saved. Default: ‘*’, which saves all layers.

imagecat.optional module

Helpers for implementing optional functionality.

imagecat.optional.module(name)[source]

Quietly load a module by name, ignoring errors.

Note that dotted names, e.g. pkg.mod will return the top-level package, just like the import statement.

Parameters

name (str) – Name of the module to be loaded.

Returns

module

Return type

loaded module if successful, or None.

imagecat.operator.blur module

Operators for blurring images.

imagecat.operator.blur.gaussian(graph, name, inputs)[source]

Blur an image using a Gaussian kernel.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image containing layer to be blurred.

  • layer (str, optional) – Name of the layer to be blurred. Default: None.

  • sigma ((x, y) tuple, required) – Width of the gaussian kernel in pixels along each dimension.

Returns

image – A copy of the input image with some layers blurred.

Return type

imagecat.data.Image

imagecat.operator.color module

Functions that generate and alter image color.

imagecat.operator.color.colormap(graph, name, inputs)[source]

Convert single-channel layers to RGB layers using a colormap.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image with layer to be color mapped.

  • inlayer (str, optional) – image layer to be color mapped. Default: None.

  • outlayer (str, optional) – Name of the output image layer. Default: "C".

  • mapping (Python callable, optional) – Mapping function that accepts a shape (rows, columns, 1) array as input and produces an RGB (rows, columns, 3) shaped array as output. If None (the default), a linear map with a Color Brewer 2 Blue-Red palette will be used.

Returns

image – A copy of the input image with some layers mapped.

Return type

imagecat.data.Image

imagecat.operator.color.dot(graph, name, inputs)[source]

Compute the dot product of a image.data.Layer and a matrix.

This is most commonly used to convert an RGB layer to grayscale, but the operator is capable of converting any depth \(M\) layer to depth \(N\) using an \(M \times N\) matrix. The values in each output channel will be a weighted sum of the input channels, using weights stored in the corresponding matrix column.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image containing layer to be converted.

  • inlayer (str, optional) – Layer to be converted. Default: None.

  • outlayer (str, optional) – Output layer. Default: “Y”.

  • outrole (imagecat.data.Role, optional) – Role for the new layer. Defaults to imagecat.data.role.LUMINANCE.

  • matrix (\(M \times N\) numpy.ndarray matrix, optional) – Matrix controlling how much each input channel contributes to each output channel. Defaults to an RGB-to-grayscale matrix. \(M\) must match the depth of the input layer, and \(N\) must match the expected depth of the output role.

Returns

image – Image containing the new layer.

Return type

imagecat.data.Image

imagecat.operator.color.fill(graph, name, inputs)[source]

Generate an image with a single solid-color layer.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • layer (str, optional) – New layer name. Default: “C”.

  • res ((width, height) tuple, optional) – Resolution of the new image. Default: (256, 256).

  • role (imagecat.data.Role, optional) – Semantic role of the new layer. Default: imagecat.data.Role.RGB.

  • values (sequence of values, optional) – Values for the new layer. The number of values must be appropriate for role. Default: [1, 1, 1].

Returns

image – New image with a single solid-color layer.

Return type

imagecat.data.Image

imagecat.operator.cryptomatte module

Functionality for working with Cryptomattes, see https://github.com/Psyop/Cryptomatte.

imagecat.operator.cryptomatte.decoder(graph, name, inputs)[source]

Extract matte(s) from an image containing Cryptomatte data.

Parameters
  • graph (Graph, required) – Graphcat graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • clown (bool, optional) – If True, extract a clown matte containing a unique color for the ID that has the greatest coverage in a given pixel. Default: False

  • image (imagecat.data.Image, required) – Image containing Cryptomatte data to be decoded.

  • layer (str, optional) – Output matte layer name. Default: “M”.

  • mattes (list of str, optional) – List of mattes to extract. The output will contain the union of all the given mattes. Default: [], which returns an empty matte.

  • cryptomatte (str, optional) – Name of the Cryptomatte to extract. Use this parameter to control which Cryptomatte to use, for images that contain multiple Cryptomattes. Default: None, which will match one Cryptomatte or raise an exception if there is more than one.

Returns

matte – The extracted matte.

Return type

imagecat.data.Image

imagecat.operator.noise module

Operators that generate images containing noise.

imagecat.operator.noise.uniform(graph, name, inputs)[source]

Generate an image containing random values drawn from a uniform distribution.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • high (number, optional) – Highest value in the generated noise. Default: 1.

  • layer (str, optional) – Name of the layer to be created. Default: ‘Y’.

  • low (number, optional) – Lowest value for the generated noise. Default: 0.

  • role (imagecat.data.Role, optional) – Role for the layer to be created. Default: imagecat.data.Role.LUMINANCE.

  • seed (int, optional) – Random seed for the random noise function. Default: 1234.

  • res ((width, height) tuple, optional) – Resolution of the new image along each dimension. Default: [256, 256].

Returns

image – New image with one layer containing uniform noise.

Return type

imagecat.data.Image

imagecat.operator.render module

Functions that generate new image data.

imagecat.operator.render.text(graph, name, inputs)[source]

Generate an image containing text.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • anchor (str, optional) – Anchor point for text placement, defined at https://pillow.readthedocs.io/en/latest/handbook/text-anchors.html#text-anchors. Defaults to “mm”.

  • fontindex (integer, optional) – Index of the font to use within a multi-font file. Defaults to 0.

  • fontname (str, optional) – Path to a font file. Defaults to imagecat.data.default_font().

  • fontsize (Size of the rendered font, optional) – Default: “0.33h”, which is one-third the height of the output image.

  • layer (str, optional) – Name of the generated layer. Default: [“A”].

  • position ((x, y) tuple, optional) – Position of the text anchor relative to the output image. Default: [“0.5w”, “0.5h”], which is centered vertically and horizontally.

  • res ((width, height) tuple, optional) – Resolution of the output image. Default: [256, 256].

  • string (str, optional) – String to be rendered. Default: “Text”.

Returns

image – New image containing rendered text.

Return type

imagecat.data.Image

imagecat.operator.transform module

Operators that modify images by transforming content.

imagecat.operator.transform.composite(graph, name, inputs)[source]

Composite foreground and background layers using a mask and optional transformation.

Parameters
  • graph (Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • background (imagecat.data.Image, required) – Image containing the background layer.

  • bglayer (str, optional) – Name of the background layer. Defaults to None.

  • fglayer (str, optional) – Name of the foreground layer. Defaults to None.

  • foreground (imagecat.data.Image, required) – Image containing the foreground layer.

  • layer (str, optional) – Name of the output image layer. Defaults to the value of bglayer.

  • mask (imagecat.data.Image, optional) – Image containing the foreground layer mask. If omitted, the foreground layer is assumed to be 100% opaque.

  • masklayer (str, optional) – Name of the mask layer. Defaults to None.

  • orientation (number, optional) – Rotation of the foreground layer for the composition. Default: 0.

  • pivot ((x, y) tuple, optional) – Position of the foreground pivot point. All rotation and positioning is relative to this point. Default: [“0.5w”, “0.5h”], which is centered on the foreground.

  • position ((x, y) tuple, optional) – Position of the foreground layer over the background layer. All rotation and positioning is relative to the pivot point. Default: [“0.5w”, “0.5h”], which is centered on the background.

Returns

image – New image with a single solid-color layer.

Return type

imagecat.data.Image

imagecat.operator.transform.offset(graph, name, inputs)[source]

Offset layers in an image.

Parameters
  • graph (graphcat.Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image containing layers to be offset.

  • layers (str, optional) – Pattern matching the layers to be offset. Default: ‘*’, which offsets all layers.

  • offset ((x, y) tuple, required) – Distance to offset layers along each dimension.

Returns

image – A copy of the input image with some layers offset.

Return type

imagecat.data.Image

imagecat.operator.transform.resize(graph, name, inputs)[source]

Resize an image to a new resolution.

Parameters
  • graph (graphcat.Graph, required) – Graph that owns this task.

  • name (hashable object, required) – Name of the task executing this function.

  • inputs (Named Inputs, required) – Inputs for this operator.

Named Inputs
  • image (imagecat.data.Image, required) – Image to be resized.

  • order (int, optional) – Resampling filter order. Default: ‘3’ for bicubic resampling.

  • res ((width, height) tuple, optional) – New resolution of the image along each dimension.

Returns

image – A copy of the input image that has been resized.

Return type

imagecat.data.Image

imagecat.operator.util module

Functions that produce, consume, and modify Imagecat images.

imagecat.operator.util.array(ndim=None, shape=None, dtype=None)[source]

Factory for parameter converters that return arrays.

Parameters
  • ndim (integer, optional) – Raise exceptions if the number of value dimensions don’t match.

  • shape (integer or tuple of integers, optional) – Raise exceptions if the value shape doesn’t match.

  • dtype (numpy.dtype, optional) – If specified, the returned array will be coerced to the given dtype.

Returns

converter – Callable that takes a single value as input and produces a numpy.ndarray as output.

Return type

callable

imagecat.operator.util.log_result(log, name, operation, output, **parameters)[source]

Standard logging output for operators when they’re executed.

imagecat.operator.util.optional_image(name, inputs, input)[source]

Extract an optional image from task inputs.

Parameters
  • name (hashable object, required) – The name of the task being executed.

  • inputs (Named Inputs, required) – Named inputs containing task function arguments.

  • input (hashable object, required) – Name of the optional input image.

Raises

RuntimeError – If inputs contains input, but it isn’t a imagecat.data.Image.

Returns

image – The optional image from inputs.

Return type

class:imagecat.data.Image or None

imagecat.operator.util.optional_input(name, inputs, input, *, type=None, default=None)[source]

Extract an optional parameter from task inputs.

Parameters
  • name (hashable object, required) – The name of the task being executed.

  • inputs (Named Inputs, required) – Named inputs containing task function arguments.

  • input (hashable object, required) – Name of the input parameter.

  • type (callable, optional) – Function for testing / converting the parameter value.

  • default (Any python object, optional) – Default value that will be returned if inputs doesn’t contain input.

Returns

parameter – The optional parameter from inputs, or the default value.

Return type

Any python object.

imagecat.operator.util.optional_layer(name, inputs, input, *, layer=None, role=None, depth=None, dtype=None)[source]

Extract an optional layer from task inputs.

Parameters
  • name (hashable object, required) – The name of the task being executed.

  • inputs (Named Inputs, required) – Named inputs containing task function arguments.

  • input (hashable object, required) – Name of the optional input image.

  • layer (str, optional) – The name of the optional layer. If None (the default) and the image only contains one layer, use it.

  • role (imagecat.data.Role, optional) – If specified, the layer must have a matching role.

  • depth (int, optional) – If specified, the layer must have a matching depth (number of channels).

  • dtype (numpy.dtype, optional) – If specified, the layer must have a matching dtype.

Returns

imagecat.operator.util.require_image(name, inputs, input)[source]

Extract an image from task inputs.

Parameters
  • name (hashable object, required) – The name of the task being executed.

  • inputs (Named Inputs, required) – Named inputs containing task function arguments.

  • input (hashable object, required) – Name of the required input image.

Raises

RuntimeError – If inputs doesn’t contain the required input.

Returns

image – The required image from inputs.

Return type

class:imagecat.data.Image

imagecat.operator.util.require_input(name, inputs, input, *, type=None)[source]

Extract a parameter from task inputs.

Parameters
  • name (hashable object, required) – The name of the task being executed.

  • inputs (Named Inputs, required) – Named inputs containing task function arguments.

  • input (hashable object, required) – Name of the required input parameter.

  • type (callable, optional) – Function for testing / converting the type of the input parameter value.

Raises

RuntimeError – If inputs doesn’t contain the required input.

Returns

parameter – The required parameter from inputs.

Return type

Any python object.

imagecat.operator.util.require_layer(name, inputs, input, *, layer=None, role=None, depth=None, dtype=None)[source]

Extract a layer from task inputs.

Parameters
  • name (hashable object, required) – The name of the task being executed.

  • inputs (Named Inputs, required) – Named inputs containing task function arguments.

  • input (hashable object, required) – Name of the required input image.

  • layer (str, optional) – The name of the required layer. If None (the default) and the image only contains one layer, use it.

  • role (imagecat.data.Role, optional) – If specified, the layer must have a matching role.

  • depth (int, optional) – If specified, the layer must have a matching depth (number of channels).

  • dtype (numpy.dtype, optional) – If specified, the layer must have a matching dtype.

Raises

RuntimeError – If a layer matching all of the criteria can’t be found.

Returns

imagecat.operator.util.transform(source, target_shape, *, pivot, position, orientation, scale, order)[source]

Transform an image using an affine transformation.

Parameters
  • source (numpy.ndarray, required) – Image to be transformed.

  • target_shape (2-tuple of integers, required) – Desired output image size, as a (rows, cols) tuple. Note that this does not have to match the size of the source image. By default, the source image will be centered in the output, cropped if necessary.

  • pivot (2-tuple of numbers, required) – Location of the point on the source image around which scaling and rotation takes place.

  • orientation (number, required) – Rotation of the source around its pivot point, in degrees. Positive angles lead to counter-clockwise rotation.

  • position (2-tuple of numbers, required) – Position of the image pivot point relative to target_shape.

  • scale (2-tuple of numbers, required) – Scale of the source image around its pivot point.

Returns

  • rowoffset (integer) – Vertical offset of the returned array relative to the upper-left corner of target_shape

  • coloffset (integer) – Horizontal offset of the returned array relative to the upper-left corner of target_shape

  • image (numpy.ndarray) – The transformed image.

imagecat.require module

Functionality for testing preconditions and assertions.

imagecat.require.loaded_module(modules)[source]

Function decorator that tests whether module(s) have already been loaded.

Parameters

modules (str or sequence of str, required) – Names of the modules that must already be loaded for the wrapped function to execute.

Raises

RuntimeError – If any module in modules isn’t already loaded.

imagecat.units module

Functionality for performing unit conversions.

imagecat.units.length(value, size, default='px')[source]

Convert a length value to pixels.

Supported unit abbreviations include:

“px”, “pixel”, “pixels”

absolute length in pixels

“w”, “width”

relative length, as a fraction of the width of an image

“h”, “height”

relative length, as a fraction of the height of an image

“min”

relative length, as a fraction of the smaller of width and height

“max”

relative length, as a fraction of the larger of width and height

Relative lengths will be relative to some reference that is context-specific and documented. For example: the text operator fontsize is relative to the size of the output image.

Parameters
  • value (number, str or (number, str) tuple, required) – Value to be converted. The value may be a number (in which case the default parameter will specify the unit of measure), a str containing a number and unit abbreviation, or a (value, units) tuple.

  • size ((width, height) tuple, required) – Reference width and height for use when the caller specifies a relative unit of measure. Note that width and height must be specified in pixels.

  • default (str, optional) – Default unit of measure to use when value is a plain number.

Returns

valuevalue converted to pixel units. Note that the result is a floating-point number, so callers may need to convert to an int if they are intend to e.g. specifying the resolution of an image.

Return type

number

_images/logo.png

Compatibility

A quick disclaimer on backwards-compatibility for Imagecat users:

Imagecat follows the Semantic Versioning standard for assigning version numbers in a way that has specific meaning. As of this writing Imagecat releases are still in the 0.y.z development phase, which means (among other things) that the API may change at any time. We try not to be abusive about it, but you should be prepared for the occasional bump on the road to the 1.0 release.

_images/logo.png

Release Notes

Imagecat 0.7.0 - November 21, 2022

  • Make it easier to manage optional functionality.

  • Simplify creating images from numpy arrays.

  • Switch to pyproject.toml for packaging and flit for builds.

  • Cleanup and organize documentation.

Imagecat 0.6.1 - October 21, 2021

  • Make it easier to display single-layer images in Jupyter notebooks.

  • Updated the way we collect code coverage data.

  • Switched from Zulip to Github Discussions for support.

Imagecat 0.6.0 - October 13, 2021

  • PIL reader didn’t handle luma-only images correctly.

  • Incorporate platform-specific regression test reference images.

  • Reorganize and streamline the documentation.

  • Switch from Travis-CI to GitHub Actions for continuous integration.

  • Clarify where named inputs are documented.

Imagecat 0.5.0 - March 19, 2021

  • Cryptomatte operator works with a wider range of files, and better matches the behavior of other implementations.

  • Added an option to extract clown mattes from the Cryptomatte operator, with caller control over which mattes to include.

  • Missing dependencies cause failures at run time instead of import time.

  • Replaced the rgb2gray operator with dot, which can created weighted combinations of layers with any depth.

  • Added new layer roles for RGBA, matte, luminance, depth, UV, position, velocity, and normal data, and subsets of RGB channels.

  • Substantial reorganization and cleanup of the documentation.

Imagecat 0.4.0 - December 9, 2020

  • Initial support for storing image metadata.

  • OpenEXR loader imports metadata.

  • imagecat.notebook.display() dynamically renders image layers using IPython widgets.

  • Added new imagecat.data.Role enumerations for varying subsets of RGB, alpha, matte, luminance, and depth data.

  • Added imagecat.operator.remap() for creating new images from arbitrary combinations of existing layers and components.

  • Added support for Cryptomatte decoding.

  • imagecat.data.Layer supports Jupyter rich output.

  • Expanded / cleaned-up the documentation.

  • Substantial reorganization of operators into separate modules.

  • Removed support for explicit layer component names.

Imagecat 0.3.0 - December 4, 2020

  • Add support for categorical color maps.

  • Added optional parameters to control the output range of imagecat.operator.uniform().

  • Updated the implementation for compatibility with graphcat >= 0.10.0.

  • Dramatically improved performance for imagecat.operator.composite().

  • OpenEXR loader generates simplified output.

Imagecat 0.2.0 - November 23, 2020

  • Move functionality for image conversion to the imagecat.data module.

  • Add scaling support to imagecat.operator.composite().

  • Add control over the reconstruction kernel in imagecat.operator.composite().

  • Made the mask input optional for imagecat.operator.composite().

Imagecat 0.1.0 - November 13, 2020

  • Initial Release.

_images/logo.png

Support

The Imagecat documentation:

Visit our GitHub repository for access to source code, test results, issue tracker, and the wiki:

Our coverage statistics are updated automatically when modifications are committed:

For Imagecat questions, comments, or suggestions, get in touch with the team at:

Otherwise, you can contact Tim directly:

_images/logo.png

Credits

Included in Imagecat

Cynthia A. Brewer, “ColorBrewer: Color Advice for Maps,” http://colorbrewer2.org, accessed October, 2014.

Tyler Finck, “League Spartan” TrueType font https://github.com/theleagueof/league-spartan:

Copyright (c) 2016-2020, Tyler Finck <hi@tylerfinck.com>

Copyright (c) 2014, Micah Rich <micah@micahrich.com>,
with Reserved Font Name: "League Spartan".

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL

Version 1.1 - 26 February 2007

Jason Summers, “A close look at the sRGB formula” https://entropymine.com/imageworsener/srgbformula, accessed November, 2020.

Indices and tables