-
-
Notifications
You must be signed in to change notification settings - Fork 6
EEDI3
Edge-directed interpolation, more than twice as fast as eedi3m.
EEDI3 reconstructs a missing field by finding, for each interpolated pixel, the best non-crossing warping between the neighbouring lines: a dynamic program minimises a cost built from neighbourhood similarity (alpha), the vertical difference the interpolation creates (beta), the interpolation direction's length (the remaining 1-alpha-beta), and the change in direction from pixel to pixel (gamma).
This plugin exposes two functions sharing one numeric core:
-
EEDI3— interpolates rows (the classic vertical deinterlacer / doubler). -
EEDI3H— interpolates columns (the horizontal axis). It runs the identical kernel on a transposed copy, so it is bit-exact toTranspose → EEDI3 → Transpose.
vszip.EEDI3(vnode clip, int field[, bint dh=False, float alpha=0.2, float beta=0.25, float gamma=20.0, int nrad=2, int mdis=20, bint hp=False, int vcheck=2, float vthresh0=32.0, float vthresh1=64.0, float vthresh2=4.0, vnode sclip=None, vnode mclip=None])
vszip.EEDI3H(vnode clip, int field[, ... same arguments ...])Both functions take the same arguments. For EEDI3 the interpolated axis is the height; for EEDI3H it is the width (so the mod-2 / dh-doubling rules below apply to width instead of height).
- clip:
8-16 bit integer or 32-bit float. Any planar/gray color family (Gray, YUV, RGB) is supported. Half precision float (GRAYH) and 17+ bit integer are rejected. Integer output keeps the input format; cubic overshoot is clamped to[0, peak]on store. - field: Mode of operation and which field is kept.
-
0= same rate, keep bottom field -
1= same rate, keep top field -
2= double rate (alternates each frame), starts with bottom -
3= double rate (alternates each frame), starts with top
-
- dh: (Default: False)
Doubles the size of the input along the interpolated axis (height forEEDI3, width forEEDI3H): each input line is copied to every other output line and the gaps are interpolated.fieldmust be0or1whendh=True. - alpha / beta / gamma: Cost weights.
alphaandbetamust each be in[0, 1]andalpha + beta ≤ 1;gamma ≥ 0. Largeralphaconnects more lines/edges; largerbetaconnects fewer; the leftover weight favours shorter (more vertical) connections; largergammapenalises direction changes (smoother field). - nrad: (Default: 2)
Radius for the neighbourhood-similarity term. Range[0, 3]. - mdis: (Default: 20)
Maximum connection radius (search distance). Range[1, 40]. Larger connects shallower slopes but is slower and more artifact-prone. - hp: (Default: False)
Use half-pel search steps (higher angular resolution, slower). Implemented here, unlike eedi3m where it is a no-op. - vcheck: (Default: 2)
Reliability check on the interpolated result:0off,1weak,2medium,3strong. When> 0, inconsistent pixels are blended towardcint(a vertical-cubic value, or the matchingsclippixel if given). - vthresh0 / vthresh1 / vthresh2: (Default: 32.0 / 64.0 / 4.0)
Thresholds forvcheck. Must be> 0whenvcheck > 0. - sclip: (Default: None)
Optional "smooth clip" supplying thecintvalue for thevcheckblend. Must match the output format and dimensions. - mclip: (Default: None)
Optional Gray mask: only nonzero pixels get the full edge-directed search; zero pixels get plain cubic interpolation (mainly a speed knob). Must match the clip's width/height/length. A non-8-bit gray mask is converted internally (full-range).
out = core.vszip.EEDI3(src, field=1) # deinterlace, keep top field
out = core.vszip.EEDI3(src, field=1, dh=True) # double the height (anti-aliasing base)
out = core.vszip.EEDI3(src, field=0, nrad=3, mdis=40) # stronger (slower) search
out = core.vszip.EEDI3H(src, field=1, dh=True) # double the width
mask = src.std.Prewitt().std.Binarize(0.1)
out = core.vszip.EEDI3(src, field=1, mclip=mask) # edge-directed only on maskThe interior matches, but a thin band of border pixels differs because the two compute edge connections differently (see below).
-
eedi3m shrinks the search at the border. At pixel
xit clamps the offset toumax = min(x, width − 1 − x, mdis), so near the left/right edge only short, fully in-bounds connections are even considered. Neighbourhood terms whose taps would land outside the frame are dropped from that pixel's cost (s1/s2simply aren't added), and the DP backtrack applies a matching edge correction (pumax) so the chosen direction never points off-frame. -
vszip evaluates the full range over a mirror-padded line. Each line is copied into a buffer with
mdis-wide mirror-reflected margins on both sides, and the cost is computed for the entire[−mdis, +mdis]offset range at every pixel. Out-of-frame taps therefore read the mirror reflection instead of being skipped, and the per-pixelumax/pumaxcorrections are omitted. This keeps the SIMD inner loop uniform and branch-free (the main speed win) at the cost of slightly different — but still physically valid — connections within ~mdispixels of the edge.
So the results agree everywhere except a mdis-wide strip at the relevant borders (left/right for EEDI3, top/bottom for EEDI3H), where eedi3m forces short edge-clamped connections and vszip allows longer, mirror-fed ones. In practice the disagreement is sparse and concentrated in the first few pixels.
TODO: Test other ways to fill padded borders.
-
EEDI3His new. eedi3m has no horizontal variant; you would transpose aroundEEDI3. -
hpworks. eedi3m documentshpas having no effect; here it performs real half-pel search. -
mclipmust be Gray and the single mask is applied to every processed plane. eedi3m requires a same-format mask and uses it per-plane. (With subsampled chroma the gray mask is at luma resolution; use it with gray/4:4:4 clips or luma-only processing.) -
All planes are always processed. There is no
planesargument; eedi3m'splanes(which leaves unselected planes uninitialized) is dropped. -
Removed arguments (vs eedi3m):
-
ucubic— always uses cubic 4-point interpolation (i.e.ucubic=True). -
cost3— always uses the 3-neighbourhood cost (i.e.cost3=True). -
opt— CPU dispatch is automatic (portable Zig SIMD); there is no manual override.
-
TODO: improve mclip.