AgentSkillsCN

deflicker

修复视频素材中的 LED 频闪问题。可有效消除因 overhead 面板闪烁而引起的滚动快门相机频闪现象,无论是整帧频闪(LED 光线在墙面或天花板上反射产生的频闪),还是局部频闪(小灯泡发出的点状频闪),均能妥善应对。当用户反馈在 LED 照明下的室内视频出现闪烁、脉动或频闪时,可使用此技能进行处理。

SKILL.md
--- frontmatter
name: deflicker
description: Fix LED flicker in video footage. Removes LED PWM flicker from overhead panels beating against rolling shutter cameras. Handles both whole-frame flicker (reflected LED light on walls/ceiling) and spot flicker (small filament bulbs). Use when user reports flickering, pulsing, or strobing in indoor video shot under LED lights.
argument-hint: [input-video] [output-video]
allowed-tools: Read, Bash(python3 *), Bash(ffmpeg *), Bash(ffprobe *), Write, Glob, Grep

Deflicker Runner

Fix LED flicker in video footage caused by LED PWM drivers beating against rolling shutter cameras.

Quick Start

bash
# Auto-detect flicker type and fix
python3 deflicker.py auto input.MP4 output.MP4 --duration=5

# Whole-frame LED flicker (best approach)
python3 deflicker.py temporal-median input.MP4 output.MP4 --radius=2

# Small flickering bulbs / fairy lights
python3 deflicker.py spot-replace input.MP4 output.MP4 --start=128 --duration=5

# Diagnose flicker type before fixing
python3 diagnose.py input.MP4

# Run tests
python3 test_deflicker.py verify

Two Video Types

Whole-frame flicker

LED panels reflect off walls, ceiling, floors. The entire frame pulses because the reflected light covers large surfaces. Dark surfaces show it most — bright LED panels are saturated and don't flicker visibly.

Detection: Row brightness at 540p varies 1-3% frame-to-frame with 3-frame repeating pattern.

Spot flicker

Small flickering light sources — exposed filament bulbs, fairy lights, candles. Only a few pixels flicker while the rest of the frame is stable. Standard 540p approaches miss these (2-5 pixels at 4K = sub-pixel at 540p).

Detection: Bright pixels (>150) with high temporal std (>40) in small clusters.

Approaches

ApproachTypeBest ForPerformance
autoautoDefault — detects and selectsQuick scan
temporal-median2DWhole-frame LED flicker (recommended)~15 fps compute, ~20 fps apply
running-mean1DGeneral-purpose deflickerFast compute
spot-replacespotSmall filament bulbs, fairy lights~8 fps apply
pixel-smooth2DScene changes, motion-preserving~2 fps compute
bcc1DScene changes (per-row)Medium
fft-notch1DPrecise LED beat removal only (~2%)Fast
physical-model1DKnown LED frequency, physics-basedSlow (fitting)
global-row1DGlobal frame brightness variationFast
hybrid1DExperimental (not recommended)Medium

Type key

  • 1D: Per-row corrections at 540p, interpolated to full resolution
  • 2D: Per-pixel corrections at 540p, bilinearly upscaled to full resolution (uses cv2.resize, 96x faster than scipy)
  • spot: Full-resolution detection + per-box correction (works at native 4K)

Common Parameters

code
--qp=10              Output quality (lower = better, 10 = near-lossless)
--start=30           Start time in seconds
--duration=5         Process N seconds
--dark-floor=25      Suppress corrections below this brightness
--radius=2           Temporal radius (temporal-median, spot-replace)
--window=300         Temporal window for running-mean
--bright-threshold=150  Spot detection: min pixel brightness
--std-threshold=40      Spot detection: min temporal std

Performance Notes

  • Uses CUDA-accelerated ffmpeg decode + NVENC encode
  • cv2.resize for 2D correction upscale: 96x faster than scipy.ndimage.zoom
  • QP=10 needed to preserve subtle 2% corrections
  • Per-box delta storage: ~50MB vs 3.2GB full-frame for spot-replace

Results

C1608 (whole-frame, temporal-median r=2)

  • Ceiling: 57% std reduction, 85% 3-frame oscillation removal
  • Wall: 66% std reduction, 76% 3-frame oscillation removal

C1595 (spot flicker, spot-replace r=2)

  • Both filament bulbs detected and corrected at 4K resolution
  • Fixed detection: bright>150, std>40 (was broken with adaptive threshold)

Integration with color-grade-ai

Deflicker BEFORE applying color correction LUTs:

code
raw clip → deflicker.py → color-corrected clip (in Premiere/Resolve)

Physics

  • Australian mains: 50Hz → LED PWM at 100Hz
  • Camera: 59.94fps rolling shutter (Sony A7IV)
  • Beat: 100Hz mod 59.94fps = 19.88Hz aliased (3-frame cycle)
  • Amplitude: ~2% on ceiling, ~1.8% on walls (subtle but perceptible at 20Hz)