digitalFAQ.com Forum

digitalFAQ.com Forum (https://www.digitalfaq.com/forum/)
-   Restore, Filter, Improve Quality (https://www.digitalfaq.com/forum/video-restore/)
-   -   VHS restoration script for broadcast recordings? (https://www.digitalfaq.com/forum/video-restore/11680-vhs-restoration-script.html)

MediaHoarder 03-28-2021 01:49 PM

VHS restoration script for broadcast recordings?
 
1 Attachment(s)
Hello video wizards, after following through on your advice for selecting equipment I now have a JVC-7800 VCR and ATI 600 USB capture setup up and running.
I have done a couple captures and would like to start on restoring them. I spent quite a bit of the last few days reading through all of the restoration threads I could find and picked up on some of the tools and approaches used.
That said, I am wondering what might be an appropriate starting point for broadcast recordings, ie. home tapes of over the air or perhaps cable television. Much of what I have seen deals with home taping using a camcorder and the various corrections required for that, but I am not sure how much of that is still relevant for restoring a professionally produced programme from a broadcast.

I have a basic Avisynth script started, to handle a few basics points, but I am not sure what else might be appropriate here. Any thoughts greatly appreciated. Sample video is attached.

Code:

AviSource("G:\Personal Files\Videos\Captures\Real Captures\out.avi")
AssumeTFF()
ColorYUV(gain_y=10)
ConvertToYV12(interlaced=true)
RemoveDirtMC(20,false)
Crop(10,0,-14,-16).AddBorders(12,8,12,8)


lollo2 03-29-2021 04:45 AM

1 Attachment(s)
This is the flow I normally do, the order is important:

- understand the nature of the video

You need to discover if your video is interlaced or not, the used telecine, fields repetition, frame rate, etc...
I am in a PAL land where generally the only problems I face is "phase shift fields" or bad NTSC-PAL transfer, but you may require the usage of IVTC, Decimate, SRestore...

The best filters are designed for progressive material and applying them to interlaced videos requires some procedure.

If I have a mixed of interlaced/progressive inside the same video I apply the filters with ConditionalFilter()

- exact removal of black bands at left, top, right and of head switching noise at the bottom with crop.

The histograms and waveform monitor used later are altered with them.

The filters work better without them.

- fix the levels inside the proper YUV 16-235 range and preliminary color correction

ColorYUV used to adjust luma contrast to limit and center luma hystogram
Tweak used to adjust luma contrast, colors saturation, hue and brightness
LevelsLumaOnly used to adjusts luma brightness, luma contrast, and luma gamma

I anticipate some color correction here because if after filtering I like the result, I avoid the final correction in VirtualDub

Levels() command in AviSynth also change the chroma, that is rarely out of range, so I prefere a modified version of it to only act on luma

- stabilization (rarely required on recorded tv programs, but sometime it happens)

- motion compensated remove dirt (not very often on recorded tv programs, but sometime it happens)

- denoise (choose here your favourite denoiser, mine is TemporalDegrain2)

- dehalo (not very often on recorded tv programs, but sometime it happens)

- sharpening (choose here your favourite sharpener here, mine is LSFmod)

- levels correction after filtering

LevelsLumaOnly used to adjusts luma brightness and luma contrast

used to my personal taste for tuning final result

necessary if exporting to VirtualDub to be in the proper YUV 16-235 range

- addborders() to reintroduce pixels removed with crop(), eventualy centering the image

- final color correction in VirtualDub in RGB colorspace

In all the steps I try to avoid lossy convertToYV12() color conversion and use filters where convertToYV16() is possible.

When facing interlaced material I apply a lossless deinterlace before filtering and then I interlace back.

Many posts from sanlyn explains very well the level adjustements in the forum, search for them. Many scripts here and in VideoHelp forums are shown. What is important is that you tune the parameters of the filters to your own case, results may change a lot.

Here one example of my workflow http://www.digitalfaq.com/forum/atta...16ad-muxed-mp4

Here another one http://www.digitalfaq.com/forum/atta...1&d=1617011784

both quickly compressed to mp4 for size reasons

lollo2 03-29-2021 09:08 AM

1 Attachment(s)
Here a last example (no broadcast s-vhs recording, commercial vhs tape) so we cover live action, animation and puppets :) :) :)

It is not optimized for stabilization, just uses lordsmurf's stabmod() script for a quick result.

http://www.digitalfaq.com/forum/atta...1&d=1617026767

If you wish and you think is worth, I can share one of the script ;-)

MediaHoarder 04-03-2021 01:10 AM

@lollo2

Thanks for the reply and info. Its been a long week here so I have not gotten much time with it yet. I did spend some more time capturing to get a better feel for the material I have to work with. The sample I shared above seems to be, relatively speaking better off than most of my material so it is a little more obvious with other clips where improvements are needed.

I do want to ask about the first thing you mentioned about
You need to discover if your video is interlaced or not, the used telecine, fields repetition, frame rate, etc...
In my case I have interlaced video at NTSC 29.97 frames per second, etc. from the capture card. However, when you mention telecine, are you referring to just cases where the source is a telecine, or also cases of broadcast programming that was taken from a telecine?

I am still cobbling a script together using what you have indicated for a different capture that needed more help, I will put a summary here once I have had time to work on it.

lollo2 04-03-2021 03:19 AM

In my tapes recorded from DVB-S TV I found interlaced, "progressive", and mix of both. On some other tapes from friends I also found PAL phase-shift, even or odd fields corrupted in a PAL50Ip structure, etc...

I ignore the characteristics of your video and I do not have Lagarith codec installed to check, but before doing any filtering you need to understand the nature of your video (in your case it does not depend on the capture card).

Some helpful links (used filters are sometimes obsolete, but the concept is still valid):

https://web.archive.org/web/20090303...2.net/faq.html
http://www.doom9.org/index.html?/cap..._avisynth.html
http://www.digitalfaq.com/forum/news...html#post36198
https://forum.doom9.org/showthread.p...07#post1865607 (Scharfis_Brain document is excellent, mainly PAL but also NTSC)

I hope it helps!

-- merged --

Quote:

I am still cobbling a script together
If you wish, you can start with a basic non optimized script like this on one of your "bad" samples

Code:

video_org=AviSource("<file path\file name")

video_org_crop=video_org.crop("crop_left","crop_top","-crop_right","-crop_bottom")

noise_baseclip=video_org_crop.Levels("your lowest black", 1, "your highest white", 16, 235)

deinterlaced=noise_baseclip.AssumeTFF().nnedi3(field=-2) #or AssumeBFF()

deinterlaced_yv16=deinterlaced.convertToYV16(interlaced=false)

denoised_yv16=deinterlaced_yv16.TemporalDegrain2(postFFT=0, postSigma=1)

denoised=denoised_yv16.convertToYUY2(interlaced=false)

denoised_yv12=denoised.convertToYV12(interlaced=false)

sharpened_yv12=denoised_yv12.LSFmod(ss_x=1.5, ss_y=1.5, secure=false, Spwr=2, SdmpHi=0, soothe=false, keep=25, edgemaskHQ=true)

sharpened=sharpened_yv12.convertToYUY2(interlaced=false).MergeChroma(denoised)

interlaced=sharpened.AssumeTFF().SeparateFields().SelectEvery(4,0,3).Weave()

video_restored=interlaced.addborders("crop_left","crop_top","crop_right","crop_bottom")

return(video_restored)

and post the comparison. I'd like to see if this blind attempt improves or not (probably not :wink2:)

MediaHoarder 04-03-2021 03:20 PM

1 Attachment(s)
Ok, for this tape I know it was taken from broadcast NTSC in the 90's so the source should be interlaced. I have attached an mp4 conversion of this "bad" tape.
I don't yet have the output from your script, I am still trying to get some functions to work.
In the case of this clip however, I have a very irritating combination of what I think are duplicated frames and some jitter. I have tried removing both with a combination of TDecimate() & Stab() but its not quite there. Any other filters to try?

lollo2 04-04-2021 04:20 AM

Well, this tape is so bad that I suspect is beyond the capabilites of AviSynth filters and my experience. When I talk about "restoration", I mainly refer to denoise, sharpening and removal of some small defect.

I think that for this tape you should add a frame-TBC (or a less effective Panasonic E-10) before capturing to mitigate in hardware some of the problems This is the field of lordsmurf, he will give better suggestions...

However, if you can post a small clip of the first 10/15 seconds in HuffYUV we can see what can be achieved, it will be useful anyhow for the future.

hodgey 04-04-2021 07:49 AM

Yeah it looks like there is some alignment and/or tracking problem on that sample, you can see the bottom of the image going in and out, and a noisy area at the middle. Manual tracking adjustment and/or a different VCR may be of help.

The sample Lollo2 posted also seem to have some issue, it looks like what you get when the TBC in the JVC SVHS decks is acting up. Using a ES10 or similar and turning the in-VCR TBC may help reduce the vertical jittering on that tape.

lollo2 04-04-2021 09:12 AM

Quote:

The sample Lollo2 posted also seem to have some issue
Which one? If you refer to the Marvel Thor cartoon it's a really bad commercial tape that the line-TBC of my JVC HR-S9500 MS is not able to fix 100%; the ES15 I tried in the chain did not succeed as well. Probably only a frame-TBC could bring some improvements, but I do not have one :(.

However, AviSynth filters improved a little bit ;-)

lordsmurf 04-04-2021 10:17 AM

Quote:

Originally Posted by lollo2 (Post 76568)
the Marvel Thor cartoon it's a really bad commercial tape

BTW, the Thor 60s toon was released official in UK about 15 years ago. I have those releases. Those were not easy to get at the time. You sometimes see them on eBay UK for $100+

All of the 60s toons were eventually available, and I have all of those releases. Cap is my favorite. (I don't count Spiderman 60s, different animation style, different everything, much longer show, easily available at the time.)

You could get a few episodes on VHS around 2000, mostly at Hastings. Maybe FYE. Not sure which Canada store (forget), but was comparable to FYE/Hastings.

If it's a Marvel or DC toon, I have it. :)

lollo2 04-04-2021 12:35 PM

Off Topic


We share a passion.

For official Thor release in DVD I have (region 2):

https://www.amazon.co.uk/Mighty-Thor...556918&sr=8-11

https://www.amazon.fr/Mighty-Thor-Co...7556870&sr=8-9

I missed the Spiderman '66 official Region 1 DVD release and now is hard to find at a decent price :(
https://www.amazon.com/Spider-Man-67.../dp/B0001I55O2

Still waiting for the Fantastic Four '67 official DVD release

MediaHoarder 04-04-2021 04:38 PM

1 Attachment(s)
Interesting thoughts on the TBC. In this case I am using the line TBC that is built into the JVC 7800, this is the only recording thus far that has had this kind of issue. Yes there is a tracking issue, this was actually captured with manual tracking in which case I was compromising between some noise in the center and some at the bottom edge. This tape was re-used several times I believe, is EP, and was not rerecorded on my JVC 7800. That was as good as it got.

Going frame by frame it appears that there are duplicated frames which is odd. I don't think it is a capture card issue either as I re-watched the tape without capturing and saw the same thing. Is it possible this was a broadcast error that got recorded to the tape?

@hodgey When you say when the TBC in the JVC SVHS decks is acting up. do you mean that as in the TBC not agreeing with that particular recording, or the TBC malfunctioning more generally? I have not noticed this on any recording except this part of one tape thus far, so I would think the former but interested to know if this is a sign of more than just trouble with one tape.

I have attached a huffyuv encoded sample of the "bad" tape from above.

MediaHoarder 04-04-2021 04:41 PM

1 Attachment(s)
Here is the output I have so far with a script I have been working on. Any thoughts on improvements? I did move crop to the end because the effect it produced at the beginning was unpleasant to say the least ( a result of stabilizing the image after crop I think).

Script is below, commented sections not used. Audio was separately noise reduced in Audacity and the treble boosted slightly.

Code:

video = AviSource("C:\Users\Charles\Videos\Scripts\out2.avi")
audio = LWlibavAudioSource ("C:\Users\Charles\Videos\Scripts\out2.wav")
AudioDub (video, audio)


# change path statement below to match your suystem
#AviSource("C:\Users\Charles\Videos\Scripts\out2.avi")

AssumeTFF()
ColorYUV(gain_y=20)
Tweak(cont=1.1,sat = 1.1, dither=true,coring=false)
ConvertToYV12(interlaced=true)
QTGMC(Preset="Faster", Lossless=2, MatchEnhance=0.75, TR2=1, Sharpness=0.1)
#Dup1(threshold = 10.0, copy = true, maxcopies = 3, blend = true)
TDecimate(mode = 4, output = "G:\Personal Files\Videos\Captures\Real Captures\stabilize.txt")
TDecimate(mode = 2, input = "G:\Personal Files\Videos\Captures\Real Captures\stabilize.txt")
Stab()
Stab()
#RemoveDirtMC(20,false)
RemoveGrain(mode=2, modeU=2, modeV=2)
#TemporalDegrain(degrain=3, ov=4, blksize=16)
TemporalDegrain2(degrainTR=2)
LSFmod(strength=100, Smode=3, Smethod=2, kernel=11)
#AddGrainC(1.5,1.5)
Crop(8,0,-8,-16).AddBorders(8,8,8,8)
#ConvertToRGB32(interlaced=false,matrix="Rec601")


lollo2 04-05-2021 06:06 AM

2 Attachment(s)
Your script is a reasonable attempt (QTGMC probably should be after decimation). Here a quick script I tried. Small improvements as well, not a lot :-( The script may have some errors. Attached the result, compressed to h264 for size reason. The comparison is with the original video after TFM and TDecimate, because the original video is too bad.

There are many many other options in term of filters and their parameters, you have to experiment a lot. But remember that the major improvement may come from "hardware".

Code:

video_org=aviSource("C:\Users\giuse\Desktop\b\out22.avi")

# separate fields tff
video_org_sep_tff=video_org.AssumeTFF().separateFields()

# separate fields bff
video_org_sep_bff=video_org.AssumeBFF().separateFields()

# separate fields tff even
video_org_sep_tff_even=video_org_sep_tff.SelectEven()

# separate fields tff even
video_org_sep_tff_odd=video_org_sep_tff.SelectOdd()

        # to check if progressive or interlaced
#return(video_org_sep_tff)
#return(video_org_sep_bff)

        # to check if TFF or BFF for interlaced segments
#stackhorizontal(\
#subtitle(video_org_sep_tff,"video_org_sep_tff",size=28,align=2),\
#subtitle(video_org_sep_bff,"video_org_sep_bff",size=28,align=2)\
#)

        # display fields separately
#stackvertical(\
#subtitle(video_org_sep_tff_even,"video_org_sep_tff_even",size=28,align=2),\
#subtitle(video_org_sep_tff_odd,"video_org_sep_tff_odd",size=28,align=2)\
#)

        # display frames and display fields separately (equivalent to VirtualDub plugin ViewFields)
#stackhorizontal(\
#subtitle(video_org,"video_org",size=28,align=2),\
#stackvertical(\
#subtitle(video_org_sep_tff_even,"video_org_sep_tff_even",size=28,align=2),\
#subtitle(video_org_sep_tff_odd,"video_org_sep_tff_odd",size=28,align=2)\
#)\
#)

# plugins directory
plugins_dir="C:\Users\giuse\Documents\VideoSoft\MPEG\AviSynth\extFilters\"

        # TIVTC
loadPlugin(plugins_dir + "TIVTC-v1.0.26\x86\TIVTC.dll")

video_org_tfm_td=video_org.TFM().TDecimate()
#stackhorizontal(video_org, video_org_tfm_td)

# cropping
        crop_left=20        # | rimozione esatta delle bande nere sinistra, sopra, destra e del disturbo sotto       
        crop_top=2        # | 720-(20+12)x576-(2+14)=688x464
        crop_right=12
        crop_bottom=14
video_org_tfm_td_crop=video_org_tfm_td.crop(crop_left,crop_top,-crop_right,-crop_bottom)

# convert to YV16 (required for Histogram)
video_org_tfm_td_crop_yv16=video_org_tfm_td_crop.ConvertToYV16(interlaced=true)

#video_org_tfm_td_crop_yv16_histo=video_org_tfm_td_crop_yv16.Histogram("Levels")

#return(video_org_tfm_td_crop_yv16_histo)

        # DePulse
loadPlugin(plugins_dir + "depulse\DePulse.dll")

video_org_tfm_td_sep=video_org_tfm_td_crop.AssumeTFF().SeparateFields()
video_org_tfm_td_dp=video_org_tfm_td_sep.DePulse(h=10, l=10, d=10).DePulse(h=10, l=10, d=10).Weave()

        # RemoveDirtSMC
Import(plugins_dir + "RemoveDirt2_modGMa.avsi")
        # MVTools
loadPlugin(plugins_dir + "mvtools-2.7.41-with-depans20200430\x86\mvtools2.dll")
        # RgTools
loadPlugin(plugins_dir + "RgTools-v1.0\x86\RgTools.dll")
        # RemoveDirt
loadPlugin(plugins_dir + "RemoveDirt-0.9.2\x86\RemoveDirt.dll")
        # SeeSaw
Import(plugins_dir + "SeeSaw.avs")
        # MaskTools2
loadPlugin(plugins_dir + "masktools2-v2.2.23\x86\masktools2.dll")

        # TemporalDegrain2
Import(plugins_dir + "TemporalDegrain-v2.2.1_modGMa.avsi")
        # RgTools
loadPlugin(plugins_dir + "RgTools-v1.0\x86\RgTools.dll")
        # MaskTools2
loadPlugin(plugins_dir + "masktools2-v2.2.23\x86\masktools2.dll")
        # MVTools
loadPlugin(plugins_dir + "mvtools-2.7.41-with-depans20200430\x86\mvtools2.dll")
        # FFT3DFilter
loadPlugin(plugins_dir + "FFT3dFilter-v2.6\x86\fft3dfilter.dll")
        # FFTW
loadPlugin(plugins_dir + "LoadDll\LoadDll.dll")
loadDll(plugins_dir + "fftw-3.3.5-dll32\libfftw3f-3.dll")
        # Dither
loadPlugin(plugins_dir + "dither-1.28.0\win32\dither.dll")
        # DFTT
loadPlugin(plugins_dir + "dfttest-v1.9.6\clang\x86\dfttest.dll")

        # LSFmod
Import(plugins_dir + "LSFmod.v1.9.avsi")
        # RgTools
#loadPlugin(plugins_dir + "RgTools-v1.0\x86\RgTools.dll")
        # MaskTools2
#loadPlugin(plugins_dir + "masktools2-v2.2.23\x86\masktools2.dll")

        # Nnedi3
loadPlugin(plugins_dir + "NNEDI3_v0_9_4_55\x86\Release_W7\nnedi3.dll")

### de-interlacing
deinterlaced=video_org_tfm_td_dp.AssumeTFF().nnedi3(field=-2)

### convert to YV16
deinterlaced_yv16=deinterlaced.convertToYV16(interlaced=false)

### cleaning
cleaned=RemoveDirtSMC(deinterlaced_yv16, 30)
cleaned2=RemoveDirtSMC(cleaned, 30)

### denoising
denoised_yv16=cleaned2.TemporalDegrain2(postFFT=3, postSigma=1)

### convert to YUY2
denoised=denoised_yv16.convertToYUY2(interlaced=false)

### convert to YV12
denoised_yv12=denoised.convertToYV12(interlaced=false)

### sharpening
sharpened_yv12=denoised_yv12.LSFmod(ss_x=1.5, ss_y=1.5, secure=false, Spwr=2, SdmpHi=0, soothe=false, keep=25, edgemaskHQ=true)

### convert to YUY2 with chroma from YUY2 color space
sharpened=sharpened_yv12.convertToYUY2(interlaced=false).MergeChroma(denoised)

### interlacing
interlaced=sharpened.AssumeTFF().SeparateFields().SelectEvery(4,0,3).Weave()

video_restored=interlaced.addborders(20,2,12,14)

#stackhorizontal(video_org, video_restored)
stackhorizontal(video_org_tfm_td, video_restored)

# ---> check the following scripts <---
# https://forum.doom9.org/showthread.php?p=1563120#post1563120
# https://forum.doom9.org/showthread.php?p=1563121#post1563121

I also found that the histogram of your capture is not optimal, because it show clipped blacks at y=16 and gaps in the values.

Attachment 13372

For the first, be sure to use proc amp setting to have lowest black at y=16 before capturing. For the second it may depend on the bad source, not sure.

lordsmurf 04-10-2021 11:28 PM

I hate the term "clipped blacks". It's not accurate. Illegal blacks were discarded.

Stating "clipped" acts as if the device is at fault. Again, not accurate. The source is the problem. In the olden days, before capture cards, you corrected this with a proc amp (and you still can). Even if you leave those illegal/clipped values, it will cause problems during viewing. Because again, illegal. You cannot have blacker than black values. Some cards will capture those, and you can play with them in post. But most cards don't capture illegal values of 0-15 or 236-255.

I see tracking errors. So discussing histograms is like arguing the color of the drapes while the house is burning down.

lollo2 04-11-2021 03:31 AM

We can use whatever definition is more appropriate, but the analog signal on the tape ignores it. The video has levels that once converted to digital in YUV colorspace are in the illegal 0-16 and 235-255 ranges and that contain details.

Most of the cards do not capture 0-16 range and capture 235-252/253/254 range, even if this last is illegal.

In order to do not loose details in the illegal ranges, the card procamp should be used to shrink the levels in the range 16-252/253/254 prior to capturing.

Quote:

I see tracking errors. So discussing histograms is like arguing the color of the drapes while the house is burning down.
It was useful to highlight illegal 0-16 range not being captured. In addition, I just wanted to give to the OP an indication to check the histograms on clean captures, because Y has gaps, but U and V do not. As I said, it may be related to the bad source ;-)

hodgey 04-11-2021 05:43 AM

Quote:

Originally Posted by MediaHoarder (Post 76586)

@hodgey When you say when the TBC in the JVC SVHS decks is acting up. do you mean that as in the TBC not agreeing with that particular recording, or the TBC malfunctioning more generally?.

The former, it's how the TBC in these VCRs can react to certain tapes.

JoLeFou 04-15-2023 12:41 PM

2 Attachment(s)
Hi Hodgey,
I have worked for several months on this VHS restoration scripts. I use it for most of my customer's tapes.
This code is based on Fred Van de Putte's restoration script, with many improvements and major updates.
This script uses the latest AVIsynth plug-ins. And, moreover, it is compatible with Avisynth+ x64, multithread.
I hope this will help :)

timtape 04-16-2023 12:13 AM

As already touched on, the most important step is getting the cleanest capture of each tape. It's where we AVOID DEGRADING the recording. It's not always simple or obvious that we've succeeded 100%. For example how do we know if the poor image on our monitor is solely what's on the tape, or due to our playback device, or perhaps a misalignment of the playback deck to the tape played?

It's also why using software tools after capture is not really "restoration". It's perhaps better seen as some tidying up/ filtering after having captured the tape optimally.

themaster1 04-16-2023 05:35 AM

You don't want to use DirectShowSource(), it's not frame accurate, and can have problems with the interlacing at times. I've spotted a couple unecessary steps in your filtering imo, but without a video sample i can't do anything to help further on this "months long" scripted script :)


All times are GMT -5. The time now is 04:51 AM

Site design, images and content © 2002-2024 The Digital FAQ, www.digitalFAQ.com
Forum Software by vBulletin · Copyright © 2024 Jelsoft Enterprises Ltd.