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. |
10th November 2008, 13:04 | #1 | Link |
Registered User
Join Date: Dec 2002
Location: UK
Posts: 1,673
|
Sharpest HDV>DVD workflow?
I'm trying to nail the conversion from HDV>DVD.
I'm happy with most of it, but the thing I can't crack is making the output look really sharp without ringing. Most of the BBC HD content, when shown in SD, has a "super sharp" kind of look to it. I know they're using slightly better cameras, lenses etc - but the problem I have isn't lack of sharpness, it's ringing when I do sharpen. In this thread... http://forum.doom9.org/showthread.php?t=140776&page=2 ...there was a suggestion to use ImageMagik for re-sizing, but I don't understand how to include this into an AVIsynth workflow. So far, I'm trying things like this... Code:
# 1440x1080i50 source, bobbed already, so now progressive # resize: spline36resize(704,576) # sharpen horizontally: limitedsharpenfaster().Sharpen(0.5,0.0) # prevent interlace twitter: Blur(0.0,1.0).Sharpen(0.0,0.5) # re-interlace: assumetff() separatefields().SelectEvery(4,0,3).Weave() Here an alternative - I think the approach is silly, but it rings slightly less while looking sharper... Code:
# 1440x1080i50 source, bobbed already, so now progressive # sharpen HD: limitedsharpenfaster() limitedsharpenfaster() limitedsharpenfaster() # denoise HD: mc_spuds() # resize: spline36resize(704,576) limitedsharpenfaster() # prevent interlace twitter: Blur(0.0,1.0).Sharpen(0.0,0.5) # re-interlace: assumetff() separatefields().SelectEvery(4,0,3).Weave() I understand filtering very well, so I know that sharpness, ringing, and aliasing are all trade-offs - however, lsf manages to cheat the compromise between sharpness and ringing up to a point. The problem with anamorphic 16x9 PAL is that the pixels are so stretched horizontally than any softness or ringing in the horizontal direction is magnified greatly. Any suggestions? Cheers, David. |
10th November 2008, 13:25 | #2 | Link |
Registered User
Join Date: Dec 2002
Location: UK
Posts: 1,673
|
Here are some images showing:
the original HD SD without sharpening SD with lsf+sharpen SD with lsf four times! http://rapidshare.de/files/40876150/sharpening.zip.html Cheers, David. |
10th November 2008, 16:16 | #3 | Link |
x264aholic
Join Date: Jul 2007
Location: New York
Posts: 1,752
|
Read me: link
Rambling: There was a thread on this problem a while back, I can't remember where but if you do search you'll find it (I have to sift through the posts a bit to find it for you). I don't remember the details perfectly, but it has to do with the fact that resizing by that huge of a step makes it hard to represent all the details present in the 1920/1440x1080 frame in a 720x480 frame without introducing artifacts. You usually get aliasing or a soft picture. In your case, when you resharpen the soft image to get back that "sharp" look of HD, you end up introducing ringing. I do know that M4G recommended using a FIR filter to filter out frequencies that were too strong (caused aliasing). So you can removing the aliasing + sharpen without ringing if you do that. I'll look around and link it when I find it.
__________________
You can't call your encoding speed slow until you start measuring in seconds per frame. Last edited by Sagekilla; 10th November 2008 at 16:22. |
10th November 2008, 17:06 | #4 | Link |
Registered User
Join Date: Dec 2002
Location: UK
Posts: 1,673
|
Sagekilla,
Thanks, but I was in that thread, and other recent ones too. This has come up quite a lot lately. Most of those discussions were about how to make things sharp in the vertical dimension while avoiding interlaced flicker. I'm quite happy with my results in that respect. It's the horizontal direction where I want something better. That's why I started a new thread. The H/V resolution discrepancy is worse for "PAL" than for "NTSC" (1.45 PAR instead of 1.21 PAR), which exacerbates the problem. Cheers, David. Last edited by 2Bdecided; 10th November 2008 at 17:09. |
10th November 2008, 18:29 | #5 | Link |
Registered User
Join Date: Feb 2004
Posts: 1,348
|
This is the best I could manage, using an absurdly slow script, and oversharpening the source by a karge margin, then using an extremely sharp interpolator. It dowsn't look much sharper then your lsf X4 image unless you view it fullscreen with mpc or something similar, in which case it looks much sharper.
This is a great example of crap in crap out. The source is very blurry, and you can fix this to an extent, but it will never look as good as something that was never blurry. if you are willing to go well into sub 1fps range to get this source to look sharp, I'll post the script, but I don't want to waste time trying to find all the dependencies etc. when that probably isn't the case. |
10th November 2008, 19:14 | #6 | Link | |||
Registered User
Join Date: Dec 2002
Location: UK
Posts: 1,673
|
Quote:
Quote:
I think tgmc makes it a little softer than with mcbob. Here's the same frame mcbob, and another frame with both... http://rapidshare.de/files/40878996/...ning2.zip.html Quote:
I almost daren't ask (I've seen your ~1fps sharpening scripts before!) but can you share? Don't worry about unpicking dependencies just yet if it's too painful - just give me a clue what you're doing. I think your result will be way too sharp vertically for interlaced display, but that's OK - I can easily blur it vertically! It looks a little grainy too, but a little grain might be OK. It's the fact you've made the SD version look far more detailed than the HD version that's quite amazing. Cheers, David. |
|||
10th November 2008, 22:00 | #7 | Link |
Registered User
Join Date: Feb 2004
Posts: 1,348
|
Well, the script itself is pretty regular, its the functions I used.
Code:
ImageReader("C:\Documents and Settings\\Desktop\sharpening2\4520mcbob.jpg") spline36resize(1408, 1152).converttoyv12()# automttap3 works best when resizing by factors of 2, though it can resize by any factor aslong as at no point the image is less then 144*144 pizels limitedsharpenfaster(smode=2, strength=400, ss_x=1, ss_y=1)#modified to use a different sharpening kernel sssharp(denoise=0, iter=2)#in the avisynth development forum, absurdly slow sharpener automttap3(704, 576)#a sub function of an interpolation script, uses backprojection to adaptively choose the number of taps to use on a per source pixel pasis, avoidsmost ringing while otherwise performing similarly to high tap lanczos automttap3 Code:
function automttap3(clip clp, int "dx", int "dy", int "mtaps3", int "thresh"){ c = clp #g = clp.converttoy8() dx = default(dx, c.width*2) dy = default(dy, c.height*2) mtaps3 = default(mtaps3, 1) thresh = default(thresh, 256) t1 = lanczosresize(clp, dx, dy, taps=1) t2 = lanczosresize(clp, dx, dy, taps=2) t3 = lanczosresize(clp, dx, dy, taps=3) t4 = lanczosresize(clp, dx, dy, taps=4) t5 = lanczosresize(clp, dx, dy, taps=5) t6 = lanczosresize(clp, dx, dy, taps=9) t7 = lanczosresize(clp, dx, dy, taps=36) m1 = mt_makediff(clp, lanczosresize(t1, clp.width, clp.height, taps=1), u=1, v=1) m2 = mt_makediff(clp, lanczosresize(t2, clp.width, clp.height, taps=1), u=1, v=1) m3 = mt_makediff(clp, lanczosresize(t3, clp.width, clp.height, taps=1), u=1, v=1) m4 = mt_makediff(clp, lanczosresize(t4, clp.width, clp.height, taps=2), u=1, v=1) m5 = mt_makediff(clp, lanczosresize(t5, clp.width, clp.height, taps=2), u=1, v=1) m6 = mt_makediff(clp, lanczosresize(t6, clp.width, clp.height, taps=3), u=1, v=1) m7 = mt_makediff(clp, lanczosresize(t7, clp.width, clp.height, taps=6), u=1, v=1) cp1 = mt_merge(t1.blur(1.42), t2, lanczosresize(mt_lutxy(m1, m2, "x 128 - abs y 128 - abs - "+string(thresh)+" *", u=1, v=1), dx, dy, taps=mtaps3)) m100 = mt_makediff(clp, bilinearresize(cp1, clp.width, clp.height), u=3, v=3) cp2 = mt_merge(cp1, t3, lanczosresize(mt_lutxy(m100, m3, "x 128 - abs y 128 - abs - "+string(thresh)+" *", u=1, v=1), dx, dy, taps=mtaps3)) m101 = mt_makediff(clp, bilinearresize(cp2, clp.width, clp.height), u=3, v=3) cp3 = mt_merge(cp2, t4, lanczosresize(mt_lutxy(m101, m4, "x 128 - abs y 128 - abs - "+string(thresh)+" *", u=1, v=1), dx, dy, taps=mtaps3)) m102 = mt_makediff(clp, bilinearresize(cp3, clp.width, clp.height), u=3, v=3) cp4 = mt_merge(cp3, t5, lanczosresize(mt_lutxy(m102, m5, "x 128 - abs y 128 - abs - "+string(thresh)+" *", u=1, v=1), dx, dy, taps=mtaps3)) m103 = mt_makediff(clp, bilinearresize(cp4, clp.width, clp.height), u=3, v=3) cp5 = mt_merge(cp4, t6, lanczosresize(mt_lutxy(m103, m6, "x 128 - abs y 128 - abs - "+string(thresh)+" *", u=1, v=1), dx, dy, taps=mtaps3)) m104 = mt_makediff(clp, bilinearresize(cp5, clp.width, clp.height), u=3, v=3) cp6 = mt_merge(cp5, t7, lanczosresize(mt_lutxy(m104, m7, "x 128 - abs y 128 - abs - "+string(thresh)+" *", u=1, v=1), dx, dy, taps=mtaps3)) m105 = mt_makediff(clp, bilinearresize(cp6, clp.width, clp.height), u=3, v=3) return(mergechroma(cp6, spline36resize(clp, dx, dy), 1))} Code:
# LimitedSharpen() ( a modded version, 29 Oct 2005 ) # # A multi-purpose sharpener by Didée # # # Changes in this mod: # # - RemoveGrain >= v0.9 IS REQUIRED!! # ================================== # # - Smode=4 / sometimes does the magic ;-) # - a separate "undershoot" parameter, to allow for some line darkening in comic or Anime # - Lmode=3 / on edges, limited sharpening with zero OS & US. On not-edges, limited sharpening with specified OS + LS # - "soft" acts different now: no more boolean true/false, but instead integer 0 - 100 (or -1 -> automatic) # instead of blurring before finding minima/maxima, it now softens the "effect-of-sharpening" # - edgemode=-1 now shows the edgemask. (scaling still not implemented :p ) # ## - MODIFIED version using MaskTools 2.0 #modified to use unsharp (from variable blur plugin) for smode2 function LimitedSharpenFaster( clip clp, \ float "ss_x", float "ss_y", float "vary", float "varc", \ int "dest_x", int "dest_y", \ int "Smode" , int "strength", int "radius", \ int "Lmode", bool "wide", int "overshoot", int "undershoot", \ int "soft", int "edgemode", bool "special", \ int "exborder" ) { ox = clp.width oy = clp.height vary = default(vary, 1) varc = default(varc, vary) Smode = default( Smode, 3 ) ss_x = (Smode==4) \ ? default( ss_x, 1.25) \ : default( ss_x, 1.5 ) ss_y = (Smode==4) \ ? default( ss_y, 1.25) \ : default( ss_y, 1.5 ) dest_x = default( dest_x, ox ) dest_y = default( dest_y, oy ) strength = (Smode==1) \ ? default( strength, 160 ) \ : default( strength, 100 ) strength = (Smode==2&&strength>100) ? 100 : strength radius = default( radius, 2 ) Lmode = default( Lmode, 1 ) wide = default( wide, false ) overshoot = default( overshoot, 1) undershoot= default( undershoot, overshoot) softdec = default( soft, 0 ) soft = softdec!=-1 ? softdec : sqrt( (((ss_x+ss_y)/2.0-1.0)*100.0) ) * 10 soft = soft>100 ? 100 : soft edgemode = default( edgemode, 0 ) special = default( special, false ) exborder = default( exborder, 0) #radius = round( radius*(ss_x+ss_y)/2) # If it's you, Mug Funky - feel free to activate it again xxs=round(ox*ss_x/8)*8 yys=round(oy*ss_y/8)*8 smx=exborder==0?dest_x:round(dest_x/Exborder/4)*4 smy=exborder==0?dest_y:round(dest_y/Exborder/4)*4 clp.isYV12() ? clp : clp.converttoyv12() ss_x != 1.0 || ss_y != 1.0 ? last.lanczos4Resize(xxs,yys) : last tmp = last edge = mt_logic( tmp.mt_edge(thY1=0,thY2=255,"8 16 8 0 0 0 -8 -16 -8 4") \ ,tmp.mt_edge(thY1=0,thY2=255,"8 0 -8 16 0 -16 8 0 -8 4") \ ,"max") .mt_lut("x 128 / 0.86 ^ 255 *") #.levels(0,0.86,128,0,255,false) tmpsoft = tmp.removegrain(11,-1) dark_limit1 = tmp.mt_inpand() bright_limit1 = tmp.mt_expand() dark_limit = (wide==false) ? dark_limit1 : dark_limit1 .removegrain(20,-1).mt_inpand() bright_limit = (wide==false) ? bright_limit1 : bright_limit1.removegrain(20,-1).mt_expand() minmaxavg = special==false \ ? mt_average(dark_limit1, bright_limit1) \ : mt_merge(dark_limit,bright_limit,tmp.removegrain(11,-1),Y=3,U=-128,V=-128) dfg = MT_lutxy(last, fq2d("bcl", 256, 0, gamma=1, rescale=false), "y "+string(round(strength/100))+" * 127 + X + 127 -", u=2, v=2).invert #smode 2 is the modification Str=string(float(strength)/100.0) normsharp = Smode==1 ? MT_lutxy(dfg, fq2d(dfg, "bcl", 256, 0, gamma=1, rescale=false), "y "+string(round(strength/100))+" * 127 + X + 127 -", u=2, v=2).invert \ : Smode==2 ? unsharp(vary=1.5, varc=1.5, strength=1) \ : Smode==3 ? mt_lutxy(tmp,minmaxavg,yexpr="x x y - "+Str+" * +") \ : mt_lutxy(tmp,tmpsoft,"x y == x x x y - abs 16 / 1 2 / ^ 16 * "+Str+ \ " * x y - 2 ^ x y - 2 ^ "+Str+" 100 * 25 / + / * x y - x y - abs / * + ?") OS = string(overshoot) US = string(undershoot) mt_lutxy( bright_limit, normsharp, yexpr="y x "+OS+" + < y x y x - "+OS+" - 1 2 / ^ + "+OS+" + ?") mt_lutxy( dark_limit, last, yexpr="y x "+US+" - > y x x y - "+US+" - 1 2 / ^ - "+US+" - ?") Lmode==1 ? mt_clamp(normsharp, bright_limit, dark_limit, overshoot, undershoot) : last normal = last zero = mt_clamp(normsharp, bright_limit, dark_limit, 0,0) Lmode==3 ? mt_merge(normal,zero,edge.mt_inflate()) : normal edgemode==0 ? last \ : edgemode==1 ? mt_merge(tmp,last,edge.mt_inflate().mt_inflate().removegrain(11,-1),Y=3,U=1,V=1) \ : mt_merge(last,tmp,edge.mt_inflate().mt_inflate().removegrain(11,-1),Y=3,U=1,V=1) AMNT = string(soft) AMNT2 = string(100-soft) sharpdiff=mt_makediff(tmp,last) sharpdiff2=mt_lutxy(sharpdiff,sharpdiff.removegrain(19,-1), \ "x 128 - abs y 128 - abs > y "+AMNT+" * x "+AMNT2+" * + 100 / x ?") soft==0 ? last : mt_makediff(tmp,sharpdiff2) (ss_x != 1.0 || ss_y != 1.0) \ || (dest_x != ox || dest_y != oy) ? lanczos4Resize(dest_x,dest_y) : last ex=blankclip(last,width=smx,height=smy,color=$FFFFFF).addborders(2,2,2,2).coloryuv(levels="TV->PC") \.blur(1.3).mt_inpand().blur(1.3).bicubicresize(dest_x,dest_y,1.0,.0) tmp = clp.lanczos4Resize(dest_x,dest_y) clp.isYV12() ? ( exborder==0 ? tmp.mergeluma(last) \ : mt_merge(tmp,last,ex,Y=3,U=1,V=1) ) \ : ( exborder==0 ? tmp.mergeluma(last.converttoyuy2()) \ : tmp.mergeluma( mt_merge(tmp.converttoyv12(),last,ex,Y=3,U=1,V=1) \ .converttoyuy2()) ) (edgemode!= -1) ? last : edge.lanczos4Resize(dest_x,dest_y).greyscale return last } Last edited by *.mp4 guy; 21st November 2008 at 03:33. |
11th November 2008, 21:42 | #10 | Link |
brainless
Join Date: Mar 2003
Location: Germany
Posts: 3,653
|
try this little detail enhancer:
x1=subtract(source.deen("a2d",5,4,0),source) result=subtract(source,x1) 5 is spatial radius 4 is luma threshold 0 is chroma threshold (you usually don't want to enhance nonexistent chroma detail, i.e. noise) this script will only amplify faint detail/textures while leaving edges alone.
__________________
Don't forget the 'c'! Don't PM me for technical support, please. |
20th November 2008, 17:11 | #11 | Link |
Registered User
Join Date: Dec 2002
Location: UK
Posts: 1,673
|
Thank you scharfus_brain - I'm sure I'll find a use for that, but the effect of subtracting deen is more subtle than I was looking for in this case.
mp4 guy - I love this script (apart from the speed!). btw, the modified LSF above crashes on start-up for me, so I'm using my old version for now. The error I'm getting is ": expected at start of line 88" - which is strange, given that there is one! I don't think I have the function unsharp - remind me what that's part of again please? I need a new PC! Cheers, David. |
20th November 2008, 18:32 | #12 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,431
|
Quote:
Code:
\ : Smode==2 ? unsharp(vary=1.5, varc=1.5, strength=1)#modification EDIT: (Or if using v2.58, change to /* ... */ which I think is allowed) Last edited by Gavino; 20th November 2008 at 18:34. |
|
21st November 2008, 02:39 | #14 | Link |
likes to tinker
Join Date: Jan 2004
Location: girt by sea
Posts: 635
|
I have the same "softening" issue for PAL 1080i25 -> 576i25 DVD. With respect to post #1 and resizing interlaced ... I'd thought this was the quick way to resize without having to bob and still get a reasonable output/speed tradeoff (ignoring sharpening for the moment) ?
Code:
AssumeFPS(25) AssumeTFF() Global NewHeight=576 Global NewWidth=720 # PURE VERSION PER http://forum.doom9.org/showthread.php?p=1185790#post1185790 SetMTmode(mode=2,threads=4) # mode=2 for temporal multi-threading (interleaved frames) SeparateFields() #LimitedSharpenFaster(smode=4,strength=100) # doesn't seem to do much if done here Shift = (GetParity() ? -0.25 : 0.25) * (Height()/Float(NewHeight/2)-1.0) E = SelectEven().Spline36resize(NewWidth, NewHeight/2, 0, Shift) O = SelectOdd( ).Spline36resize(NewWidth, NewHeight/2, 0, -Shift) Ec = SelectEven().Spline36Resize(NewWidth, NewHeight/2, 0, 2*Shift) Oc = SelectOdd( ).Spline36Resize(NewWidth, NewHeight/2, 0, -2*shift) Interleave(E, O) IsYV12() ? MergeChroma(Interleave(Ec, Oc)) : Last #LimitedSharpenFaster(smode=4,strength=100) # doesn't seem to do much if done here either Weave() Distributor() # use this when using HC and SetMTmode, per http://forum.doom9.org/showthread.php?p=1063622#post1063622 Just wondering the reason for a modified kernel ? Last edited by halsboss; 21st November 2008 at 02:44. |
21st November 2008, 08:08 | #16 | Link | |
likes to tinker
Join Date: Jan 2004
Location: girt by sea
Posts: 635
|
I must be missing something with that new limitedsharpenfaster - as far as I can tell, for smode=2 it
Just wondering how to interpret Quote:
Last edited by halsboss; 21st November 2008 at 08:52. |
|
21st November 2008, 09:16 | #17 | Link | |
Registered User
Join Date: Feb 2004
Posts: 1,348
|
Quote:
2 - probably an oversight on my part 3 - see 2 4 - this combined with 1 results in a slightly larger, much more accurate sharpening kernel, which produces different results then the sharpen function. The sharpen function aplieas a simple and inaccurate 3X3 sharpening FIR filter, that uses in total 5 pixels (iirc), the unsharp function, applies an accurate gaussian distribution derived unsharp mask that accurately uses many pixels, even at relatively low radii. The differences aren't very big, but its one of the versions of lsf that I use, and its what was used to produce the screenshot, so I had to post it when I posted the script. 5 - No. |
|
21st November 2008, 10:20 | #18 | Link | |
likes to tinker
Join Date: Jan 2004
Location: girt by sea
Posts: 635
|
OK, thanks. Re 5. would this
Quote:
If it doesn't sharpen, is its advantage that it mitigates ringing then or are there other benefits too ? Last edited by halsboss; 21st November 2008 at 10:30. |
|
21st November 2008, 10:43 | #19 | Link |
likes to tinker
Join Date: Jan 2004
Location: girt by sea
Posts: 635
|
Wow. Using that seems to slow post 14 script down from
pass 1 encoding time: 0:00:32 (32.16 s) fps: 23.3 to pass 1 encoding time: 0:04:18 (258.01 s) fps: 2.9 For a footy game, the convert time has gone from ~3h to ~30h The file size has gone up by a few % so it's done something. Now I have 2 .mpv's how can I compare them (it's late and my eyes are going). Last edited by halsboss; 21st November 2008 at 10:47. |
21st November 2008, 12:07 | #20 | Link |
Registered User
Join Date: Feb 2004
Posts: 1,348
|
making the script compatable with crops/pixel shifts is going to be much more complicated then that.
its benefit is that it gives you the interpolative performance of high tap lanczos (wich is very good at eliminating aliasing, and maintaining detail) while greatly reducing the amount of ringing. Unless your source is extremely sharp, and causes other interpolators to leave aliasing behind, or blur detail, then you shouldn't use it. It was usefull in this case because I had to oversharpen the source so much, many of the lines became extremely (over)sharp and would leave aliasing behind when using other interpolators to downsize the image, in this case automttap3 was usefull, because it could remove the aliasing while maintaing (slightly) better sharpness, which is not something that many filters can do. The vast majority of images won't cause problems when using normal interpolators to downsize an image, so it is only usefull when your source is tough, or you want every last drop of detail at your final resolution, without worrying about speed. If you really want to see what it does, take a really sharp, high res image, downsize it with a a regular resizer by 2x, then enlarge by 2x, then compare it to the same procedure, using automttap3 instead. for your football game, if it was sufficiently high res, and sufficiently sharp, you should be able to see a reduction in aliasing on lines, and extremely fine detail will be preserved a little better. Last edited by *.mp4 guy; 21st November 2008 at 13:19. |
Thread Tools | Search this Thread |
Display Modes | |
|
|