digitalFAQ.com Forums [Archives]

digitalFAQ.com Forums [Archives] (http://www.digitalfaq.com/archives/)
-   Avisynth Scripting (http://www.digitalfaq.com/archives/avisynth/)
-   -   Avisynth: MaskTools based adaptive script? (http://www.digitalfaq.com/archives/avisynth/9221-avisynth-masktools-based.html)

marcellus 04-20-2004 05:50 PM

Avisynth: MaskTools based adaptive script?
 
Hi, everybody!

Being a ffvfw/ffdshow freak I finally managed to shoot myself in the foot with it, getting with a particular encode bitrate peaks over 7000 kbps at VCD resolution (352x288), with Q value after the peaks as high as 31. (Yeah, a sudden high motion/high detail area in the movie, libavcodec based encoders users must know what I'm talking about).

So I thought I need a more aggressive filtering (my source is a capture) against high motion and noise, but also with preservation for the details and pleasant look.

I think the MA script is sub-optimal (at least for noisy sources as captures) because detecting motion by luma variation doesn't seem to me very satisfying (I mean there are a lot of movement without much luma variation). Besides, I don't like the idea of spatially filtering the entire image when high movement is detected, temporalsmoother preserves more detail (when it can). Put those thoughts together with the interest I got for the masktools plugin developed lately by Manao (also used in HybridFuPP, but that thing is way over my understanding to optimally use it) and you'll get the basic idea for the script I managed to put together (I am a complete newbie in scripting field so I spent many hours (days, as a matter of fact) in the following loop: read avisynth docs -read masktools doc - try -error -read docs again - try -error ... ;-)

To cut it short, I got a script that works (and worked good) for me (I make TV capture based PAL KVCDs), but with some fine tunings regarding resolution/quality/movie character I think could work for everybody. A disadvantage vs. MA script is the slower speed (of course). But I think it's well spent CPU processing.

The funny thing is: I realized that I somehow reproduced peachsmoother algorithm, because with some settings I managed to get peachsmoother's "floating hair around the head" phenomenon, but I think the masktools motion detection (SansGrip's algo as I understand) is better than the one in peachsmoother and anyway I got much more control in this script.

Code:

SetMemoryMax(64)
#####Load plugins:
Loadplugin("C:\Program Files\AviSynth 2.5\pluginz\MPEG2Dec3dg.dll")
LoadPlugin("C:\Program Files\AviSynth 2.5\pluginz\unfilter.dll")
#
#
#You need the latest manao's masktools plugin (1.4.15.3 at the moment)
#you can find it in this page:
#http://www.geocities.com/manao47/Filters/
LoadPlugin("C:\Program Files\AviSynth 2.5\pluginz\masktools.dll")
#
#
#
#####Source: put your source here and crop\resize it as needed
thesource=mpeg2source("your_source.d2v") \
        .crop(your_settings).????resize(your_settings).trim(your_settings)
#
#
#####Processing:
#You need to put the borders before processing
#because unfilter seems to act funny at the borders, so it's better to
#cover the "funny" area with overscan borders:
original=thesource.letterbox(16,16,16,16) #or addborders, you know better
                                        #your source
#
#
#Movement mask: it makes a grayscale mask with areas where is detected movement.
#Tweak parameters acording to your source in order to get a good representation
#of moving areas.(Read MaskTools readme for details). Later it will be
#temporal/spatial filtered because is very noisy
movementmask=MotionMask(original,thY1=0,thY2=1,thSD=255 \
        ,y=3,u=-128,v=-128)
#
#
#Border mask: it makes a blured border where the final image will be gradually
#spatial filtered (one macroblock wide, in addition to overscan macroblock) The image
#I actually use is here: http://www.marcellusvcd.netfirms.com/bordermask.html.
#I think doing so increases the compresibility a little with
#very low impact on image quality (well, I want to squeeze all I can).
#Of course, you need to make another macroblock aligned image if you use
#other resolution than 352x288.
bordermask=ImageReader \       
        ("C:\Program Files\AviSynth 2.5\pluginz\bordermask.png" \
        ,fps=25).converttoyv12()
#
#
#Final mask is made by adding movementmask to bordermask. I temporal/spatial
#filter the final mask because is very noisy and flickering by nature. I put a
#heavy limiter because otherwise the final image is flickering (I don't know why,
#the mask is actually never seen, it only controls merging spatial filtered
#and temporal filtered clips - anyone has an idea?)
finalmask=overlay(movementmask,bordermask \
        ,x=0,y=0,mode="lighten",pc_range=true)\
        .temporalsoften(2,255,255,255).unfilter(-100,-100)\
        .limiter(32,224).fity2uv("bilinear")
#
#
#Spatial filtered clip (needs fine tuning for your source/resolution):
spatial=original.scriptclip("unfilter(int(-100*averageluma(finalmask)/224) \
        ,int(-100*averageluma(finalmask)/224))")
#
#
#Temporal filtered clip(idem about tuning):
temporal=original.TemporalSoften(2,8,16,10,2)
#
#
#Merged clips:
merged=temporal.MaskedMerge(spatial,finalmask,y=3,u=3,v=3) \
        .scriptclip("unfilter(int(-10*averageluma(finalmask)/224) \
        ,int(-10*averageluma(finalmask)/224))")
#
#
#####Final:
final=merged.limiter()
#
#
return final

Please remember:
-The script is very agressive right now, I needed it that way, is targeted on noisy sources. To make it "lighter" first try decrease unfilter "multiplicators".
-I'm a newbie in scripting, so if you have any idea/correction/speed optimization/improvement -I would be glad to know it, I think I already reached my limits here :-) .


bye
marcellus

Peter1234 04-20-2004 09:24 PM

marcellus,
I am confused by the following script line, can you please explain it?

bordermask=ImageReader \
("C:\Program Files\AviSynth 2.5\pluginz\bordermask.png" \
,fps=25)

My fps is 29.97, when I change it in this script line in get an error "fps" had wrong type.

My script is:

LoadPlugin("C:\Filters25\masktools.dll")
LoadPlugin("C:\Filters25\UnFilter.dll")
LoadPlugin("C:\Filters25\MPEG2Dec3dg.dll")
thesource=AVISource("C:\Documents and Settings\user\Desktop\DVtype2.avi")
thesource=ConvertToYV12(thesource)
original=thesource
movementmask=MotionMask(original,thY1=0,thY2=1,thS D=255 \
,y=3,u=-128,v=-128)
bordermask=ImageReader \
("C:\Filters25\bordermask.png" \
,fps=29.97)
finalmask=overlay(movementmask,bordermask \
,x=0,y=0,mode="lighten",pc_range=true)\
.temporalsoften(2,255,255,255).unfilter(-100,-100)\
.limiter(32,224).fity2uv("bilinear")
spatial=original.scriptclip("unfilter(int(-100*averageluma(finalmask)/224) \
,int(-100*averageluma(finalmask)/224))")
temporal=original.TemporalSoften(2,8,16,10,2)
merged=temporal.MaskedMerge(spatial,finalmask,y=3, u=3,v=3) \
.scriptclip("unfilter(int(-10*averageluma(finalmask)/224) \
,int(-10*averageluma(finalmask)/224))")
final=merged.limiter()
return final

As you can tell I do not know much about script writing. But I would like something to help me clean up my noisy DV tapes. I do not want to resize the video.

marcellus 04-21-2004 07:38 AM

Hi Peter

First of all: that "border mask" trick is not so important (as the rest of the script), so you can try my script bypassing that. Your script would be:
Code:

LoadPlugin("C:\Filters25\masktools.dll")
LoadPlugin("C:\Filters25\UnFilter.dll")
LoadPlugin("C:\Filters25\MPEG2Dec3dg.dll")
thesource=AVISource("C:\Documents and Settings\user\Desktop\DVtype2.avi")
thesource=ConvertToYV12(thesource)
original=thesource
movementmask=MotionMask(original,thY1=0,thY2=1,thSD=255 \
,y=3,u=-128,v=-128)
#bordermask=ImageReader \
#("C:\Filters25\bordermask.png" \
#,fps=29.97)
#finalmask=overlay(movementmask,bordermask \
#,x=0,y=0,mode="lighten",pc_range=true)\
#.temporalsoften(2,255,255,255).unfilter(-100,-100)\
#.limiter(32,224).fity2uv("bilinear")
finalmask=movementmask.temporalsoften(2,255,255,255)\
.unfilter(-100,-100).limiter(32,224).fity2uv("bilinear")
spatial=original.scriptclip("unfilter(int(-100*averageluma(finalmask)/224)\
,int(-100*averageluma(finalmask)/224))")
temporal=original.TemporalSoften(2,8,16,10,2)
merged=temporal.MaskedMerge(spatial,finalmask,y=3,u=3,v=3) \
.scriptclip("unfilter(int(-10*averageluma(finalmask)/224) \
,int(-10*averageluma(finalmask)/224))")
final=merged.limiter()
return final

But if you want try it anyway: what resolution do you have? I assume because your fps you are not encoding at PAL 352x288. So you have first to resize that bordermask.png to your resolution. Is best to construct it again in a bitmap editor, because if you simply resize it you will get it masking more/less areas you don't want masked.

Now, to your fps problem:
Use the latest avisynth alpha release:
http://cultact-server.novi.dk/kpo/avisynth/avs_cvs.html
With it you can use non-integer fps for imagereader.

Peter1234 04-21-2004 01:00 PM

marcellus,
Thanks, works with updated AviSynth. It is very agressive as you said. but it definitely gets rid of any interlace artifacts. I added asharp and the results are good. I will try to adjust values in your script as I figure them out and do some more tests. My source is 720x480 interlaced 29.97fps from DV camera. I want to keep it at 720x480. ImageReader does not seem to have a problem with 720x480 frame size. Without boardermask statement I did not see any problems on edges.

edit - I guess I just didn't notice them at first, there are still problems on edges even without boardermask statement, so I put letterbox back in.


All times are GMT -5. The time now is 01:10 AM  —  vBulletin © Jelsoft Enterprises Ltd

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