About Keying and Spill Suppression |
This section talks about different strategies for pulling keys by combining nodes in different ways. If you don't know how to use Primatte and Keylight, Shake's primary bundled keyers, you should probably read those tutorials first.
We can loosely define keying as creating a new alpha channel based upon the pixel color (a pure blue pixel, for example), luminance (a very dark pixel) or Z-depth (a pixel 300 Z units away, for example) in an image. I will be discussing keying as a separate process from masking, which we can loosely define as creating an alpha channel by hand through the use of painting, rotosplines, or imported alpha masks from either 2D or 3D renders in other packages. I discuss those techniques in About Masking.
Pulling a Blue-
or Greenscreen
There are three nodes included in the software for pulling blue or greenscreen keys. They are Primatte, Keylight and ColorReplace. There are entire tutorials devoted to Primatte and Keylight, so I won't go into them too much. We also have a ChromaKey node in the Key tab, but for some reason I can't fathom, it completely sucks. No kidding. The same model and parameters appear in ColorReplace, but ColorReplace works much better. Go figure.
You should also investigate Ultimatte, a third-party keyer with a long and Oscar-winning history of production use. Contact Ultimatte for more information.
Keying in Primatte - see Primatte Tutorial
Keying in Keylight - see Keylight Tutorial
Keying with ColorReplace - There are two images in doc/pix/primatte labeled alex_fg.jpg and clouds1.jpg. Attach them in a tree like this one.
![]() |
![]() |
Special parameter settings:
We use the Invert because ColorReplace puts white in the Source Color area of the alpha channel. We have to invert it for the Over node. With the initial settings, you are probably getting blue fringes - drag the satFalloff setting up to perhaps 1. Also, if pure black or pure white pixels start to show transparent (check the flowers), drag your valRange and valFalloff numbers down to perhaps .2 and .5.
You can see there is some crunchiness, particularly in the hair to the right of her mouth. This is why ColorReplace is usually used to pull a key to mask off other operations like color correctors rather than the actual composite. We will have examples of using this later on.
Combining Keyers
You will get the most flexibility when you combine keyers. Both Primatte and Keylight allow you to input a holdout matte. There are at least three typical ways of combining keys:
You can combine keys by using the holdout matte input. Typically, you pull a basic key for soft edges and reflections. You also pull a second key which is very hard, and then soften it up afterwards with filters. Taking the Keylight sample images in doc/pix/keylight, here is an example. The first image shows us the initial key coming out of Keylight- we like the reflections, but we want to get rid of the transparency near the seatbelt and steering wheel.
Next, we also pull a key with Primatte on the same bluescreen. Using just foreground and background operators, we remove the reflection and fill in the transparent areas. This results in a very hard matte:
We next attach filters to the Primatte - I add a DilateErode, setting my xPixels to 1 - this will close up any holes. You can also use a Median filter to do the same thing. I then apply a second DilateErode, setting the xPixels to -5. The will eat away at the matte. This filtering process will clean up the matte, making it more solid. I add a Blur to soften it, and then feed it into the third input of Keylight. The result is a solid matte with soft edges:
The next way to combine keys is specifically for Primatte using its arithmetic parameter. Normally when you pull a key in Primatte, it replaces whatever alpha mask is in the foreground image. By switching the arithmetic parameter from replace to add, multiply or subtract, you can combine the mattes within Primatte. In this tree, I have pulled an initial key with ColorReplace, inverted it, and then I can switch arithmetic in the Primatte node to add to combine them:
The last way to combine keys is of course using Layer nodes. In this tree, I pull a key with two different nodes and then combine them with the Max operator, which takes whatever pixel value is greatest. I combine all of the elements later with a KeyMix. Note that the KeyMix won't actually get an alpha channel since neither clouds or blonde have one. KeyMix only mixes between the two through the mask we have pulled:
Here is the same tree using an Over node instead. This will generate an alpha channel coming out of this tree:
Applying Effects
to Bluescreen Footage
Here is a problem with applying effects to bluescreen footage. Suppose you want to blur your foreground but not the background. Your natural instinct is to put a Blur node and then key and comp with Keylight. This example shows you that this is what we call A Real Bad Idea. Notice we have introduced a nice blue edge along her neck line and haloing on the flowers:
![]() |
![]() |
So, being bright kids, we think maybe we can put the Blur after the Keylight. Also A Real Bad Idea - it blurs the background as well:
![]() |
![]() |
Being particularly bright kids, we think perhaps we can mask off the blur with the key we just pulled from Keylight: Hmm. Maybe we aren't so bright and we rightfully deserve to be chained to our desks and our mouse SuperGlued to our hands:
![]() |
![]() |
The problem with all of these is that we are asking the keying node, in this case Keylight, to do too much - it has the simultaneous task of keying, suppressing spill and compositing. The solution of course is to use other nodes for the compositing. In this example, Keylight's output parameter can be set to either comp or on Black:
![]() |
![]() |
As a general principle, then, you should use Primatte's and Keylight's background inputs as test comps, to be later rewired into a composite with Over or KeyMix. This gives you several advantages:
Blue and Green
Spill Suppression
Once we have pulled the composite out of the Keyers and back into the KeyMix or Over nodes, we can start to work with spill suppression. Blue spill is when light is reflected off of the bluescreen and onto the foreground material. For our examples, we will be using doc/pix/primatte/woman.iff and bg.jpg, since there is quite a bit of bluespill on her shirt. In this tree, I have left Primatte's output to alpha only, created a holdout matte for the line under her arm with QuickPaint, and put in foreground and background operators. I then comp with the Over node, which has preMultiply turned on. You can plainly see the blue spill that remains:
![]() |
![]() |
You might think that it would look better if you switch Primatte's output to comp and turn off the preMultiply in Over: You'd be wrong and ridiculed and, in some countries, forced into hard labor for 16 years with crazy people, political dissidents, and tv programmers.: It turns your blue edges into black edges, making them even harder to get rid of (although we will look at techniques to help correct this in a bit...). Plus, we still have the bluespill...
So, supposing you don't want to do bluespill correction in your composites, here are several sample trees to help you out:
Color Replace I:
This technique is nice because it is fast, but often simply replaces blue spill with a different color. In this tree, I apply a ColorReplace to the foreground, replacing the blue with the color of the wall. As always, I increase the satFalloff to around 1. The head looks great, but the spill is still there on the shirt and there is now a horrible yellow edge around the skirt:
![]() |
![]() |
To fix this, I drop the valRange to 0 and the valFalloff to around .4. I add a second ColorReplace to get rid of the bluespill on her shirt - I carefully select the blue on the shirt, and then replace it with a beige-white color. I also move all Range parameters to 0 and all Falloff parameters to around .3. The shirt looks fine, but you can see even in this snapshot that there is still a yellow ring around her skirt:
![]() |
![]() |
Color Replace II:
A second, better, technique is to use ColorReplace to mask a color correction. Replace ColorReplace2 with a Monochrome node and pipe Primatte directly into it. Then take the output of ColorReplace1 in as Monochrome1's mask, and turn on the affectAlpha parameter in ColorReplace. This process turns off all saturation in the blue areas, turning it grey. This is cool because the eye can detect luminance levels better than saturation: Notice how both the skirt and the shirt look good:
![]() |
![]() |
Alternatives to Monochrome are AdjustHSV or Saturation.
SpillSuppress:
This next technique mathematically evaluates each pixel, comparing the blue and green strength. If the blue is significantly stronger than the green, it suppresses it. The SpillSuppress node is under the Key tab. This tends to work better on bluespill than on greenspill because of the luminance difference between the two. It also tends to push your images to a yellow color.
![]() |
![]() |
HueCurves
The next helpful node is HueCurves. This node is nice because you can do any color correction you want based on the hue of the pixel you want to affect. HueCurves works by loading a parameter into the Curve Editor and tuning it. The X axis is the hue, and the Y axis depends on what parameter you are using. For example, load the saturation curve into the Curve Editor and grab the knot around .66, since blue has a hue of 66 percent. Drag it down, and you are decreasing the saturation for the blue pixels:
![]() |
![]() |
Edge Treatment
Another typical problem with keying (OK, well, it is the problem with keying) is edge treatment. In doc/pix/primatte, you will find two images, pillar1.jpg and clouds1.jpg. These images remind me to bring up an important tip for compositors:
|
Anyway, slap them together with a Keylight node, scrubbing the sky near the horizon. The black nasty line is what I am concerned with here:
![]() |
![]() |
As we blabbed on and on about before, it is better to composite after pulling your key because it gives you more flexibility, so rewire the tree with an Over node. Make sure you turn on preMultiply in the Over node and set Keylight's output to unPremult.
Now insert a DilateErode to Keylight, and set it's channel to just affect the alpha by entering an a instead of rgba. Now set xPixels to -1, and it should chew into the matte. The third image is what happens if you don't turn on preMultiply in the Over node because you have upset the mask - RGB premultiplied relationship. You can clearly see the white lines around the edges:
![]() |
![]() |
![]() |
The dilation only happens in 1 pixel intervals. If you want a soft edge, turn on soften, which will make a ramp from the original edge out to your x/yPixels distance. soften will also be significantly slower at large values, i.e., numbers greater than, say, 20.
One little problem. Compare the electrical power lines in the original image with the dilated result - they have disappeared. This is because the details are so fine, the DilateErode chewed them away:
![]() |
![]() |
Therefore, go to the Mask input of DilateErode and select QuickPaint from the associated pulldown menu. This will attach a mask to the DilateErode. Paint across the electrical wires. This will only dilate where the wires are, which is exactly opposite of what we want, so open the Mask parameters in the DilateErode and turn on invertMask:
Now, your edges are dilated except around the wires area.
Keying DV footage
First of all, what the hell is wrong with you, trying to key off of DV? Now with that obligatory yelling out of the way, let's see what we can do to salvage the situation.
Here, you have shot your no doubt perfect bluescreen with your shiny brand new DV camera. There is a small portion of an image found in doc/pix/primatte called dv.iff if you want to sing along. Try and key it and place it over a background (here, just a red field), and you are no doubt horrified to find blocky chunks all over your image:
DV bluescreen | Key pulled on DV bluescreen |
![]() |
![]() |
What the hell is up with this? Whereas RGB represents each pixel with a value for each of Red, Green and Blue, YUV (or YCrCb) color space, which is how video sees the world, represents each pixel with a luminance value (Y) and two chrominance values: red/green difference (Cr) and blue/green difference (Cb). This is done, I think, because green has a higher luminance value and is therefore more likely to display artifacts if too much information is taken away. Who knows, this stuff was figured out before W.W.II. Anyway, in the video world, a signal describes as 4:4:4 means for every four pixels, you get four pixels each for Y, Cr, Cb. This is equivalent to 8-bit RGB. 4:2:2 means that you get a four Y pixels and two each of Cr/Cb for every four pixels. You get less information in a smaller package, giving you a little more speed and a usually acceptable loss of detail. 4:1:1, which is what DV is using, means you get 4 Y (luminance) pixels and a single each of Cr/Cb (red/green and blue/green difference) for every 4 pixels, meaning luminance can change every pixel, but color changes only every 4 pixels. For example, if you look at the now-keyed footage, you will see that each of those blocks is 4 pixels wide. Wow, that saves a lot of data! But, oops, bluescreen keyers pull keys from color, not luminance, thus, we get the chunkiness.
Since the information in video is transferred from the YUV signal to the digital RGB, let's take a look at what the original YUV channels look like. You can do this by attaching a Color - ColorSpace to the FileIn and declaring the outSpace to be yuv. Hit the R/G/B on the Viewer to look at the new YUV channels.
Y (luminance) | U (Cr, or red/green difference) | V (Cb, or blue/green difference) |
![]() |
![]() |
![]() |
Looking at the luminance channel, it is getting the full amount of information that we need, since the human eye is susceptible to differences in luminance than hue.
So, how do we fix our key? You'll like this next trick. Attach a Blur to the ColorSpace node, and in the channels parameter, blur only the U and V channels by switching the channels from rgba to gb. Blur it a little bit, maybe 8 pixels. Now attach a second ColorSpace operator and declare your inSpace to be yuv. This will convert it back to RGB space.
Tree |
![]() |
Now check your key out. It's mathemagical!
Without blur on UV: | With blur on UV: |
![]() |
![]() |
A couple of other ways to enhance your keying is to actually capture the blue/greenscreen DV footage through an analog capture board, or a board that can convert back up to 4:2:2. This significantly enhances the quality of the image and reduces the blockiness one typically sees with 4:1:1 footage.
Another problem is when these come through an .avi file, which has some sort of odd bug that we suspect is OS-related, that doesn't fully decode the data fully. A work-around is to decode it with some other method, although we've had similar problems with other decoding methods on NT as well.
When using straight YUV files (i.e. Tremor-captured footage), you can bypass the RGB -> YUV conversion by turning off yuvDecode in the FileIn. Do the Blur, and then use just one ColorSpace to convert it to RGB space.
Finally, although I haven't tested this, I suspect you will have better results with greenscreen than bluescreen because of the higher luminance value. Feel free to confirm or refute this and let me know.
For three appropriate links (among thousands), jump to
http://www.philipwilliams.com/greenscreen.asp
http://www.philipwilliams.com/dvcompression.asp
http://www.neopics.com/bluescreen/