This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

A cookie will be stored in your browser regardless of choice to prevent you being asked this question again. You will be able to change your cookie settings at any time using the link in the footer.

[HELP] Trying To Clean Up DVD Video
#1
Hi,

I have an older TV show DVD's that I am hoping to clean up the video on as much as possible. I am not really looking to upscale but just trying to improve anywhere possible.

Here's a sample file on Google Drive for one of the episodes that I remuxed to MKV. Other than that, the file is untouched from the original DVD. I realize the source is pretty bad and not expecting any miracles on this.

It would be awesome to get some recommendations on what filters in Avisynth/Vapoursynth and the levels for any filters to try. Mainly looking for a decent base set of filters/levels to start with and play around with for results afterwards. I have quite a few of retail DVD's from 1980's U.S. TV shows and they all seem to suffer from the same poor video quality.

I greatly appreciate any help and feedback!  Big Grin
Reply
#2
To start I would
  • enable "Config->Internals->Prefer Original->Frame rate" (before loading the source)
  • enable "Filtering->(De-)Interlace/Telecine->QTGMC Vapoursynth->Bob"
  • enable "Filtering->Vapoursynth->Frame->Reduction->sRestore" and enable 'Frate' and set it to 23.976
  • enable "Crop/Resize->Base->Picture Crop" and set left to 8 and right to 12
then I would look through the source to see whats it about.
Here just looking through the source, some scenes are really noise while others are partially cleaned up.
So fo a final product one might want to thing about scene based filtering.
(I would at least filter the intro, and may be the dark scenes, way stronger than the rest,

Then I would probably check what BasicVSR++ or DPIRDenoise would do to the clip. (both require a recent NVIDIA CPU and the torchAddon, DPIRDenoise is probably better suited)

Leaving the ML stuff aside I would choose a DeGrain filter, SMDeGrain and TemporalDegrain are probably good starting points and tweak the settings to my liking.
Then I would probably add Declock_QED which usually is a good idea on DVD content, add SpotLess with a temporal radius of 2.

So something like:
# Imports
import vapoursynth as vs
import os
import ctypes
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("i:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
import sys
# getting Vapoursynth core
core = vs.core
# Import scripts folder
scriptPath = 'i:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SharpenFilter/CAS/CAS.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/CTMF/CTMF.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/DCTFilter.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DeblockFilter/Deblock/Deblock.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/libtemporalmedian.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/GrainFilter/RemoveGrain/RemoveGrainVS.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/DFTTest/DFTTest.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/EEDI3m.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/NNEDI3CL.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/temporalsoften.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/scenechange.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/MiscFilter/MiscFilters/MiscFilters.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/DGDecNV/DGDecodeNV.dll")
# Import scripts
import nnedi3_resample
import mvsfunc
import smdegrain
import SpotLess
import adjust
import havsfunc
# source: 'C:\Users\Selur\Desktop\title_t00.mkv'
# current color space: YUV420P8, bit depth: 8, resolution: 720x480, fps: 29.97, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading C:\Users\Selur\Desktop\title_t00.mkv using DGSource
clip = core.dgdecodenv.DGSource("E:/Temp/mkv_58c8c6132152712942132531ae1f0232_853323747.dgi",fieldop=0)
# Setting color matrix to 470bg.
clip = core.std.SetFrameProps(clip, _Matrix=5)
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=5)
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=5)
# Setting color range to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# making sure frame rate is set to 29.970
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# setting field order to what QTGMC should assume (top field first)
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=2)
# Deinterlacing using QTGMC
clip = havsfunc.QTGMC(Input=clip, Preset="Fast", TFF=True, opencl=True) # new fps: 59.94
# make sure content is preceived as frame based
clip = core.std.SetFieldBased(clip, 0)
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip, frate=23.9760, omode=6, speed=9, thresh=16, mode=2)
# Color Adjustment
clip = adjust.Tweak(clip=clip, hue=0.00, sat=1.05, cont=1.00, coring=True)
clip = SpotLess.SpotLess(clip=clip, radT=2)
# applying deblocking using DeBlock QED
clip = havsfunc.Deblock_QED(clip)
# cropping the video to 700x480
clip = core.std.CropRel(clip=clip, left=8, right=12, top=0, bottom=0)
# removing grain using SMDegrain
clip = smdegrain.SMDegrain(input=clip, interlaced=False, opencl=True, device=-1)
# contrast sharpening using CAS
clip = core.cas.CAS(clip=clip, sharpness=0.700)
# set output frame rate to 23.976fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()/code]
Would be my starting point for tweaking.

Personally I would also boost the saturation a slight bit (1.05-1.1).
I would not apply AutoWhite since for my taste it would alter the general feel too much.
Also I would think about adding some light grain at the end, depending on the output bit rate I choose. (if you use high bit rates, grain can help give the image a slightly more 'alive' 'feeling', but for low bit rates it will only cause problems since it's a pain to compress.

Also if you want to upscale the content to 1280 you could:
Use something like:
[code]# Imports
import vapoursynth as vs
import os
import ctypes
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("i:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
import sys
# getting Vapoursynth core
core = vs.core
# Import scripts folder
scriptPath = 'i:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
import site
# Import libraries for onnxruntime
path = site.getsitepackages()[0]+'/onnxruntime_dlls/'
ctypes.windll.kernel32.SetDllDirectoryW(path)
# Loading Plugins
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/DCTFilter.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DeblockFilter/Deblock/Deblock.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/GrainFilter/RemoveGrain/RemoveGrainVS.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/DenoiseFilter/DFTTest/DFTTest.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/EEDI3m.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/NNEDI3CL.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/temporalsoften.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/scenechange.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/MiscFilter/MiscFilters/MiscFilters.dll")
core.std.LoadPlugin(path="i:/Hybrid/64bit/vsfilters/SourceFilter/DGDecNV/DGDecodeNV.dll")
# Import scripts
import lostfunc
import adjust
import havsfunc
# source: 'C:\Users\Selur\Desktop\title_t00.mkv'
# current color space: YUV420P8, bit depth: 8, resolution: 720x480, fps: 29.97, color matrix: 470bg, yuv luminance scale: limited, scanorder: top field first
# Loading C:\Users\Selur\Desktop\title_t00.mkv using DGSource
clip = core.dgdecodenv.DGSource("E:/Temp/mkv_58c8c6132152712942132531ae1f0232_853323747.dgi",fieldop=0)
# Setting color matrix to 470bg.
clip = core.std.SetFrameProps(clip, _Matrix=5)
clip = clip if not core.text.FrameProps(clip,'_Transfer') else core.std.SetFrameProps(clip, _Transfer=5)
clip = clip if not core.text.FrameProps(clip,'_Primaries') else core.std.SetFrameProps(clip, _Primaries=5)
# Setting color range to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# making sure frame rate is set to 29.970
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# setting field order to what QTGMC should assume (top field first)
clip = core.std.SetFrameProp(clip=clip, prop="_FieldBased", intval=2)
# Deinterlacing using QTGMC
clip = havsfunc.QTGMC(Input=clip, Preset="Fast", TFF=True, opencl=True) # new fps: 59.94
# make sure content is preceived as frame based
clip = core.std.SetFieldBased(clip, 0)
# adjusting frame count and rate with sRestore
clip = havsfunc.srestore(source=clip, frate=23.9760, omode=6, speed=9, thresh=16, mode=2)
# Color Adjustment
clip = adjust.Tweak(clip=clip, hue=0.00, sat=1.05, cont=1.00, coring=True)
clip = lostfunc.DeSpot(o=clip)
# applying deblocking using DeBlock QED
clip = havsfunc.Deblock_QED(clip)
# cropping the video to 700x480
clip = core.std.CropRel(clip=clip, left=8, right=12, top=0, bottom=0)
from vsrealesrgan import RealESRGAN
# adjusting color space from YUV420P8 to RGBS for VsRealESRGAN
clip = core.resize.Bicubic(clip=clip, format=vs.RGBS, matrix_in_s="470bg", range_s="limited")
# resizing using RealESRGAN
clip = RealESRGAN(clip=clip, model=0, provider=1, device_id=0) # 1400x960, do not use the anime model on normal content.
# resizing 1400x960 to 934x720
# adjusting resizing
clip = core.fmtc.resample(clip=clip, w=934, h=720, kernel="lanczos", interlaced=False, interlacedd=False)
# letterboxing 934x720 to 1280x720
clip = core.std.AddBorders(clip=clip, left=174, right=172, top=0, bottom=0)
# adjusting output color from: RGBS to YUV420P8 for x264Model
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P8, matrix_s="470bg", range_s="limited", dither_type="error_diffusion")
# set output frame rate to 23.976fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=24000, fpsden=1001)
# Output
clip.set_output()
Note that I did no do any degrain since RealESRGAN usually does a good job on such sources, I also swapped SpotLess for DeSpot.
(SwinIR might also be worth a try, but is even slower than RealESRGAN)

-> Hope this helps a bit.
The main thing is to find a good balance between denoising/degrain which causes smoothing while keeping details.

Cu Selur
Reply
#3
Thanks for the abundance of info and details! This is definitely a great place to start. I may do like you recommended and isolate some scenes that are worse than others versus same settings for the entire episode.

My main desktop does have a RTX 3080 card, so I can definitely leverage the GPU processing stuff you recommended.

I'll give this a try this weekend and thanks again for the wealth of knowledge!

Thanks!  Big Grin
Reply
#4
Quote: I may do like you recommended and isolate some scenes that are worse than others versus same settings for the entire episode.
You might want to read: [INFO] About Vapoursynth Filter Order/Queue (+ enable 'Use Filter Queue', enable "Filtering->Vapoursynth->Misc->UI->Show 'Apply onto to'" and play a bit with it to understand how it works. (looking at the Script View also helps)

Cu Selur
Reply
#5
Is the ML stuff (BasicVSR++ and DPIRDenoise) only available in the Dev releases or is there a way to install manually? You had previously shared a dev build link via PM last year but it looks like when I installed the current public Hybrid release back in March over the top of it, it broke the ML stuff. 

I completely uninstalled Hybrid and reinstalled the current public release version and now the ML stuff options are gone.

Thanks!
Reply
#6
ML addon should work with any newer build, but I usually send links to my current dev to be sure that the version that is used is one where I know that it works with the addon.

-> will send you a new link to my current dev and the addon in ~15min.

Cu Selur
Reply
#7
Received your PM and downloaded everything. I greatly appreciate the links for the Dev builds and addons!

Thanks!
Reply
#8
Have fun with it. Big Grin
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)