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.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 6th March 2010, 10:01   #1  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,348
Soft thresholded median sharpening function

Code:
Function MedSharp(Clip C, int "thresh", int "rad", int "mode", bool "lp", bool "hp", bool "nr", float "str", int "kernel")
{

	_Thr = Default(thresh, 256)
	_Rad = Default(rad, 1)
	Mode = Default(mode, 1)
	str = Default(str, 1.5)
		THR  = string(_Thr)
		RAD  = string(_Rad)
		RAD2  = string(_Rad)

	lp = Default(lp, false)
	hp = Default(hp, false)
	nr = Default(nr, false)
	kernel = Default(kernel, 1)


	Lowpass = C
	Lowpass = lp == true ? _Rad >= 2 ? Lowpass.NLLV(rad=1).NLLH(rad=1) : Lowpass : Lowpass 
	Lowpass = lp == true ? _Rad >= 4 ? Lowpass.NLLV(rad=2).NLLH(rad=2) : Lowpass : Lowpass 
	Lowpass = lp == true ? _Rad == 6 ? Lowpass.NLLV(rad=3).NLLH(rad=3) : Lowpass : Lowpass 
	Lowpass = lp == true ? _Rad >= 8 ? Lowpass.NLLV(rad=4).NLLH(rad=4) : Lowpass : Lowpass 
	Lowpass = lp == true ? _Rad == 10 ? Lowpass.NLLV(rad=4).NLLH(rad=5) : Lowpass : Lowpass 
	Lowpass = lp == true ? _Rad == 12 ? Lowpass.NLLV(rad=4).NLLH(rad=6) : Lowpass : Lowpass 
	Lowpass = lp == true ? _Rad == 14 ? Lowpass.NLLV(rad=4).NLLH(rad=7) : Lowpass : Lowpass 
	Lowpass = lp == true ? _Rad >= 16 ? Lowpass.NLLV(rad=4).NLLH(rad=8) : Lowpass : Lowpass
	Lowpass = nr == true ? Lowpass.TMed2(rad=_Rad, thresh=thresh, Kernel=Kernel) : Lowpass

	Diff = Mode==0 ? MT_Luts(C, Lowpass, mode="med", pixels = "0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD ,\
	expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)\
	 : MT_Luts(C, Lowpass, mode="med", pixels = "0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD+" 0 0" ,\
	 expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)

        Diff = Kernel > 1 ? MT_Luts(C, Lowpass, mode="med", pixels = "-"+RAD2+" -"+RAD2+"-"+RAD2+" "+RAD2+" "+RAD2+" -"+RAD2+" "+RAD2+" "+RAD2+" 0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD ,\
          expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1) : Diff 
		
		Diff = Diff.mt_Lut("X 128 - "+string(str)+" * 128 +")
		
		Diff2 = Diff.NLLV(rad=_Rad).NLLH(rad=_Rad)
		Diff = hp == true ? Mt_Makediff(diff, diff2) : Diff
		#Diff = hp == true ? Diff.lanczosresize(c.width*2, c.height*2, 0.25, 0.25, taps=3).NLHH().NLHV().pointresize(c.width, c.height) : Diff
		#Diff = hp == true ? Diff.NLHH2().NLHV2() : Diff
	  
	  
		MT_adddiff(C, Diff, u=2, v=2)

Return(Last)
}
Dependencies
Code:
Function TMed2(Clip C, int "thresh", int "rad", int "mode", int "kernel")
{

	_Thr = Default(thresh, 256)
	_Rad = Default(rad, 1)
	Mode = Default(mode, 1)
		THR  = string(_Thr)
		RAD  = string(_Rad)
		RAD2  = string(_Rad)
		kernel = Default(kernel, 1)

	Diff = Mode==0 ? MT_Luts(C, C, mode="med", pixels = "0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD ,\
	expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)\
	 : MT_Luts(C, C, mode="med", pixels = "0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD+" 0 0" ,\
	 expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)
        Diff = Kernel > 1 ? MT_Luts(C, C, mode="med", pixels = "-"+RAD2+" -"+RAD2+"-"+RAD2+" "+RAD2+" "+RAD2+" -"+RAD2+" "+RAD2+" "+RAD2+" 0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD ,\
          expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1) : Diff 

	 
	 
	 	MT_Makediff(C, Diff, u=2, v=2)

Return(Last)
}

Function NLHH2(Clip C)
{


	B1 = C.BlurH(1, 0.833)
	B2 = C.BlurH(2, 0.750)
	B3 = C.BlurH(3, 0.944)
	B4= C.BlurH(4, 0.981)

		B1_D = Mt_Makediff(c, b1, u=1, v=1)
		B2_D = Mt_MakeDiff(b2, c, u=1, v=1)
		B3_D = Mt_MakeDiff(c, b3, u=1, v=1)
		B4_D = Mt_MakeDiff(b4, c, u=1, v=1)

			B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 0.75 * X 128 - abs - 0 > \
			Y 128 - abs 0.75 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.25 * X 128 - abs - 0 > \
			Y 128 - abs 2.25 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 6.75 * X 128 - abs - 0 > \
			Y 128 - abs 6.75 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)

	Mt_AddDiff(B4_DT, C)

Return(last)
}

Function NLHV2(Clip C)
{


	B1 = C.BlurH(1, 0.833)
	B2 = C.BlurH(2, 0.750)
	B3 = C.BlurH(3, 0.944)
	B4= C.BlurH(4, 0.981)

		B1_D = Mt_Makediff(c, b1, u=1, v=1)
		B2_D = Mt_MakeDiff(b2, c, u=1, v=1)
		B3_D = Mt_MakeDiff(c, b3, u=1, v=1)
		B4_D = Mt_MakeDiff(b4, c, u=1, v=1)

			B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 0.75 * X 128 - abs - 0 > \
			Y 128 - abs 0.75 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.25 * X 128 - abs - 0 > \
			Y 128 - abs 2.25 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 6.75 * X 128 - abs - 0 > \
			Y 128 - abs 6.75 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)

	Mt_AddDiff(B4_DT, C)

Return(last)
}


Function NLLH(Clip C, int "rad")
{


	Rad = Default(Rad, 1)

	B1 = C.BlurH(1*rad, 0.439)
	B2 = C.BlurH(3*rad, 0.833)
	B3 = C.BlurH(5*rad, 0.934)
	B4= C.BlurH(7*rad, 0.983)

		B1_D = Mt_Makediff(B1, C, u=1, v=1)
		B2_D = Mt_MakeDiff(C, B2, u=1, v=1)
		B3_D = Mt_MakeDiff(B3, C, u=1, v=1)
		B4_D = Mt_MakeDiff(C, B4, u=1, v=1)

			B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 1.915 * X 128 - abs - 0 > \
			Y 128 - abs 1.915 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.025 * X 128 - abs - 0 > \
			Y 128 - abs 2.025 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.077 * X 128 - abs - 0 > \
			Y 128 - abs 2.077 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)

	Mt_AddDiff(B4_DT, C)

Return(last)
}

Function NLLV(Clip C, int "rad")
{


	Rad = Default(Rad, 1)

	B1 = C.BlurV(1*rad, 0.439)
	B2 = C.BlurV(3*rad, 0.833)
	B3 = C.BlurV(5*rad, 0.934)
	B4= C.BlurV(7*rad, 0.983)

		B1_D = Mt_Makediff(B1, C, u=1, v=1)
		B2_D = Mt_MakeDiff(C, B2, u=1, v=1)
		B3_D = Mt_MakeDiff(B3, C, u=1, v=1)
		B4_D = Mt_MakeDiff(C, B4, u=1, v=1)

			B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 1.915 * X 128 - abs - 0 > \
			Y 128 - abs 1.915 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.025 * X 128 - abs - 0 > \
			Y 128 - abs 2.025 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)
			B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.077 * X 128 - abs - 0 > \
			Y 128 - abs 2.077 * X 128 - abs - 0 ?  X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / +  128 + ", u=1, v=1)

	Mt_AddDiff(B4_DT, C)

Return(last)
}

Function blurH(clip c, int "rad", Float "CW")
{
	
	Rad = Default(rad, 1)
	CW = Default(CW, 0.5)
	
	Center = C
	Left = C.PointResize(C.width, C.height, -rad, 0, C.width, C.height)
	Right = C.PointResize(C.width, C.height, rad, 0, C.width, C.height)
	
	Average(Center, CW/2, Left, (1-CW)/2, Right, (1-CW)/2, Center, CW/2)
	
Return(last)
}

Function BlurV(clip c, int "rad", Float "CW")
{
	
	Rad = Default(rad, 1)
	CW = Default(CW, 0.5)
	
	Center = C
	Down = C.PointResize(C.width, C.height, 0, -rad, C.width, C.height)
	Up = C.PointResize(C.width, C.height, 0, rad, C.width, C.height)
	
	Average(Center, CW/2, Down, (1-CW)/2, Up, (1-CW)/2, Center, CW/2)
	
Return(last)
}
Quick tests look promising, it appears to completely avoid aliasing the way normal median sharpening does, but I have tested very little. Str is exponential, 4 is twice as strong as 1, etc. This was hacked together out of a bit of something else, so some of the internals are a little odd (like str) but everything looks like its working well.

[edit] forgive the wideness, will fix later
[edit] fixed (mostly, still too wide, but I don't want to split the equations)

Last edited by *.mp4 guy; 10th March 2010 at 11:05.
*.mp4 guy is offline   Reply With Quote
Old 6th March 2010, 13:54   #2  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,389
Hey, that's a nice idea! Alas, the available means in Avisynth are somewhat restricted, you know.

With "thresholded median", I rather understand that the thresholdig (be it soft or hard) is applied to each single neighborhood pixel while doing the median calculation. What we have here is a plain median, where the median's result is furtheron mix-calculated with the original pixel. That's a non-trivial difference.
However, the former way can not be done at all with MaskTools, any access "into" the basic operation is not possible. The latter way, as you are doing, is infact the only way that's open from the script level. (I'm only noting, not complaining!)

But I wonder a bit about the median neighborhood. E.g. with rad=2, you're using only the following pixels from a 5x5 neighborhood:

x x x x x
x x x x x
x x x x x
x x x x x
x x x x x

With increasing radii, the results get less and less precise. rad=1 is a bit rough, rad=2 is pretty rough, and with rad=3 (or at latest with 4), the result starts to be purely random (too little pixels, from too far away, to produce a meaningful result).

Shouldn't there be mt_square used instead, to take all pixels into account? Of course, things will get pretty slow then, especially with larger radii, but that's how median and mt_luts are.


A possible addition: make the treshold adaptive to the actual min-max span of the used neighborhood. Idea?
__________________
- 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!)
Didée is offline   Reply With Quote
Old 7th March 2010, 21:36   #3  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,348
Oddly enough, adding in the corners doesn't really help (at least not at small radii).

Also, the median is calculated after the limiting, iirc. From documentation:
Quote:
Originally Posted by readme
mt_luts takes two clips into account. It'll compute the "mode" operation over the
result of the lut expression, with the pixel of the first clip as x, and the neighbouring
pixel of the second clip as y.
So it goes.

1 calculate difference between center pixel and median neighborhood pixels

2 soft-limit each difference

3 find median of differences

4 add median difference to source

Also, if the source is blurry at radii X (and needs to be sharpened) then there is correlation at radii X, even excluding the extra pixels, its a bit non-optimal, but there are other problems with using median sharpening at high radii that this avoids besides the speed problem.
*.mp4 guy is offline   Reply With Quote
Old 8th March 2010, 10:47   #4  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,389
Jeeze .... my last post clearly was a case of "unwrap candy, throw candy into dustbin, put paper into mouth."

Thanks for the reminder on the order-of-calculation in mt_luts. It's a more powerful tool than it looks at first glance.

Even more funnily, somehow I had stopped reading after "Soft thresholded median|..." - thought it was just a kind of soft-median, but didn't see that it's actually a sharpener. [ouch]

I'm still a bit puzzeled about "precision" - if only a few random pixels out of a rather big neighborhood are evaluated, it just doesn't seem right. But hey, apart from all theorizing, the empiric test is a strong argument, too. And after simply giving a try on that function, conclusion is:

This baby seems to work pretty good. Period.
__________________
- 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!)
Didée is offline   Reply With Quote
Old 9th March 2010, 13:04   #5  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,389
To compensate for my silliness above, here are two suggestions. (Hopefully, more constructive this time.)

Firstly, just about boring syntax:
Quote:
Originally Posted by *.mp4 guy View Post
[[edit] forgive the wideness, will fix later
[edit] fixed (mostly, still too wide, but I don't want to split the equations)
Quite a few characters can be saved by not calling "string(var)" several times. Using a string variable makes things shorter. Example how I did locally:
(Took the freedom to also delete leading-blanks, end-blanks, and double-blanks from the strings.)
Code:
        _Thr = Default(thresh, 256)
        _Rad = Default(rad, 1)
        Mode = Default(mode, 1)

        THR  = string(_Thr)
        RAD  = string(_Rad)

        Diff = Mode==0 ? MT_Luts(C, C, mode="med", pixels = "0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD ,\
         expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)\
                        : MT_Luts(C, C, mode="med", pixels = "0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD+" 0 0" ,\
 	 expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)
If that's still too wide, use [size= 1][/size].


Ah, boring, isn't it. More interestingly, a technical change. I found that using only 4 pixels from the neighborhood can indeed cause a drawback: if there is any strictly-horizontal or strictly-vertical detail, then most of it will not get any sharpening. (On a straight line, 3 of the 5 samples are on the line, so the median won't bite.)

Surely that's by intention, but it could be interpreted as a shortcoming. The issue can be pretty much avoided by extending the kernel to 8 neighbors, using 4 additional pixels from the diagonals:

(Now the strings get awfully long again....)

Code:
        _Thr = Default(thresh, 256)
        _Rad = Default(rad, 1)
        Mode = Default(mode, 1)

        THR  = string(_Thr)
        RAD  = string(_Rad)
        RAD2 = string( round(_Rad/1.4142) )

        Diff = Mode == 0 ? MT_Luts(C, C, mode="med", pixels = "-"+RAD2+" -"+RAD2+"-"+RAD2+" "+RAD2+" "+RAD2+" -"+RAD2+" "+RAD2+" "+RAD2+" 0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD ,\
          expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)\
                         : MT_Luts(C, C, mode="med", pixels = "-"+RAD2+" -"+RAD2+"-"+RAD2+" "+RAD2+" "+RAD2+" -"+RAD2+" "+RAD2+" "+RAD2+" 0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD+" 0 0" ,\
          expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)
        MT_adddiff(C, Diff, u=2, v=2)
Could be integrated by extending the "mode" parameter, or by "fast=true/false", or by "kernel=4/8", or whatever.
__________________
- 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!)
Didée is offline   Reply With Quote
Old 9th March 2010, 14:42   #6  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,348
Well, the problem with the diagonals, and with large medians in general, is that all the pixels have the same "weight", when they really shouldn't. Anyway, If you want to force sharpening all the time, that is what mode 0 is for, by excluding the center value, you get sharpening no matter what (though its not exactly a median anymore, it works fine).

Expanding on the pixel positioning problem, the basic situation is that you want all of the pixels in your median calculation to have the same frequency relation to the center pixel, furthermore, you want them to all be of the highest correlation with the center pixel (for any given radius X) the correct way to solve this problem is to use all of the pixels needed to accurately represent a given radius, and then weight them to the correct proportions, but this is slow and causes implementation problems in avisynth.

However, I'll see what adding in the diagonals looks like, also, new version in first post, with some experimental features (I know things are really unoptimized, that will be addressed when I know what works and what doesn't)
*.mp4 guy is offline   Reply With Quote
Old 9th March 2010, 15:04   #7  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,389
Quote:
Originally Posted by *.mp4 guy View Post
Anyway, If you want to force sharpening all the time, that is what mode 0 is for, by excluding the center value, you get sharpening no matter what (though its not exactly a median anymore, it works fine).
- And that's a question indeed: if it is not a median, what IS it, then?

If the "pixel situation" is like this ...
Code:
o o o o o o o
o o o o o o o
x x x x x x x
o o o o o o o
o o o o o o o
... then it's not quite clear to me what is supposed to happen.


Quote:
to use all of the pixels needed to accurately represent a given radius, and then weight them to the correct proportions, but this is slow and causes implementation problems in avisynth.
Exactly that. And also, exactly that.


Quote:
However, I'll see what adding in the diagonals looks like,
Well, the most obvious difference (apart from even stronger enhancement of horizontal/vertical features, compared to mode=0) is that the overall effect is stronger.
__________________
- 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; 9th March 2010 at 15:06.
Didée is offline   Reply With Quote
Old 9th March 2010, 15:17   #8  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,348
What happens with 4 values is that the median two values are found and then averaged, which still works pretty well, though by all rights it shouldn't.

As to the differences when using the corners, well, it definitely is stronger, but in the one test I did, I couldn't call it better. it amplified the median artifacts, and skewed the sharpening to a lower frequency level, which reduced overall high frequency sharpening, which is the opposite of what I want.

[edit]

Did another test, it looked alright this time, it might be faster for really strong sharpening, don't think it will look better though.

[edit2]

The larger kernel is stronger and more regular, while the smaller kernel can get more "sharpness" into the high frequencies, so there is a trade off of sorts. I might have to cobble together a weighted median filter now, since larger kernels do have some clear advantages, meh.

Last edited by *.mp4 guy; 9th March 2010 at 17:43.
*.mp4 guy is offline   Reply With Quote
Old 29th March 2010, 07:47   #9  |  Link
rkalwaitis
Robert
 
Join Date: Jan 2008
Location: Stuttgart
Posts: 407
*.mp4 guy,

I was interested in seeing what you finally came up with for this sharpening method.
rkalwaitis is offline   Reply With Quote
Old 11th August 2010, 07:02   #10  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,348
Hopefully this doesn't count as necro posting, but I had forgotten about this thread. When I was working on doing things correctly, I did a test run which took an incredible amount of time to accomplish essentially nothing. Then a bit later I had an idea on how to cheat to get something similar with a still large, but now manageable speed hit, its definitely not "correct" but it works.

Code:
Function MedSharp2(Clip C, int "thresh", int "rad", int "mode", bool "lp", bool "hp", bool "nr", float "str", int "kernel")
{

	_Thr = Default(thresh, 256)
	_Rad = Default(rad, 1)
	Mode = Default(mode, 1)
	str = Default(str, 1)
		THR  = string(_Thr)
		RAD  = string(_Rad)
		RAD2  = string(_Rad)

	lp = Default(lp, false)
	hp = Default(hp, false)
	nr = Default(nr, false)
	kernel = Default(kernel, 2)


	inputclipproperties = c
	blank = BlankClip(length=inputclipproperties.framecount, width=inputclipproperties.width,\
	 height=inputclipproperties.height, pixel_type="rgb32", fps=inputclipproperties.framerate,\
	  fps_denominator=1, audio_rate=inputclipproperties.Audiorate, stereo=true, sixteen_bit=true,\
	   color=$828282).converttoyv12()

	Lowpass1 =  C.NLLV(rad=1).NLLH(rad=1) 
		Lowpass_Return = lp == true ? _Rad >= 2 ? Lowpass1 : C : C 

	Lowpass_NR_1 = Lowpass_Return.TMed2(rad=_Rad, thresh=_Thr, Kernel=1)
	Lowpass_NR_2 = Lowpass_Return.TMed2(rad=_Rad, thresh=_Thr/4, Kernel=2)

	Diff1 = MT_Luts(C, Lowpass_NR_1, mode="med", pixels = "0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD+" 0 0" ,\
	 expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 1 >= "+THR+" 0.5 ^ "+THR+" ? + / - 128 +", u=1,v=1)
	Diff2 = MT_Luts(C, Lowpass_NR_2, mode="med", pixels = "-"+RAD2+" -"+RAD2+"-"+RAD2+" "+RAD2+" "+RAD2+" -"+RAD2+" "+RAD2+" "+RAD2+" 0 "+RAD+" "+RAD+" 0 -"+RAD+" 0 0 -"+RAD ,\
	 expr = "X Y - X Y - X Y - abs 1 + * X Y - abs 1 + "+THR+" 2 * 1 >= "+THR+" 2 * 0.5 ^ "+THR+" 2 * ? + / - 128 +", u=1,v=1)
		
	mask1 = Mt_Lut(Diff1, " X 128 - 255 * ", u=1, v=1)#.NLLV().NLLH()
	#mask2 = Mt_Lut(Diff2, " X 128 - 255 * ", u=1, v=1)#.NLLV().NLLH()
		
	s1 = mt_merge(Diff2, blank, mask1).mt_Lut("X 128 - "+string(str)+" 2 / * 128 +")
		s1b = s1.NLLV().NLLH()
			s1s = mt_makediff(s1, s1b)
	s2 = Diff1.mt_Lut("X 128 - "+string(str)+" * 128 +")
		s2b = s1.NLLV().NLLH()
			s2s = mt_makediff(s2, s2b)
		

	out = MT_adddiff(C, s1s, u=2, v=2)
	out = MT_adddiff(out, s2s, u=2, v=2)
	out

Return(Last)
}
This predates ReCon which I consider to be generally better, but I coded the solution a while ago, and it works fine. All it does is use the larger radius filter on pixels that the lower radius doesn't operate on, and the smaller radius the remainder of the time.

The last version I posted also had the following features, but I don't think I explained them. A lowpass is applied to the neighbor pixels when using radius 2 because it reduces noise amplification, while otherwise performing about the same. I didn't code for radii larger then 2, because they never looked acceptable to me, the medians start to do weird things and distort the image. Also, neighborhood pixels are themselves put through a median smoothing operation before being used for sharpening, it reduces noise and does not significantly effect sharpening strength. There is additionally some fiddling with the frequency components of the sharpening before applying them to the picture.

[edit] also it is too wide again, and some of the arguments don't do anything anymore.

Last edited by *.mp4 guy; 12th August 2010 at 03:18.
*.mp4 guy is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 09:48.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.