digitalFAQ.com Forum

digitalFAQ.com Forum (https://www.digitalfaq.com/forum/)
-   Restore, Filter, Improve Quality (https://www.digitalfaq.com/forum/video-restore/)
-   -   Static, moving bars in VHS video? (https://www.digitalfaq.com/forum/video-restore/8030-static-moving-bars.html)

solchaser 06-03-2017 04:38 PM

Static, moving bars in VHS video?
 
1 Attachment(s)
Is it possible to remove (or even soften) static (sometimes moving from top to the bottom of the video) bars like those in the attached video?

The bars appear in the beginning and in the middle of the video a couple of times.

What else (besides AviSynth's QTGMS and chubbyrain2 filters) could I do to enhance quality of this particular video?

sanlyn 06-03-2017 05:10 PM

Quote:

Originally Posted by solchaser (Post 49611)
What else (besides AviSynth's QTGMS and chubbyrain2 filters) could I do to enhance quality of this particular video?

I think you mean QTGMC (a deinterlacer and denoiser), while chubbyrain2 is a chroma cleaner. Neithr of those would have any effect.

Not much you can do. The bars are static, or very slow moving. Think about it: what picture elements would one be able to use or create to replace the bars if they're removed? Someone might devise a surpirse, but for tape this badly damaged there's likely no fix.

solchaser 06-04-2017 09:29 AM

2 Attachment(s)
Thanks for the reply. I was just wondering (I even hoped so) that there's some kind of content-aware tools, that you can find in Adobe's products but just for video editing.

I’ve tried to do some “content-aware” filling with one frame in Photoshop, but I don’t think that’s a good idea for a couple minute video (with 50 FPS) - my computer behaves like a jet engine just when it comes to AS script (I need at least 12h to process the whole video). I’ve attached the “final” results.

This is the AviSync's script I've used to prepare the frame to do "content-aware filling" test.

Code:

# Set Multi-Threading
SetMTMode(6)

# Set inputVideo
inputVideo = AVISource("c:\video.avi")
processedVideo = inputVideo

#Don't know if we need this:
#lvideo = AssumeTFF(lvideo)

# Deinterlance
processedVideo = QTGMC(processedVideo, preset="slower",EZDenoise=6,denoiser="dfttest",ChromaMotion=true, border=true,ChromaNoise=true,DenoiseMC=true,GrainRestore=0.5)

# Fix the most issues connected with VHS tapes
processedVideo = FixChromaBleeding(processedVideo)
processedVideo = FixVHSOversharp(processedVideo,20, 18, 10)
processedVideo = FixVHSOversharpL(processedVideo,10, 20, 10)

# We need to convert YUY2 to YV12 for filter processing
processedVideo = ConvertToYV12(processedVideo,interlaced=false)

processedVideo = SmoothLevels(processedVideo,16,1.0,255,16,250,chroma=200,limiter=0,tvrange=true,dither=100,protect=6)
# Propably is not mandatory in this file
#lvideo = ChromaShift(lvideo, C=0,L=0)

processedVideo = deVCR(processedVideo,30)

# Remove the spatial-temporal rainbow (visible especially at the top of video)
processedVideo = chubbyrain2(processedVideo, th=1, radius=25) # remove moire rainbows

processedVideo = tweak(processedVideo,hue=10, coring=false)

super = processedVideo.MSuper(pel=2, sharp=1)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, blksize=8, overlap=4, dct=0)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, blksize=8, overlap=4, dct=0)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, blksize=8, overlap=4, dct=0)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, blksize=8, overlap=4, dct=0)
processedVideo = MDegrain2(processedVideo,super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
processedVideo = TemporalSoften(processedVideo,4,4,8,15,2)

# And finally crop and return the processed video
processedVideo = Crop(processedVideo, 14, 0, -8, -46, align=False)
return processedVideo


Function FixChromaBleeding (clip input) {

  # prepare to work on the V channel and reduce to speed up and filter noise
  area = input.tweak(sat=4.0).VtoY().ReduceBy2()

  # select and normalize both extremes of the scale
  red = area.Levels(255,1.0,255,255,0)
  blue = area.Levels(0,1.0,0,0,255)

  # merge both masks
  mask = MergeLuma(red, blue, 0.5).Levels(250,1.0,250,255,0)

  # expand to cover beyond the bleeding areas and shift to compensate the resizing
  mask = mask.ConvertToRGB32().GeneralConvolution(0,"0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0").ConvertToYV12()

  # back to full size and binarize (also a trick to expand)
  mask = mask.BilinearResize(Width(input),Height(input)).Levels(10,1.0,10,0,255)

  # prepare a version of the image that has its chroma shifted and less saturated
  input_c = input.ChromaShift(C=-4).tweak(sat=0.8)

  # combine both images using the mask
  return input.overlay(input_c,mask=mask,mode="blend",opacity=1)
}

function DetectVCRLines(clip c,int threshold)
{
spacial_data = GeneralConvolution(ConvertToRGB(c),0,"0 -1 0 0 2 0 0 -1 0")
bar_data = ConvertToRGB(BilinearResize(spacial_data,16,c.height))
st_data = Overlay(bar_data,Trim(bar_data,1,0),mode = "subtract")
st_data2 = Greyscale(Levels(st_data,threshold,10.0,threshold+1,0,255,coring = false))
st_data3 = Greyscale(Levels(st_data2,127,10.0,128,0,255,coring = false))
st_data4 = Overlay(st_data3,st_data3,y = -1, mode = "add")
return PointResize(st_data4,c.width,c.height)
}

function deVCR(clip c,int threshold)
{
mybars = DetectVCRLines(c,threshold)
return Overlay(c,Trim(c,1,0), mask = mybars,greymask = true)
}


msgohan 06-04-2017 09:54 AM

That deVCR function is ultimately just replacing the "detected lines" with the same spatial location, from the previous frame (in this case the previous field since you correctly fed it 50Hz input).

sanlyn 06-04-2017 02:31 PM

I tightened up your script somewhat, so hope yolui don't mind. I think adding MDegrain2 is a bit of overkill and really slows things down, but you can certainly use whatever you want.

I'd strongly advise that you don't do the following:
Code:

# And finally crop and return the processed video
processedVideo = Crop(processedVideo, 14, 0, -8, -46, align=False)

That code results in an oddball frame size that no website would accept, does not make a 4:3 image, and distorts the image proportions. It's only mod-2, not mod-4, not mod-8, not mod-16. Many players have problems with mod-2 video -- many Avisynth and some Virtualdub filters generate or cause errors with mod-2 video. Some Avisynth filters require at least mod-8.

As you can see, temporal filters don't often treat continuous, static disturbances as noise. Doing this sort of thing manually has been tried many times, but remember that video moves -- locations in one frame have to match other frames, or the moving image will look "disturbed" during play, like sloppy animation.

Code:

# Set Multi-Threading
SetMTMode(6)

AVISource("c:\video.avi")
AssumeTFF()
QTGMC(preset="medium",EZDenoise=8,denoiser="dfttest",ChromaMotion=true, border=true,\
  ChromaNoise=true,DenoiseMC=true,GrainRestore=0.5)

# Fix the most issues connected with VHS tapes
FixChromaBleeding()
FixVHSOversharp(20, 18, 10)
FixVHSOversharpL(10, 20, 10)

# We need to convert YUY2 to YV12 for filter processing
ConvertToYV12(interlaced=false)
SmoothLevels(16,1.0,255,16,250,chroma=200,limiter=0,tvrange=true,dither=100,protect=6)

# Propably is not mandatory in this file
#ChromaShift(C=0,L=0) #<- these values do nothing.

deVCR(30)

# Remove the spatial-temporal rainbow (visible especially at the top of video)
chubbyrain2(th=1, radius=25) # remove moire rainbows

tweak(hue=10, coring=false, dither=true)
source=last
super = source.MSuper(pel=2, sharp=1)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, blksize=8, overlap=4, dct=0)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, blksize=8, overlap=4, dct=0)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, blksize=8, overlap=4, dct=0)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, blksize=8, overlap=4, dct=0)
MDegrain2(source,super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
TemporalSoften(4,4,8,15,2)

# And finally crop and return the processed video as PAL original 720x576
Crop(12, 0, -8, -8, align=False).AddBorders(10,4,10,4)

# Reinterlace for DVD/BluRay/AVCHD and encode for 4:3 DAR playback.
SeparateFields().SelectEvery(4,0,3).Weave()
return last


Function FixChromaBleeding (clip input) {

  # prepare to work on the V channel and reduce to speed up and filter noise
  area = input.tweak(sat=4.0).VtoY().ReduceBy2()

  # select and normalize both extremes of the scale
  red = area.Levels(255,1.0,255,255,0)
  blue = area.Levels(0,1.0,0,0,255)

  # merge both masks
  mask = MergeLuma(red, blue, 0.5).Levels(250,1.0,250,255,0)

  # expand to cover beyond the bleeding areas and shift to compensate the resizing
  mask = mask.ConvertToRGB32().GeneralConvolution(0,"0 0 0 0 0 1 1 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0").ConvertToYV12()

  # back to full size and binarize (also a trick to expand)
  mask = mask.BilinearResize(Width(input),Height(input)).Levels(10,1.0,10,0,255)

  # prepare a version of the image that has its chroma shifted and less saturated
  input_c = input.ChromaShift(C=-4).tweak(sat=0.8)

  # combine both images using the mask
  return input.overlay(input_c,mask=mask,mode="blend",opacity=1)
}

function DetectVCRLines(clip c,int threshold)
{
spacial_data = GeneralConvolution(ConvertToRGB(c),0,"0 -1 0 0 2 0 0 -1 0")
bar_data = ConvertToRGB(BilinearResize(spacial_data,16,c.height))
st_data = Overlay(bar_data,Trim(bar_data,1,0),mode = "subtract")
st_data2 = Greyscale(Levels(st_data,threshold,10.0,threshold+1,0,255,coring = false))
st_data3 = Greyscale(Levels(st_data2,127,10.0,128,0,255,coring = false))
st_data4 = Overlay(st_data3,st_data3,y = -1, mode = "add")
return PointResize(st_data4,c.width,c.height)
}

function deVCR(clip c,int threshold)
{
mybars = DetectVCRLines(c,threshold)
return Overlay(c,Trim(c,1,0), mask = mybars,greymask = true)
}


solchaser 06-07-2017 03:48 AM

Thanks, that's good to know :-)

Probably I will not use MDegrain2, because as you described it - it would be overkill. I've exported AVS as AVI using only:

Code:

AVISource("c:\video.avi")
AssumeTFF()
QTGMC(preset="medium",EZDenoise=8,denoiser="dfttest",ChromaMotion=true, border=true,\
  ChromaNoise=true,DenoiseMC=true,GrainRestore=0.5)

and the whole process took about 17 hours to complete on my 2h recording. That's insane :eek: But it does look better actually.

sanlyn 06-07-2017 04:03 AM

Quote:

Originally Posted by solchaser (Post 49660)
whole process took about 17 hours to complete on my 2h recording. That's insane :eek: But it does look better actually.

Not really insane. It sounds about par since QTGMC is being used as fairly aggressive multiple filters and does a lot of work. That's why QTGMC isn't used for real-time deinterlacing for playback.

In the past I had some godawful captures that required QTGMC and a second industrial-strength cleaner like MDegrain2 or TemporalDeGrain or MCTemporalDenoise (the last two are even slower), but I ran those complex scripts in two separate steps to avoid freezing up my PC.


All times are GMT -5. The time now is 09:01 PM

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