Lately I installed new version of Natron and decided to key some test images. Of course I haven’t found any proprietary tools like Keylight. So before start I had to create custom Keylight-like keyer scheme.

Source image:

In this case we need difference keyer. The main idea is extracting alpha from image by difference between channels. For green screen we will use:

a = Ag - (Ar + Ab) / 2

where A - foreground, a - alpha, r,g,b - red, green, blue channels.

In Natron it looks like img2

I use grey constants as weights.

The next step is to copy this scheme and apply green screen values(constant) as input. Then we have to divide result of first scheme by second to increase values.

img3

Finally, we need to multiply result by green constant and subtract it from original.

img4

Now RGB is despilled and keyed. If our source out of range(0,1), we disable ‘maximum’ knob in clamp node .

For alpha I suggest a little trick with channels. It’s possible to use inverted result from divide node as final, but I prefer add more information from RGB to alpha. Check screenshot below:

img6

Now it works great. It is not enough to accomplish complicated tasks, but it is just starting point for educational purposes. Next code snippet shows an implementation of this algorithm for SeExpr node. SeExpr is a small expression language developed by Walt Disney Animation Studio. Don’t forget add 2 scalar and 1 color params inside node.

RGB Script:

# Source
src = Cs;
sR = Cs[0];
sG = Cs[1];
sB = Cs[2];

# Weights
rw = x1; # 0.5
bw = x2; # 0.5

# Green screen
gs = color1;
gsR = gs[0];
gsG = gs[1];
gsB = gs[2];

diff1 = (sG - (sB*bw+sR*rw));
diff2 = (gsG - (gsB*bw+gsR*rw));

div = (diff1/diff2);
key = div*gs;
key = src - clamp(key, 0, key);
key 

Alpha Script:

# Source
src = Cs;
sR = Cs[0];
sG = Cs[1];
sB = Cs[2];

# Weights
rw = x1;
bw = x2;

# Green screen
gs = color1;
gsR = gs[0];
gsG = gs[1];
gsB = gs[2];

diff1 = (sG - (sB*bw+sR*rw));
diff2 = (gsG - (gsB*bw+gsR*rw));

div = (diff1/diff2);
key = div*gs;
key = src - clamp(key, 0, key);

a1 = clamp(invert(div), 0, 1);
a2 = max(key[0], key[2]);
a = max(a1, a2);
a