Yesterday, 15:37
Hi, Selur
I'm trying to remove a lot of scratches and white spots from a video, but I'm not having much success. If you have time, could you take a look at my script and suggest what could be improved?
Thanks in advance.
I have uploaded the full video, if it is large I can cut out the part with the most problems:
it's not the original video, I did some pre-processing with QTGMC from interlaced to progressive
I'm trying to remove a lot of scratches and white spots from a video, but I'm not having much success. If you have time, could you take a look at my script and suggest what could be improved?
Thanks in advance.
I have uploaded the full video, if it is large I can cut out the part with the most problems:
https://www.swisstransfer.com/d/1bf1ee60-fc08-4b10-8824-be68141f0180it's not the original video, I did some pre-processing with QTGMC from interlaced to progressive
Quote:import vapoursynth as vs
import ctypes
core = vs.core
# ---------------------------------------------------
# LOAD PLUGINS
# ---------------------------------------------------
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/Support/akarin.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/Support/DePan.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/Support/vszip.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/DenoiseFilter/ZSmooth/zsmooth.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/DenoiseFilter/CTMF/CTMF.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/DenoiseFilter/KNLMeansCL/vsnlm_cuda.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/DenoiseFilter/RemoveDirt/RemoveDirt.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/MiscFilter/MiscFilters/MiscFilters.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/FrameFilter/ReduceFlicker/ReduceFlicker.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/vsznedi3.dll")
core.std.LoadPlugin("E:/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
ctypes.windll.LoadLibrary(
"E:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll"
)
# ---------------------------------------------------
# IMPORTS
# ---------------------------------------------------
import dehalo
import removeDirt
import smdegrain
import stabilize
import SpotLess
# ---------------------------------------------------
# CLEANER SCRATCH MASK
# ---------------------------------------------------
def make_scratch_mask(clip):
y = core.std.ShufflePlanes(
clip,
0,
vs.GRAY
)
vert = core.std.Convolution(
y,
matrix=[
-4, 0, 4,
-12, 0, 12,
-4, 0, 4
]
)
vert = core.std.Expr(
vert,
"x abs"
)
# safer threshold
mask = core.std.Expr(
vert,
"x 9000 > 65535 0 ?"
)
# controlled expansion
for _ in range(8):
mask = core.std.Maximum(mask)
for _ in range(5):
mask = core.std.Inflate(mask)
# softer blur
mask = core.std.BoxBlur(
mask,
hradius=4,
vradius=1
)
return mask
# ---------------------------------------------------
# TEMPORAL SCRATCH REPAIR
# ---------------------------------------------------
def repair_scratches(clip):
y = core.std.ShufflePlanes(
clip,
0,
vs.GRAY
)
mask = make_scratch_mask(clip)
# previous / next frames
prev = y[0] + y[:-1]
next = y[1:] + y[-1]
# temporal median rebuild
repair = core.std.Expr(
[prev, y, next],
"x y z min max x z max min"
)
# light soften
repair = core.std.BoxBlur(
repair,
hradius=3,
vradius=1
)
fixed = core.std.MaskedMerge(
y,
repair,
mask
)
return core.std.ShufflePlanes(
[fixed, clip],
[0, 1, 2],
vs.YUV
)
# ---------------------------------------------------
# PROCESS
# ---------------------------------------------------
def process(clip):
# progressive
clip = core.std.SetFrameProps(
clip,
_FieldBased=vs.FIELD_PROGRESSIVE
)
# ---------------------------------------------------
# STABILIZE
# ---------------------------------------------------
clip = stabilize.Stab(
clip,
range=8,
mirror=1
)
# ---------------------------------------------------
# FLICKER
# ---------------------------------------------------
try:
clip = core.reduceflicker.Reducer(
clip,
aggressive=1
)
except:
pass
# ---------------------------------------------------
# LIGHT TEMPORAL CLEAN
# ---------------------------------------------------
clip = smdegrain.SMDegrain(
clip,
tr=2,
thSAD=180,
thSADC=120,
interlaced=False,
pel=2,
subpixel=2
)
# ---------------------------------------------------
# DIRT CLEAN
# ---------------------------------------------------
clip = SpotLess.SpotLess(
clip,
radT=3,
asearch=5,
thsad=600,
thsad2=400,
pel=2,
smoother="zsmooth"
)
clip = removeDirt.RemoveDirtMC(
clip,
limit=16,
gpu=False
)
# ---------------------------------------------------
# SCRATCH REPAIR
# ---------------------------------------------------
clip = repair_scratches(clip)
# ---------------------------------------------------
# MAIN DENOISE
# ---------------------------------------------------
clip = smdegrain.SMDegrain(
clip,
tr=2,
thSAD=220,
thSADC=140,
interlaced=False,
pel=2,
subpixel=2
)
# ---------------------------------------------------
# FFT3D
# ---------------------------------------------------
clip = core.neo_fft3d.FFT3D(
clip,
sigma=2.0,
sigma2=1.7,
sigma3=1.4,
sigma4=1.1,
sharpen=0.0,
planes=[0]
)
# ---------------------------------------------------
# 16 BIT
# ---------------------------------------------------
clip = core.resize.Bicubic(
clip,
format=vs.YUV420P16
)
# ---------------------------------------------------
# DEHALO
# ---------------------------------------------------
clip = dehalo.FineDehalo(
clip,
rx=2.4,
ry=2.4,
darkstr=0.0,
brightstr=1.3
)
# ---------------------------------------------------
# LIGHT NLMEANS
# ---------------------------------------------------
clip = core.nlm_cuda.NLMeans(
clip,
d=1,
a=2,
s=4,
h=0.65,
channels="Y"
)
# ---------------------------------------------------
# SAFE SHARPEN
# ---------------------------------------------------
sharp = core.std.Expr(
[clip, core.std.Maximum(clip)],
"x 0.88 * y 0.12 * +"
)
clip = core.std.Merge(
clip,
sharp,
weight=0.30
)
# ---------------------------------------------------
# LIGHT GRAIN
# ---------------------------------------------------
clip = core.grain.Add(
clip,
var=0.08,
uvar=0.03
)
# ---------------------------------------------------
# FINAL OUTPUT
# ---------------------------------------------------
clip = core.resize.Bicubic(
clip,
format=vs.YUV420P10,
dither_type="error_diffusion"
)
return clip
# ---------------------------------------------------
# ENTRY
# ---------------------------------------------------
clip = process(clip)
clip.set_output()

