Your avi sample is a proper capture in terms of format and other factors. It's a low-detail video, likely the camera's fault and the tape used. But it also has a fairly low noise level for home-made video. The bug in the ointment is the magenta stain, a glitch present with many tapes.
Below is the script I used for the mp4 rework. I've included some more links for popular plugins and for documentation on some Avisynth functions. Sometimes the docs can be pretty technical, but you only have to get a general idea of what's going on. A lot of the programming involved is beyond most users, so don't feel intimidated.
Code:
# --- alter the path below to match your system --- #
Import("D:\Avisynth 2.5\plugins\Chubbyrain2.avs")
Import("D:\Avisynth 2.5\plugins\Stab.avs")
Import("D:\Avisynth 2.5\plugins\LimitedSharpenFaster.avs")
# --- alter the path below to match your system --- #
AVISource("E:\forum\faq\rks84093\Sample 1b.avi")
AssumeTFF()
ConvertToYV12(interlaced=true)
ChromaShift(L=-4,C=-4)
# --- special routine for the magenta left border -- #
separatefields
a=last
a
chubbyrain2()
smoothuv(radius=7)
MergeChroma(MCTemporaldenoise(settings="very high"))
SmoothTweak(hue2=-4,hue1=-6)
crop(0,0,-688,0,true)
b=last
overlay(a,b)
weave()
# =-- end of left border routine -- #
QTGMC(preset="super fast",EZDenoise=8,denoiser="dfttest",ChromaMotion=true,\
border=true,ChromaNoise=true,DenoiseMC=true,GrainRestore=0.3,FPSDivisor=2)
Stab()
DeHalo_Alpha()
LimitedSharpenFaster()
AddGrainC(1.25,1.25)
Crop(20,2,-8,-8).AddBorders(14,4,14,6)
ConvertToRGB32(interlaced=false)
return last
script details:
The script begins with three
Import() statements that import the code for three Avisynth plugins that are in .avs script format. Many popular filters are published in this format, for reasons best known to the developers. Plugins are also published as dll's and as .avsi files, which are loaded automatically when your script calls for them. Plain text .avs files must be imported explicitly, or you can copy their entire contents into your own script. But be careful doing that: QTGMC and many other plugins have hundreds of lines of code!
http://avisynth.nl/index.php/Internal_functions#Import
AviSource("E:\forum\faq\rks84093\Sample 1b.avi") opens and decodes the video file. AviSource can do this with your .avi sample if the video and audio codecs you used are present.
http://avisynth.nl/index.php/AviSource.
AssumeTFF()
Because deinterlacing will be used later, you must tell AVisynth what field order priority will be used. Avisynth's default is BFF (Bottom Field First), which is incorrect for your sample and will cause problems.
AssumeTFF() = Top Field First, the usual field parity for most videos except certain DV formats.
http://avisynth.nl/index.php/Parity.
ConvertToYV12(interlaced=true)
ChromaShift(L=-4,C=-4)
You captured correctly using YUY2 color for VHS, but the filters being used here work with YV12. There is a chroma difference between YUY2 and YV12, but Avisynth manages colorspace conversions with greater precision than you'll find in most editors (in particular, NLE's such as Adobe aren't so careful). Avisynth filters can work with many color systems. You'll almost always use YUY2, YV12, or RGB. In any case, you must tell Avisynth whether the current state of your video is interlaced or not. At this point in the script the video is still interlaced, so we add "
(interlaced=true)".
http://avisynth.nl/index.php/Convert.
The video has some color shift, with chroma displaced outside an object's edges. You can see the shift in the orange of the traffic sign along the road's right edge and somewhat on the hood of the car.
ChromaShift makes a correction of 4 pixels upward (
L=-4) and 4 to the left (
C=-4). The syntax for signals you can use to direct ChromaShift are on the filter's wiki page and in its documentation:
http://avisynth.nl/index.php/ChromaShift. In YUV colorspaces ChromaShift must use groups of at least 2 pixels. The image below shows the original orange chroma shift on the road sign (
left), and the result of corrections in the mp4 rework (
right).
# --- special routine for the magenta left border -- #
separatefields()
a=last
These lines begin a special routine for a special problem: the strong magenta stain on the left border. SeparateFields() is a form of deinterlace, in which the two half-height fields in the interlaced frame are separated into a non-interlaced stream. This new stream of fields is assigned the name of
"a", which is purely an arbitrary name that I invented. The
"a" is used to name the new video that was created from the "
last" step the script performed, which was to separate the interlaced fields.
http://avisynth.nl/index.php/SeparateFields
a
chubbyrain2()
smoothuv(radius=7)
MergeChroma(MCTemporaldenoise(settings="very high"))
SmoothTweak(hue2=-4,hue1=-6)
crop(0,0,-688,0,true)
b=last
The
"a" is now mentioned explicitly to focus processing on the new
"a" video. The first filter used on
"a" is an old standy de-rainbow cleaner,
chubbyrain2. The origin of its name was lost years ago. It's followed by another rainbow cleaner,
SmoothUV. It's followed again by an industrial-strength denoiser (
MCTemporalDenoise, or
MCTD for short) which works only on the chroma factor because it works within bounds of the
MergeChroma() function.
MergeChroma takes the work MCTD does on the chroma (color channels)and joins it with the luma (luminance channel) from the original
"a" video. Otherwise, MCTD working on this soft video would soften it far too much, especially since MCTD is used here at full strength. This illustrates another important characteristic of YUV colorspaces: you can work on luma and chroma separately, which you can't do with RGB.
We now have an
"a" video that has been de-rainbowed somewhat, but some facets of the color balance have changed so we must do a bit of color matching to match the cleaned portions with the background colors. The filter for this is
SmoothTweak, which is a function in the
SmoothAdjust.dll plugin. It makes a couple of hue changes to further reduce remnants of the the magenta stain, adding some slight green (
Hue2) and some slight yellow (
hue1). Now that we have this cleaned image, we really just want the portion of the image that contained the magenta stain, not the entire reprocessed frame. So
Crop() is used to chop off the right-hand 688 pixels, and we're left with the 32 left-hand pixels that have been cleaned. This narrow strip of video is now named
"b", which is another name I used off the cuff.
chubbyrain2.avs is at
http://avisynth.nl/index.php/ChubbyRain2. It requires a support file called
BiFrost, which you can get in Bifrost_v2.zip at
http://www.digitalfaq.com/forum/atta...-bifrost_v2zip. In turn, BiFrost requires another old standby,
CNR2. You can get CNR 2 at
http://avisynth.nl/index.php/Cnr2. The last support file you'll need for chubbyrain2 and its mates is
MaskTools2, which is already supplied with the QTGMC package mentioned earlier.
SmoothUV.dll is a chroma cleaner available at
http://avisynth.nl/index.php/SmoothUV.
Links for MCTemporalDenoise (MCTD) and its support files are in my previous post.
SmoothTweak is a function in the popular
SmoothAdjust plugin, which has several functions for massaging luma and chroma levels. Complete instructions are in its readme.txt file. you'll find
SmoothAdjust used in many posted projects. It comes only from a doom9.org post which has been going down a lot lately, so the complete plugin package is attached to this post as
SmoothAdjust320.zip.
overlay(a,b)
weave()
The script has now created two versions of the video: an
"a" version that represents the original input, and a cleaned and cropped
"b" version that consists of the 32 left-hand pixels of the filtered version. The
overlay() function will overlay the narrow left-hand
"b" onto the full-sized
"a". This move covers up a lot of the magenta stain, although at this point it's not 100% cleared. The next step is to restore the original interlaced structure by using
weave() to re-weave the separated fields back into interlaced frames.
See Overlay() at
http://avisynth.nl/index.php/Overlay.
See Weave(0 at
http://avisynth.nl/index.php/Weave.
QTGMC(preset="super fast",EZDenoise=8,denoiser="dfttest",ChromaMotion= true,\
border=true,ChromaNoise=true,DenoiseMC=true,GrainR estore=0.3,FPSDivisor=2)
This statement deinterlaces using QTGMC with some of its defaults overridden for extra chroma noise cleaning. QTGMC's "
super fast" default can be used all by itself by typing "QTGMC(preset="super fast") and let QTGMC let go at default settings, but super-fast doesn't do much cleaning. On the other hand you could use one of QTGMC's slowest presets (QTGMC(preset="slow") and clean up a lot, but IMO that would be overkill for this video and it has so little fine detail that it would look seriously over-filtered and somewhat like jello.
EZDenoise activates extra cleaning that isn't normally done at the super-fast preset. "
dfttest" is specified as the denoiser (
dfttest comes with the QTGMC package).
ChromaMotion=true and
ChromaNoise=true tell QTGMC to clean chroma noise as well as luma noise,
border=true tells QTGMC to use special resizing so that top and bottom borders don't get too thick/thin or flicker after half-sized fields are resized into full-size frames.
GrainRestore=0.3 restores just a small amount of the original grain to prevent an over-filtered look, and
DenoiseMC activates motion analysis for denoising. Finally,
FPSDivisor=2 drops alternate fields to maintain 29.97fps playback, and does it while interpolating new progressive frames from the original interlaced fields. QTGMC's presets and other parameters are explained in the documentation html and in the avsi script itself, both of which come with the QTGMC package described and linked in the previous post.
With special QTGMC denoising enabled and with MCTemporalDenoise used earlier at full strength, this script runs very sloooowly, poking along at about 3fps on my 3.4GHz i5 system. There's really no way around this slow performance because of the unusual noise problems. Without MCTD working on that stain at full power and with less denoisinbg by QTGMC, this script would process at about 10 to 15fps.
Stab()
This is an optional step, but it helps to effect a bit of mild stabilization in face of so much jumpy camera motion. For one thing, it will help the filters that follow the
stab() plugin. You can omit this step if you want. The Stab.avs plugin is in
stab.zip at http://www.digitalfaq.com/forum/attachment.php?attachmentid=8698&stc=1&d=153144248 3.
Stab() requires the DePan tools of Depan and DepanEstimate in DePan_Tools_1_13_1.zip at
http://www.digitalfaq.com/forum/atta...1&d=1531396979.
DeHalo_Alpha()
LimitedSharpenFaster()
AddGrainC(1.25,1.25)
There are some mild bright sharpening halos along the edges of some verticals, such as posts on the roadway.
DeHalo_Alpha is used here at default to avoid too much softening. Edge halos are a common problem with analog tapes.
LimitedSharpenfaster is a favorite sharpener that doesn't overly enhance edges or cause new sharpening halos. It's used here at mild default settings.
AddGrainC comes last, to add a layer of very fine film-like grain to avoid a waxy, over-smooothed look.
DeHalo_Alpha in its original .avsi format with its html documentation is attached below as DeHaloAlpha.zip. It requires
MaskTools2 and
RemoveGrain (part of RGTools), both of which are in the QTGMC package
LimitedSharpenFaster.avs and its text file doc are in LimitedSharpenFaster.zip at
http://www.digitalfaq.com/forum/atta...arpenfasterzip. It requires
MaskTools2 and
Rgtools, both of which are in the QTGMC package. It also requires aWarpSharp, which is one of the support files for MCTemporalDenoise discussed in the previous post, or in aWarpSharp2_2015.zip at
http://www.digitalfaq.com/forum/atta...sharp2_2015zip.
AddGrainC comes with the QTGMC package.
Crop(20,2,-8,-8).AddBorders(14,4,14,6)
This
Crop() statement crops borders and adjusts new borders to center the core image. The right-hand border has a bright halo along its edge, so that's part of the image that should be cropped off. On the left-hand border stain, some of the pink striped noise remains and is too dark for any of the filters used, so a few extra pixels have to be dropped from the left-hand side. Adding black border pixels ensures that all black edges around the image will blend with the black backgrounds on monitors and TV's the same way a 4:3 broadcast or DVD would blend. There was also an extra 2 pixels of cropping on 2 edges for the Stab() stabilization step, which shifted the image and borders inside the frame. AddBorders() adds new black pixels in this order: 14 at the left, 4 across the top, 14 at the right, and 6 along the bottom, thus restoring the frame to 720x480.
Crop():
http://avisynth.nl/index.php/Crop
AddBorders():
http://avisynth.nl/index.php/Crop
The resized 4:3 images below show how the crop and border functions worked to omit the worst part of the pink stain and to rebuild the frame to its original 720x480 dimensions.
(A) original frame with left border stain and 1-pixel bright halo on right border, plus head-switching noise across bottom
(B) stain filtered and partial color correction.
(C) final frame with stain, color, mild stabilizing, and border correction.
ConvertToRGB32(interlaced=false)
return last
The last two lines prepare the output for RGB filters in
Virtualdub and tell Avisynth to return the results of the
"last" step performed, which was conversion to RGB. As usual, you must specify the interlace state when making conversions. At this point the output video was not interlaced, so "
interlaced=false" is included.
The
VirtualDub filtering that I applied to the output of this script was done while VirtualDub was running the script. The filters used and their settings were saved in a VirtualDub .vcf file, which was attached to my previous post and is described there.
For more details about scripting and for some pics and demos of using various VirtuaLDub filters, browse the project postings in an older thread, such as VirtualDub filter details in
post #19, color and levels correction in
post #17, and correcting camera exposure errors in
post #21 of that thread.