04 · Denoise

Remove the grain

Film grain is real silver crystals; blown up to HD it crawls like noise. This is the heaviest lifter in the chain, and the reason 8mm can look so clean afterward.

Fixes: crawling grain Tool: MDegrain3 (motion-compensated) run_avs.py

The insight: grain is random from frame to frame, but the real image is not. A cheek looks almost identical across three frames; the grain speckling it is different each time. So if you average the same patch of cheek across several frames, the grain cancels and the true cheek remains.

The catch: the cheek moves. So before averaging, MDegrain3 does motion estimation, it searches for where each little block went in the neighbouring frames (up to ±3 away) and averages each block along its true motion path. Average at a fixed position instead and moving subjects ghost.

Left: one grainy frame as scanned (grain re-randomizes every frame). Right: the denoised output. Motion-compensated follows the moving head and cancels grain cleanly; naive averaging smears it. Push thSAD to max and even the good path starts softening detail.

The thSAD knob is the aggressiveness dial, how different two blocks can be and still count as "the same thing, just noisier." We run aggressive (thSAD 1000) because 8mm grain is coarse, and denoise chroma as hard as luma, because a later stage boosts saturation and any leftover colour grain would get amplified into ugly speckle.

Yossi's dials: strength: "aggressive" (thSAD 1000, with matched chroma denoise).