Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
5th October 2004, 12:18 | #1 | Link |
Registered User
Join Date: Aug 2004
Location: Italy
Posts: 45
|
Anti-aliasing script
Code:
function antialiasing(clip orig,int "th_luma",int "th_croma",string "type",int "aath") { # "th_luma" & "th_croma" are the edge detection thres.: lower values=more edges filtered # "type" is the matrix used for edge detection: with "sobel" (default) only the # hi-contrast edges, where artefacts are more noticeable, are filtered. If you want # to test other matrices, read the MaskTools Guide for more info. # "aath" = anti-aliasing strenght (default should be fine) th_luma = Default(th_luma, 20) th_croma = Default(th_croma, 20) type = Default(type, "sobel") aath = Default(aath, 48) ox = orig.width oy = orig.height dx = orig.width * 2 dy = orig.height * 2 clp = orig.IsYV12() ? orig : orig.ConvertToYV12() a=clp b=clp.Lanczos4Resize(dx,dy).TurnLeft().SangNom(aa=aath).TurnRight().SangNom(aa=aath) \ .LanczosResize(ox,oy) c=clp.EdgeMask(th_luma,th_luma,th_croma,th_croma,type) MaskedMerge(a,b,c) } This filter is meant for good quality clips with soft antialiasing (like DVs); thanks to MaskTools' functions, a strong AA-filter (Sangnom) is applied only where it's needed without producing artefacts typical of this filter. Requires: -MaskTools -SangNom Let me know what do you think about it! P.S. Thanks to Didée, mf, scharfis_brain and Soulhunter (in alphabetical order) for their help! EDIT1: Ooops! Now, with Lanczos4Resize instead of PointResize, there's no definition loss nor artefacts. ...and now SangNom's config. is aviable EDIT2: Credits EDIT3: Fixed a typo, erased a useless option, more info added. Last edited by SpikeSpiegel; 23rd October 2004 at 10:51. |
5th October 2004, 16:29 | #2 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,391
|
Did a quick comparison of some methods. I post the script as well, in case I've made an error in the hurry ...
script: Code:
mpeg2source() crop(much) orig=last ox=last.width oy=last.height jaggy=orig.separatefields().selecteven() SangN=jaggy.antialiasing().lanczosresize(ox,oy) SangNSS=jaggy.lanczosresize(ox,oy).antialiasing() tom=jaggy.tomsmocomp(1,-1,0) tomSS=jaggy.lanczosresize(ox,oy).tomsmocomp(1,-1,1).lanczosresize(ox,oy) trit=orig.tdeint(mode=0,order=1,field=1,mthreshL=-1,mthreshC=-1,type=1) tritSS=jaggy.pointresize(ox,oy).tdeint(mode=0,order=1,field=1,mthreshL=-1,mthreshC=-1,type=1) dble=jaggy.pointresize(ox,oy).tdeint(mode=0,order=1,field=1,mthreshL=-1,mthreshC=-1,type=1) \ .tomsmocomp(1,-1,1).lanczosresize(ox,oy) dbleS=dble.LimitedSharpen(ss_x=2.0,ss_y=1.0,Smode=3,strength=200,Lmode=2,overshoot=1) # without the dreadful subtitle commands: stackvertical( \ stackhorizontal(jaggy.lanczosresize(ox,oy).subtitle(jaggystr,size=12),orig), \ stackhorizontal(SangN,SangNSS), \ stackhorizontal(tom,tomSS), \ stackhorizontal(trit,tritSS), \ stackhorizontal(dble,dbleS) ) return last
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) Last edited by Didée; 5th October 2004 at 16:40. |
5th October 2004, 18:53 | #3 | Link | |
Registered User
Join Date: Aug 2004
Location: Italy
Posts: 45
|
Quote:
I've already done a few tests (always with a deinterlaced DV) with TomsMoComp(x,1,1), but results weren't really encouraging: with original resolution it removes almost all artefacts, but details are blurred; vice-versa with double height (good definition, but too much alias). On the contrary, TDeint+doubleheight works quite well: results are similiar to "antialiasing", but there's a little definition loss. Anyway, give a try to antialias (the last "version") with a hi-medium resolution source: this script is meant for good quality movies, that why it didn't perform well with the WB sample. |
|
6th October 2004, 03:18 | #4 | Link |
Registered User
Join Date: Jan 2002
Posts: 318
|
Looks promising but it would be really great if someone could figure out how faroujda's DCDI method works to create an avisynth plugin. I personally own 3 devices with the DCDI chip for deinterlacing and it is pretty amazing when it comes to deinterlacing, it really eliminates jaggies good and keeps alot of resolution, here is an example:
It's not that great of a sample but if you've seen DCDI in action you will see that there is nothing that can beat it right now (I think so anyway). More detailed explination here: http://www.av-outlet.com/en-us/dept_335.html |
6th October 2004, 10:25 | #5 | Link | |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,391
|
Quote:
In fact, most sources that do need antialiasing will be of not-so-impressing quality to start with - most probably they'll be of lower quality than the sample I used. And just discarding one field from a progressive sequence, as I did here, is a good simulation of common aliasing problems (capturing only one field, dumb bobbing, one field useless due to fieldblending, etc. pp.) However, your script has a couple of issues that could be improved: 1. You're offering the aa threshold for sangnom, but it is not used in the script. Your call of SangNom should read SangNom(order,aath) 2. Chroma probably is just passed through (it IS on that P-III I'm sitting at right now). Better would be: c=edgemask(...).FitY2UV() I've found that in many cases, it's better to use the luma edges for chroma also, insted of creating edges on chroma directly. If you prefer to use "native" chroma edges, then you must still write c=edgemask(... , Y=3,U=3,V=3) Else, you won't get any edges on the chroma planes at all (as in your posted script). Finally, you should write MaskedMerge(a,b,c, Y=3,U=3,V=3) AFAIK, MaskedMerge's default is to leave chroma alone, unless one specifies U|V=3. 3. As it is typical for EDI resamplers, SangNom too delivers an output that is spatially shifted from the input. This would not be a big issue ... if you would create the edgemask on the shifted frame. But you are creating it on the not-shifted input, and apply it later on the shifted output. That's not ideal. So, the declaration of "c" better should read c=b.edgemask( .. ) .. Below script addresses abovementioned issues, and includes these additional changes: - added "HQedge" [bool]. It's slower, reckognizes edges better, is more robust against noise ... and perhaps is not suited at all for this application. So, it's just for testing & playing. - normal edgemask is created on the original sized frame. HQedgemask is created on the (for sangnom) double-sized frame. Without much testing: Code:
function antialiasing( clip orig, int "th_luma", int "th_croma", string "type", int "order", int "aath", bool "HQedge") { # "th_luma" and "th_croma" affect directly the edge detection: higher values = more edges filtered # set "order = 0" for Top Field First; order = 1 --> Bottom Field First # aath = anti-aliasing strenght (default should be fine) th_luma = Default(th_luma, 20) th_croma = Default(th_croma, 20) type = Default(type, "sobel") order = Default(order, 1) aath = Default(aath, 48) HQedge = Default(HQedge, false) ox = orig.width oy = orig.height dx = orig.width * 2 dy = orig.height * 2 orig.convertToYV12() a=last b=lanczos4Resize(dx, dy).TurnLeft().SangNom(order,aath).TurnRight().SangNom(order,aath) # native chroma edges: #c=b.lanczosresize(ox,oy).EdgeMask(0, th_luma, 0, th_croma, type,Y=3,U=3,V=3) # use luma edges for chroma: c=b.lanczosresize(ox,oy).EdgeMask(0, th_luma, 0, th_croma, type,Y=3,U=1,V=1).FitY2UV() d= logic( b.DEdgeMask(0,255,0,255,"5 10 5 0 0 0 -5 -10 -5", divisor=4,Y=3,U=1,V=1) \ ,b.DEdgeMask(0,255,0,255,"5 0 -5 10 0 -10 5 0 -5", divisor=4,Y=3,U=1,V=1) \ ,"max").greyscale.levels(0,0.8,128,0,255,false).FitY2UV().lanczosresize(ox,oy) b=b.lanczosresize(ox,oy) HQedge ? MaskedMerge(a,b,d,Y=3,U=3,V=3) : MaskedMerge(a,b,c,Y=3,U=3,V=3) }
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) Last edited by Didée; 6th October 2004 at 10:29. |
|
6th October 2004, 18:36 | #6 | Link |
Registered User
Join Date: Aug 2004
Location: Italy
Posts: 45
|
@ Didée:
Thanks for your help, as you may have noticed (the 1st error was quite exemplifying ) I didn't pay too much attention on the creation of the script itself (that needs MUCH improving), rather I wanted to give an idea, i.e.: For aliasing is present only on edges, why we should filter the entire frame? And the main reason of filtering only what needs it (edges), in this case, is not speed gain (...and you should know why ), but to keep max definition. Obviously, using a bad-quality source (where there's something more than simple alias), there's no need of this, that's why I wrote that it's more suiteg for medim-good quality stuff (even if this reduces the possible applications). Anyway the EdgeDetection is tuned for sharp vids, then, if you are testing with mpeg2 samples, you should increase the threshold. Now I don't have much free time, but asap I'll test HQedge and the other settings! P.S. I don't see any difference between: c=edgemask( .. ) and c=b.edgemask( .. ).FitY2UV() Last edited by SpikeSpiegel; 6th October 2004 at 18:39. |
6th October 2004, 19:59 | #7 | Link |
Bored...
Join Date: Apr 2003
Location: Unknown
Posts: 2,812
|
Hmm...
Anti-aliasing via SangNom seems to work !!! Source SangNom Think the edge-detection is the culprit ??? -> Range is not wide enough... Btw, I thought the purpose is simple aliasing reduction !?! But it seems you wanna use it to reduce interlace-leavings... Bye Last edited by Soulhunter; 6th October 2004 at 20:26. |
6th October 2004, 20:49 | #9 | Link | ||
Registered User
Join Date: Aug 2004
Location: Italy
Posts: 45
|
Quote:
Did you use only SangNom or the anti-alias script? Quote:
|
||
6th October 2004, 21:06 | #10 | Link | |
Bored...
Join Date: Apr 2003
Location: Unknown
Posts: 2,812
|
Quote:
LanczosResize(X*2,Y*2).TurnLeft().SangNom().TurnRight().SangNom().LanczosResize(X,Y) Bye |
|
6th October 2004, 22:14 | #12 | Link | |
Bored...
Join Date: Apr 2003
Location: Unknown
Posts: 2,812
|
Quote:
Code:
before = last PointResize(width*2, height*2) ConvertToYUY2() TurnLeft() ConvertToYV12() SangNom() ConvertToYUY2() TurnRight() ConvertToYV12() SangNom() LanczosResize(width/2, height/2) MergeChroma(before) Last edited by Soulhunter; 7th October 2004 at 04:14. |
|
6th October 2004, 23:54 | #13 | Link |
Bored...
Join Date: Apr 2003
Location: Unknown
Posts: 2,812
|
Ok, a small update...
Source Lanczos->SangNom->Lanczos PointResize->SangNom->Lanczos Lanczos->SangNom->Bilinear Lanczos->SangNom->Bilinear->Unfilter(50,50) Imo the PointResize sample is sharp but shows still some aliasing as the Lanczos sample... The Bilinear/Unfilter sample looks same sharp but has near like no aliasing left !!! Code:
################################################################# X = 320 # Resolution width Y = 240 # Resolution height A = 50 # Unfilter value A B = 50 # Unfilter value B ################################################################# AviSource("C:\MovieBackups\Source.avi").ConverttoYV12() ################################################################# Before = Last LanczosResize(X*2,Y*2) ConvertToYUY2() TurnLeft() ConvertToYV12() SangNom() ConvertToYUY2() TurnRight() ConvertToYV12() SangNom() BilinearResize(X,Y) Unfilter(A,B) MergeChroma(Before) ################################################################# AnimeAntiAliasing: AAA(X,Y,A,B) Bye Last edited by Soulhunter; 7th October 2004 at 05:37. |
7th October 2004, 12:13 | #14 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,391
|
What's that, Soulhunter?
A brigade of inbetween "ConvertTo...ConvertTo...ConvertTo...", and in the end, the unprocessed original chroma is copied back. Perhaps one should throw some lsresize()'s in the mix, to make those NOPs even more valuable However, making a function out of that is pretty simple: You just have to /*whisper...whisper...whisper*/, that's all
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
7th October 2004, 14:43 | #15 | Link |
Bored...
Join Date: Apr 2003
Location: Unknown
Posts: 2,812
|
EDIT: Replaced the old function with a simplified new one
Code:
# _______________________________________________________ # # SAA | Simple Antialiasing # _______________________________________________________ # # Simplicity by Soulhunter... \m\ ^_^ /m/ # _______________________________________________________ # # # Requirements: # # SangNom.dll # 100GHz CPU # # Function SAA(Clip Clp,Int"SS",Bool"CP") { OX = Clp.Width OY = Clp.Height SS = Default(SS,2) CP = Default(CP,True) Clp = Clp.IsYV12() ? Clp : Clp.ConvertToYV12() Clp.PointResize(OX*SS,OY*SS).SangNom().TurnRight() \ .SangNom().TurnLeft().BilinearResize(OX,OY) CP ? Last : MergeChroma(Clp) Return(Last) } Last edited by Soulhunter; 29th August 2006 at 09:31. Reason: Update! |
8th October 2004, 19:07 | #16 | Link | |
Registered User
Join Date: Aug 2004
Location: Italy
Posts: 45
|
Quote:
this way, the base clip is still in the original position, then, overlaying base & overlay clip (shifted), I get artefacts as well (=alias on one side of edges). If the SangNom's "shift vector" is (1,1) (as it seems to be), I should use something like: orig = clip.ConvertToRGB() clp = orig.crop(0,1,-1,0).addborders(0,1,1,0).ConvertToYV12() shift = orig.crop(1,0,0,-1).addborders(0,1,1,0).ConvertToYV12() ... a= clp b= shift.Lanczos4Resize(dx, dy).TurnLeft()... c= clp.EdgeMask(0, th_luma, 0, th_croma, ....) But, if I wrote "There's still a great problem", there must be a reason : actually the "shift vector" shouldn't have integer components (it's more like (1/2,1/2) ), then...I don't see any solution! EDIT1: fixed crop&addborders Last edited by SpikeSpiegel; 9th October 2004 at 09:50. |
|
8th October 2004, 19:18 | #17 | Link |
brainless
Join Date: Mar 2003
Location: Germany
Posts: 3,653
|
I don't see any solution!
upsize using with something better than pointresize to 2x & 2y. then shift by the desired vector and to a point-downsize to the original resolution.
__________________
Don't forget the 'c'! Don't PM me for technical support, please. |
9th October 2004, 09:45 | #18 | Link | |
Registered User
Join Date: Aug 2004
Location: Italy
Posts: 45
|
Quote:
ox = clip.width oy = clip.height qx = clip.width * 4 qy = clip.height * 4 orig = clip.ConvertToRGB() clp = orig.Lanczos4Resize(qx, qy).crop(0,1,-1,0).addborders(0,1,1,0).ConvertToYV12().LanczosResize(ox, oy) shift = orig.Lanczos4Resize(qx, qy).crop(1,0,0,-1).addborders(0,1,1,0).ConvertToYV12().LanczosResize(ox, oy) ...but still I can't find the right vector (that maybe has different components, like (x,y) ) and the speed loss is already excessive. I suppose that a fast "shiftVector()" plugin doesn't already exist, isn't it? Last edited by SpikeSpiegel; 9th October 2004 at 09:57. |
|
9th October 2004, 15:39 | #19 | Link | |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,391
|
Quote:
But you can take either GeneralConvolution() or MaskTool's DEdgeMask(), together with pen & paper, and produce the frame shifts yourself through an operation on a 3x3 kernel: Code:
0 0 1 0 2 0 0 0 0 Since this is simple bilinear sampling, you'll loose sharpness as well. Perhaps upsample first to 2x with lanczos, shift by 2x of the initial target vector, and downsize back.
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
|
10th October 2004, 13:10 | #20 | Link | |
Registered User
Join Date: Aug 2004
Location: Italy
Posts: 45
|
Quote:
throw away PointResize. The "culprit" wasn't SangNom: using lanczos4resize to upsize, there's no shift at all. Thanks anyway, this method is really faster and I'm sure it will be useful in other situations. |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|