Log in

View Full Version : How to do thresholded sharpening?


Pages : 1 [2]

Didée
1st May 2004, 15:37
Originally posted by Didée
Did I forget something? Surely I forgot something. But I can't remember what it was :)
Ah, my memory started working again.

For the above posted version of LimitedSharpen(), it is absolutely necessary to use the latest version of the MaskTools! (Currently: v1.4.16)

With a lower version of MaskTools, the function will work without throwing an error, and without having any useful effect ;)
It's because a bug (multiple-instances-bug?) in the Logic() function was fixed in v1.4.16.

BTW, yesterday I applied the following to a DVB capure (eXistenZ):

ConvertToYUY2().PixieDust(2).ConvertToYV12()

LimitedSharpen(ss_x=1.75,ss_y=1.75,strength=127,radius=1,power=2.5,soft=false)Yummy!

- Didée

Manao
1st May 2004, 18:43
It's because a bug (multiple-instances-bug?)No it was the stupid copy & paste bug while programming the mode "min" and "max" which was making them totally uneffective ( result = ( src1 < src2 ) ? src1 : src1; ... ).

The funny thing was that the bug wasn't present in the optimized version of the filter, but another bug prevented it from being used ( I love such combo bugs :p )

Soulhunter
1st May 2004, 19:11
Ok, here is my first small playaround with LimitedSharpen... ;)


Source:

The Matrix - Lobby Shootout / 3:07 min. @ 25fps / 1024x576 pix.


Settings:

XviD v1 RC4 (Koepis)

Fixed Quant 2 (VHQ1)

I-frame interval = 250

Matrix = Soulhunter v3

BVOP's = 1 / 1 / 1


Results:

No filters (resized only)
Size = 154 MB / Time = 05 min.

SharpResize (defaults)
Size = 162 MB / Time = 65 min.

LimitedSharpen (defaults)
Size = 246 MB / Time = 23 min.

LimitedSharpen (strength, 100)
Size = 215 MB / Time = 23 min.

LimitedSharpen (strength, 50)
Size = 187 MB / Time = 23 min.

LimitedSharpen (radius, 1)
Size = 238 MB / Time = 23 min.

LimitedSharpen (overshoot, 2)
Size = 246 MB / Time = 23 min.

LimitedSharpen (power, 2.0)
Size = 285 MB / Time = 23 min.

LimitedSharpen (soft, false)
Size = 272 MB / Time = 23 min.


Note: For all encodes except SharpResize one, Lanczos was used for the resizing !!!

Note: Resizing was always done after the filtering !!!

Note: I take no responsibility for the trueness of the results !!!


More tests n' comments on the visual impression will follow... ;)


Bye

Soulhunter
4th May 2004, 18:47
Ok, visual impression now...

I really hate it to say, but after watching the encodes I was disappointed !!!

Nah, maybe a bit too harsh... :p

It simply does not what I thought it would do !!!

Thought it would sharpen detail/edges without amplifying noise too much... :rolleyes:

But it does amplify noise very much !!!

Yeah sure, de-noising would help with this problem... ;)



Idea:

Sounds maybe a bit dumb, but could you tweak the script to amplify noise even more ???

Coz we could use it in a complete other way then !!!

UnSmooth(Smoother="LimitedSharpen") already gives some sort of (poor) de-noising... :D

Or even a combo with some sort of edge-remover instead of amplifier ???


Bye

Didée
5th May 2004, 11:34
Originally posted by Soulhunter
Ok, visual impression now...

I really hate it to say, but after watching the encodes I was disappointed !!!

Nah, maybe a bit too harsh...

It simply does not what I thought it would do !!!Ok, visual impression now...

[/start copy'n'paste]

Ok, let's answer this now...

I really hate it to say, but after reading your comments I was disappointed !!!

Nah, maybe a bit too harsh...

I simply thought my explanations have been clear enough !!! But obviously, they were not !!!

[/end of copy'n'paste] ;)


I really start thinking about doing the following for my 'experimental' scripts:

- If the function is called with default values, this gets detected, and the function will print, in big orange letters,

"ALERT! Usage of default values detected! DONT EVER DO THAT!"

onto the clip ... :D


Okay, enough joking now. Lets get serious.

What you were experiencing, was exactly the expected behaviour, Soulhunter. Well, more or less.
You missed the fact that LimitedSharpen() provides two totally different sharpening effects, and *tries* to also enable a usage somewhere inbetween these two modes.

I'll try it once more:


- power = 0.0

This is the mode that will do edge-condensing only, and nothing else. Like shown in the screenshot of Gollum. ;)


- power >= 1.0 (1.0 <= power <= 8.0)

This mode delivers traditional sharpening, with some additional twists. The effect of edge condensing will be much weaker - it will do normal sharpening/contrast enhancing with as little oversharpening (edge halos) as possible. But this has nothing to do with noise! Noise will be enhanced, too, just like any normal sharpening will do!!

power = 1.0 is exactly normal sharpening (but slower)
power = 8.0 is edge-condensing only (almost), no contrast enhancement
In-between values are in between.


Bottom line(s):

Sharpening a.k.a. contrast enhancement *without* noise reduction is always a bad idea, of course. The above script is a script for sharpening, not more. It doesn't try to be sort of an integrated solution doing *all* the work for you! For that purpose, we have iiP() ...


My posts always tend to get long, I know. Sorry for that. I also understand that some might be bothered too much with reading all that stuff.

The thing is that I try to explain what is going on in my scripts. It's a pity then, after doing thoroughly explanations, to find that the explanations didn't reach the audience, people instead through any stuff at the defaults, afterwards stating "blah, that's crap", totally missing the possibilities of adapting the parameters.

EDIT: the last sentence refers not to Soulhunter!


- Didée

Dali Lama
5th May 2004, 17:06
Originally posted by Didée
a pity then, after doing thoroughly explanations, to find that the explanations didn't reach the audience, people instead through any stuff at the defaults, afterwards stating "blah, that's crap", totally missing the possibilities of adapting the parameters.


Didée, I understood you very well the first time. Consider the possibility that you notice people who don't understand you, because they usually post about it in hope for clarification. Those that do understand won't feel as compelled to say, "Yes, I do understand" in a post. Perhaps more people understand than not?

Best Wishes,

Dali

Soulhunter
5th May 2004, 18:01
Originally posted by Didée
I really start thinking about doing the following for my 'experimental' scripts:

- If the function is called with default values, this gets detected, and the function will print, in big orange letters,

"ALERT! Usage of default values detected! DONT EVER DO THAT!"

onto the clip ... :D
But I used the default settings only 1x time, all other tests where done with other settings... :(

But yes, this edge-enhancement seems to work more or less !!!


Just thought the sharpening should work in a more "intelligent" way... :confused:

Would it be somehow possible to prevent noise amplification (without de-noising) ???


Anyhow, I will stay with IIP for this kind of stuff... ;)


Bye

koszopal
6th May 2004, 08:47
@dideee
maybe little [OT] but will be any new version of iip ?
koszopal
PS i've thought that limitedsharp script its kinda a repleacement for iip :)

Mug Funky
7th May 2004, 16:16
i believe i found it in 3 other threads as well.

hehe.. just call me PIMP. i might do that same search and update them all.

a question occurs to me: could this filtering concept be used to remove haloes? considering they're present on so much stuff, it would be useful to throw another technique at it.

i've got R4 Akira, and it's a great copy, but it's got haloing and thus it has amplified noise. would it be possible to adapt this edge-limiting to something like this?

i might see if i can come up with a proof-of-concept for it, but don't be holding your breath. i'll be out of town a while starting next week, and i doubt there'll be much of an internet connection (to say nothing of avisynth availability). there's not even mobile/cellphone reception where i'm going (arguably a very good thing).

Didée
8th May 2004, 01:57
That's already an old story (http://forum.doom9.org/showthread.php?s=&threadid=74003&highlight=blinddehalo), Mug Funky ;)

The only thing that needs to be adjusted there is the brightness of the edgemask. With the values I used there (they were tweaked for a particular source), the overall effect is too weak. One or two numbers to change, that's all.

I thought I'd wait for anyone saying "hey, that script does nothing, what's up here?" before correcting it. Well, I'm patient ...


koszopal:

Something like that is what I have in mind, sure. But it's not so easy as it may seem.
In the meantime, feel free to implement it yourself :D


I am still at this stuff, but actually I have also some real encoding work to do. One can only do so much a day.


- Didée

pieter1976
19th May 2004, 15:30
Didée

Do you implement filters yourself?
If you do Could you implement my code in a plugin.
It is very small.
I can't do it because i don't know much about C++.
What do you think about the code?

code (http://home.zonnet.nl/pieterboots/code.htm)

Didée
19th May 2004, 16:05
Unfortunately not. My knowledge about compilers comes to its end with spelling the word - and approx. 12 years ago, for some specific reasons I decided to stop with coding, forever.

- Didée

Si
20th May 2004, 00:04
You know - we really could do with a parser that works at the pixel/byte level so people with ideas can try them out without having to learn C(++)

Any super coder available?

Simon

scharfis_brain
20th May 2004, 01:19
I can mind had read about a virtualdub filter that was able being directly programmed with something imperative like C on the per pixel level....

maybe someone could dig this thing out of the net and convert it for usage with AVISynth ?!?

Didée
14th August 2004, 20:02
LimitedSharpen is not dead.

It is alive, bursting with health, and better than ever.

There have been a lots of changes, but I'm currently too lazy to describe them all. For now, the comments in the header must suffice ;)

But one fact should be pointed out: Through the usage of MaskTool's new yv12LUTxy function (:D), LimitedSharpen is now pretty fast!

The following function call will give an output that is almost identical to the good old 4*-supersampled-XSharpen() treatment, except for that it runs 2.0~2.5 times faster: :eek:

LimitedSharpen(ss_x=2.0,ss_y=2.0,Smode=2,strength=100,Lmode=1,overshoot=1,wide=false,soft=false,radius=1,edgemode=0)
I think I'll make a thread in AviSynth Usage for this one.


The script: (MaskTools >= v1.5.1 required)
# LimitedSharpen()
#
# Multi-purpose sharpener for
# - edge condensing
# - detail contrast enhancement without oversharpening or edge halos
#
# 04.05.2004 - 'edgemode' re-implemented, now all three options (on edge [1], on NOT edge [2], disable [0])
# 05.08.2004 - Big speed-up by implementation with MaskTool's new function "yv12LUTxy()" (my proposal)
# - removed the "power" limiting. Never liked it much.
# - no more scaling of "radius" with the ss_x|y values. I like it more the 'direct' way.
# - "mode" Parameter added: mode=1 == uses UnsharpMask() for sharpening
# mode=2 == uses Sharpen() for sharpening. "strength" then is internally
# divided by 100, and "radius" then has no effect.
# 11.08.2004 - added "wide" parameter (boolean): "true" takes the min|max from a 5x5 neighborhood for limiting.
# "false" works, as formerly, on a 3x3 neighborhood
# - added "Lmode" parameter: "1" does hard limiting as formerly:
# if [sharpen] is within [min-OS,max+OS], take it. Else, use (min|max).
# "2" will replace sharpen's effective overshoot with sqrt(overshoot).
# - renamed "mode" to "Smode": "1" = UnsharpMask / "2" = Sharpen / "3" = MinMaxSharpen
# Smode=3 will, instead of sharpening the current pixel against the average
# of its 8 neighbors, sharpen it against average(min,max). It's less exact
# in theory (blurred corners!), but results in stronger overall sharpening.
# Also, it is less prone to enhancing pre-existing crap like DCT noise

function LimitedSharpen( clip clp,
\ float "ss_x", float "ss_y",
\ int "Smode" , int "strength", int "radius",
\ int "Lmode", bool "wide", int "overshoot",
\ bool "soft", int "edgemode" )
{
ss_x = default( ss_x, 1.5 )
ss_y = default( ss_y, 1.5 )
Smode = default( Smode, 1 )
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)
overshoot= overshoot<0 ? 0 : overshoot
soft = default( soft, false )
edgemode = default( edgemode,0)
#radius = round( radius*(ss_x+ss_y)/2)
ox = clp.width
oy = clp.height

ss_x != 1.0 || ss_y != 1.0 ? clp.lanczosresize(round(ox*ss_x/8)*8,round(oy*ss_y/8)*8) : clp
tmp = last

edge = logic( DEdgeMask(0,255,0,255,"5 10 5 0 0 0 -5 -10 -5", divisor=2)
\ ,DEdgeMask(0,255,0,255,"5 0 -5 10 0 -10 5 0 -5", divisor=2)
\ ,"max").greyscale.levels(0,0.86,128,0,255,false) #.levels(0,2.0,208,0,255,false)

bright_limit = (soft == true) ? last.blur(1.0) : last
dark_limit = bright_limit.inpand() #.inflate.deflate
bright_limit = bright_limit.expand() #.deflate.inflate
dark_limit = (wide==false) ? dark_limit : dark_limit .inflate.deflate.inpand().inflate.deflate
bright_limit = (wide==false) ? bright_limit : bright_limit.deflate.inflate.expand().deflate.inflate
minmaxavg = yv12lutxy(bright_limit,dark_limit,yexpr="x y + 2 /")

Str=string(float(strength)/100.0)
normsharp = Smode==1 ? unsharpmask(strength,radius,0)
\ : Smode==2 ? sharpen(float(strength)/100.0)
\ : yv12lutxy(tmp,minmaxavg,yexpr="x x y - "+Str+" * +")

OS = string(overshoot)
Lmode == 1 ? yv12lutxy( bright_limit, normsharp, yexpr="y x - 0 "+OS+" + < y x ?")
\ : yv12lutxy( bright_limit, normsharp, yexpr="y x "+OS+" + < y x y x - 1 2 / ^ + ?")
Lmode == 1 ? yv12lutxy( dark_limit, last, yexpr="y x - 0 "+OS+" - > y x ?")
\ : yv12lutxy( dark_limit, last, yexpr="y x "+OS+" - > y x x y - 1 2 / ^ - ?")

edgemode==0 ? NOP
\ : edgemode==1
\ ? MaskedMerge(tmp,last,edge,Y=3,U=1,V=1,useMMX=true)
\ : MaskedMerge(last,tmp,edge.inflate.inflate.inflate.blur(1.0),Y=3,U=1,V=1,useMMX=true)

ss_x != 1.0 || ss_y != 1.0 ? lanczosresize(ox,oy) : last

clp.mergeluma(last)
return last
}
#

Have fun

- Didée

gamr
24th August 2004, 17:29
well it works like advertised, much faster than ssxsharpen and it looks almost exactly the same :devil: 1 comment so far, where is wide used? i dont see it anywhere . . . :rolleyes:

Soulhunter
24th August 2004, 19:54
So, again...

Here (http://mf.onthanet.nl/forum/thread.php?threadid=100&boardid=4&sid=f4e4e523d639a6321ea2f40976f3cac8&page=1#9) are some samples !!!


Bye

Chainmax
30th August 2004, 03:54
So what would be the main diferences between LimitedSharpen and SSXSharpen regarding output? BTW, the japanese warpsharp is the "warpsharp_2003_1103.cab" one, right?

Soulhunter
30th August 2004, 04:11
Originally posted by Chainmax
So what would be the main differences between LimitedSharpen and SSXSharpen regarding output?
The difference is minimal !!!

Considering the speed factor then, and... :p


Bye

Chainmax
30th August 2004, 04:28
I was going to try it on a very awful VHS capture and received the following error when trying to load the script in VDubMod:

Avisynth open failure:
Script error: LimitedSharpen does not have a named argument "mode"

I copied the function from here and I called it with the following line (from the thread SoulHunter linked to):

LimitedSharpen (ss_x=2.0,ss_y=2.0,mode=2,strength=127,radius=2,power=0.0,overshoot=1,soft=false,edgemode=0)

Didée
30th August 2004, 07:50
the function from here and I called it with the .. line from the thread SoulHunter linked toVery clever.

I posted an actual function call together with the actual script in this thread.
# [...]
# 11.08.2004 - added "wide" parameter (boolean): "true" takes the min|max from a 5x5 neighborhood for limiting.
# "false" works, as formerly, on a 3x3 neighborhood
# - added "Lmode" parameter: "1" does hard limiting as formerly:
# if [sharpen] is within [min-OS,max+OS], take it. Else, use (min|max).
# "2" will replace sharpen's effective overshoot with sqrt(overshoot).
# - renamed "mode" to "Smode": "1" = UnsharpMask / "2" = Sharpen / "3" = MinMaxSharpen
# Smode=3 will, instead of sharpening the current pixel against the average
# of its 8 neighbors, sharpen it against average(min,max). It's less exact
# in theory (blurred corners!), but results in stronger overall sharpening.
# Also, it is less prone to enhancing pre-existing crap like DCT noise

Chainmax
30th August 2004, 12:49
:o :o

Chainmax
30th August 2004, 13:09
Ok, here are the pictures:

Before:
http://members.arstechnica.com/x/master_burrfoot/Frame100_NoS.png
After:
http://members.arstechnica.com/x/master_burrfoot/Frame100_S.png


Before:
http://members.arstechnica.com/x/master_burrfoot/Frame430_NoS.png
After:
http://members.arstechnica.com/x/master_burrfoot/Frame430_S.png

morsa
31st August 2004, 09:56
Chainmax, You won´t tell me you are near your thirty´s ;)
Verano Azul, hahahah.I liked it so much!!!!! (When I was 10) :D

Chainmax
31st August 2004, 15:13
¿Así que sos argentino? Yo soy uruguayo :).
Tengo 24 años, así que no estás muy lejos :sly::(. Veía verano Azul cuando lo pasaban hace unos cuantos años (no recuerdo cuántos exactamente), pero estoy haciendo ésto para mi futura cuñada.

morsa
31st August 2004, 23:33
Good luck then!!!!
Anyway I see your source is really messed up....:(

Chainmax
2nd September 2004, 00:19
Actually, the "before" shots are from the filtered source. :(++

morsa
2nd September 2004, 01:35
If that's the situation I guess you are filtering too much!!!!!!!!!!
Too much median cut.
Could you post an original frame to compare with?

Chainmax
2nd September 2004, 06:13
Will do. I'll start a new thread in Avisynth Usage so this one won't be further derailed. I'll post screenshots and a clip from the unfiltered source. You won't believe how shitty it is.

Boulder
8th September 2004, 13:05
Could someone please point me to the correct dlls? I've got the latest MaskTools but the WarpSharp package (20031103) doesn't seem to work. VirtualDubMod is unable to open the script when I try to use LimitedSharpen(). I suppose that warpsharp.dll includes UnsharpMask()?

Didée
8th September 2004, 14:49
The missing culprit is belong:

msvcr70.dll
msvcr71.dll
msvcp70.dll
msvcp71.dll

I can never remember which of these dll's is needed by which version ... or which is needed by WarpSharp, and which by some Avisynth C-plugins ... big confusion ;)

Just get all of them, place'em in /system32, and be done.

Boulder
8th September 2004, 14:58
Nope, got all of them in %WINDIR%\System32. I still get an error message in VDubMod saying "Avisynth open failure: Avisynth: script open failed!"

God I hate the different WarpSharp packages:D

Didée
8th September 2004, 16:32
I hate this game, too :)

Well, on this machine here, I've available the WarpSharp packages 06-2003 and 11-2003. (I'm actually using the 06 version).

When loading scripts with either DLL, I get the following DLL usage (MSxxx libraries only):

WarpSharp 06-2003
msvcp60
msvcp70
msvcr70
msvcrt


WarpSharp 11-03
msvcp60
msvcp71
msvcr71
msvcrt


Hope this helps, I've to leave now.

Boulder
8th September 2004, 17:04
I got it working, I forgot that warpsharp.dll in the plugins folder causes weird behaviour. I moved it elsewhere and loaded it manually in the script and now it works.

kassandro
9th September 2004, 08:29
Originally posted by Didée
The missing culprit is belong:

msvcr70.dll
msvcr71.dll
msvcp70.dll
msvcp71.dll

I can never remember which of these dll's is needed by which version ... or which is needed by WarpSharp, and which by some Avisynth C-plugins ... big confusion ;)

Just get all of them, place'em in /system32, and be done.
This is an unpleasant dynamic linking problem, which partially destroys the advantage of dynamic linking. For each compiler version you need one version of msvcpXX.dll msvcrXX.dll. In the Linux world the corresponding libraries are nearly always backward compatible, whence you need only the most recent one.