Denoising is the process of removing unwanted noise or grain from video sources, improving clarity and compression efficiency. It’s especially crucial for older or low-quality sources, as excessive noise can lead to larger file sizes and visible artifacts during playback.
This guide explores the intricacies of temporal and spatial denoising, provides detailed examples, and offers insights into combining techniques for optimal results.
Noise reduction enhances the perceived clarity of videos, especially in dark or complex scenes.
Noise takes up unnecessary bits during encoding. Denoising helps focus bits on important details, reducing file size.
Many advanced filters (e.g., sharpening or upscaling) perform better when noise is reduced.
Common in older video sources or low-light recordings, appearing as fine grain or static.
Blocky patterns or banding caused by poor compression techniques.
Fluctuating noise that changes from frame to frame, common in analog sources.
Temporal denoising analyzes multiple frames to detect and reduce noise over time. This approach preserves motion and details while minimizing artifacts.
- Excellent for reducing flickering or moving noise.
- Preserves static backgrounds and consistent patterns.
BM3D is a state-of-the-art algorithm that reduces noise by grouping similar blocks across frames.
- Example:
import vapoursynth as vs core = vs.core clip = core.bm3d.Basic(clip, sigma=3) # Adjust sigma for noise strength
MCTemporalDenoise uses motion compensation to smooth noise while retaining motion fidelity.
- Example:
clip = core.mctemporal.MCTemporalDenoise(clip, sigma=2)
A powerful denoiser based on motion vectors, suitable for both mild and aggressive denoising.
- Example:
clip = core.smd.SMD(clip, tr=3, thSAD=300) # Adjust thSAD for noise threshold
Spatial denoising works within each frame, reducing grain and artifacts on a per-pixel basis.
- Excellent for removing static noise or grain.
- Useful for still scenes or areas with little motion.
A fast, GPU-accelerated denoiser ideal for medium-strength noise reduction.
- Example:
clip = core.knlm.KNLMeansCL(clip, d=2, a=2, h=1.2)
Performs frequency-domain filtering to reduce noise without blurring details.
- Example:
clip = core.dfttest.DFTTest(clip, sigma=16)
A simple but effective denoiser for light to moderate noise.
- Example:
clip = core.hqdn3d.HQDenoise3D(clip, luma_spatial=4.0, luma_temporal=6.0)
For the best results, combine both temporal and spatial denoising. This approach reduces noise across frames while ensuring that individual frames remain clean and detailed.
# Temporal denoising with SMDegrain
clip = core.smd.SMD(clip, tr=3, thSAD=300)
# Spatial denoising with KNLMeansCL
clip = core.knlm.KNLMeansCL(clip, d=2, a=2, h=1.2)
- Start with temporal denoising to reduce inter-frame noise.
- Apply spatial denoising to clean up remaining artifacts.
- Test on a Sample Clip: Use a short segment to preview the effects before applying filters to the entire video.
- Avoid Over-Denoising: Over-aggressive denoising can create unnatural smoothness and remove desired details like film grain.
- Adjust Parameters: Fine-tune sigma, strength, and thresholds based on the source material.
- Preserve Artistic Intent: For film sources, retain some grain to maintain the original look.
-
Use Zoning: Apply stronger denoising to noisy scenes and lighter denoising to clean areas.
clip = core.knlm.KNLMeansCL(clip, d=2, a=2, h=1.5) clip = core.std.FrameEval(clip, lambda n, f: strong_clip if n in noisy_frames else clip)
-
Pre-Process the Source: For severely degraded sources, combine denoising with artifact reduction (e.g., deblocking or debanding).
-
Temporal Radius: Increase the temporal radius (e.g.,
tr
in SMDegrain) for smoother results on static scenes. -
Analyze the Output: Use tools like VapourSynth's
Preview
or test encodes to verify the effectiveness of your settings.
Here’s a complete script combining temporal and spatial denoising for a noisy source:
import vapoursynth as vs
core = vs.core
# Load source
clip = core.ffms2.Source("noisy_source.mkv")
# Temporal denoising
clip = core.smd.SMD(clip, tr=3, thSAD=400)
# Spatial denoising
clip = core.knlm.KNLMeansCL(clip, d=2, a=2, h=1.2)
# Output
clip.set_output()
Denoising is both an art and a science. By understanding and applying the techniques outlined in this guide, you can achieve clean, visually appealing videos while preserving essential details. Experiment with different methods and settings to tailor the results to your specific needs.