Home · Lab · Paint & Cleanup

PC4 Clean plate with a median

Combine many frames so only the background stays and what moves drops out

Paint & Cleanup · ~8 min · Free

1 The idea

In a locked-off plate the robot walks past, so the background shows in other frames. A per-pixel median over time picks the middle value of all frames: it keeps what stays and drops what only passes through for a few frames.

Switch “Combine frames with” between mean and median, raise “Frames used”, then pick frames “Spread over the shot”. The strip shows what share of the chosen frames cover each column (red = half or more). Read “Robot and shadow left” and “Grain left”.

clean(x, y) = median over t of plate(x, y, t)

2 Hands-on

Build a clean plate with under 8% of one robot (and its shadow) left

Look at the red parts of the strip: the most-covered pixel decides it, not the average over the frame.

SkyVFX Lab · PC4interactive · 1001

3 Deep dive

How a median differs from a mean

Take one pixel on the sand and collect its value from every chosen frame. Most are sand; in a few the robot or its shadow passes over it. The median sorts the values and takes the middle one. The robot’s values sit at one end of the list, so the middle is sand.

The mean adds every value and divides. A robot that covers a pixel in 1 of N frames still leaves 1/N of its difference: a see-through ghost. A mean of all 24 frames in the figure still leaves about 106% of one robot, spread thin along its path.

  1. 1Collect the pixel from every frame
  2. 2Sort the values
  3. 3Take the middle one
  4. 4Repeat for every pixel

The half rule: spread the frames

A median drops only what is present in fewer than half the frames used. In back-to-back frames the robot moves only a little, so the same pixels are covered in nearly all of them. Pick frames spread across the shot and each pixel is covered in only a few.

Don’t forget the shadow: it moves too. Here the robot walks diagonally, so its long shadow sweeps sideways: with all 24 frames spread, the body covers any pixel in at most about 33% of them and the shadow in at most about 38%. Walk along the shadow instead and some sand stays shaded for more than half the shot, and the median keeps it.

Judge the worst pixel: if it passes the half rule, the whole frame does.

If you average, cut a hole first

An average works too if you cut the moving thing out first: roto the robot as a hole in the alpha and premultiply so the rgb goes black there, average rgb and alpha, then unpremult so the averaged alpha divides out the dark where the robot was.

  1. 1Roto a hole over the robot
  2. 2Premult
  3. 3TimeEcho (average)
  4. 4Unpremult

The grain goes too

Grain is different in every frame, so combining many frames removes it along with the robot. The clean plate comes out smoother than the real plate and needs grain added back.

CombineGrain left (std vs one frame)
Mean of N frames1/√N
Median of N framesAbout √(π / 2N) for large N
Mean of 24 in the figureAbout 20%
Median of 24 in the figureAbout 25%

Camera moves and limits

A median needs a locked-off or stabilised plate. With a moving camera, stabilise first (2D, or 3D by projecting through the tracked camera), combine, then put the move back.

Every background pixel must be uncovered at some point in the shot, or no combination of frames can show it. Anything that stops for more than half the shot stays in the median, and if the light changes during the shot the median mixes the different lighting.

  1. 1Stabilise
  2. 2Combine frames
  3. 3Put the move back

4 In real work

In Nuke

  1. Tracker: if the camera moves, stabilise the plate first and put the move back after combining.
  2. FrameHold or TimeOffset: pull frames spread over the whole shot, not back to back.
  3. Median: feed the spread frames into a per-pixel median (a gizmo or script; it depends on your setup).
  4. Average route: Roto a hole over the robot → Premult → TimeEcho (set to average) → Unpremult.
  5. Grain2 on the clean plate, with the seed animated per frame, since the default leaves the grain frozen.

Common mistakes → the fix

  • ✗ Taking frames back to back, so the robot covers the same pixels in most of them✓ Spread the frames over the shot until every pixel is covered in fewer than half.
  • ✗ Using a plain mean, so everything that moved leaves a see-through ghost✓ Use a median, or roto a hole and premult before averaging, then unpremult.
  • ✗ Something that stops for half the shot stays in the clean plate✓ Paint that part by hand.
  • ✗ Light changes during the shot (clouds, flicker) and the median mixes them✓ Deflicker before combining.
  • ✗ Forgetting to regrain, leaving a clean but too-smooth plate✓ Add grain back to match the plate, changing every frame.

Before you send the shot

  • The plate is locked off or stabilised before combining.
  • No see-through ghost of the robot or its shadow with the viewer pushed.
  • Nothing that stopped is left behind, or it has been painted out.
  • The clean plate’s light matches the plate, with no mixed flicker.
  • Regrained: grain is close to the plate and not frozen when played.

5 Check yourself

One question to check yourself

A median of 3 consecutive frames still shows the robot clearly. Why?

What you learned

🔒 Answer the question above and this card opens

More questions

1. A clean plate from a median of 24 frames has no robot left but looks smoother than the real plate. What do you do?

2. The camera moves through the whole shot. How do you build a median clean plate?

Where the numbers come from: The 24 frames are our own Blender renders (our robot walk rig, walking diagonally past a locked-off camera, every 5th frame of about 4 s of walk), shipped as crops of what differs from the clean plate. Mean and median are computed per pixel in your browser on display values, as a teaching version; the grain is our own, seeded per frame, and the limit is ours (render noise between frames alone uses up more than half of it).