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. |
8th December 2010, 23:26 | #1 | Link |
Registered Amatuer
Join Date: Feb 2007
Posts: 20
|
Sharpen Complex 2 equivalent?
This shader in Media Player Classic creates a very nice sharpening effect, but I've had no luck at recreating the look with various avisynth sharpeners. Does anyone know of any filter and settings that could recreate it, or if perhaps it has already been ported over but is under a different name?
|
7th November 2011, 06:58 | #2 | Link |
Registered Amatuer
Join Date: Feb 2007
Posts: 20
|
Bump - This is still my favorite sharpening effect and I haven't had any luck matching it. Is there a way to pull this code out of Media Player Classic and use it in an avisynth script?
Last edited by RidgeShark; 7th November 2011 at 07:00. |
7th November 2011, 09:27 | #3 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Mhm, don't have the shader code here to look at, but IIRC, isn't it basically a 3x3-Gauss-sharpen on prewitt-masked edges?
Code:
s = mt_lutxy(last,last.removegrain(11,-1),"x x y - 1.5 * +",U=2,V=2) # "1.5" is strength multiplier, change to liking e = last.mt_edge("prewitt",thY1=5,thY2=255) last.mt_merge(s,e,U=2,V=2) Funnily, for detail-enhancement of soft footage, I usually like the opposite strategy: less sharpening on edges, more sharpening on not-edges.
__________________
- 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 November 2011, 09:52 | #4 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 4,926
|
Its cool to see someone else who likes it perception wise (though its a heavy resource shader) you should also take a peak @ mirillis detail boost it's less GPU resource intensive then sharpen complex 2 but with a similar visual result (though unfortunately only available in their Splash Player)
http://www.mediafire.com/download.php?h9ia0mi6tr637sv = Sharpen Complex 2 (unfortunately due to recording framework issues such a major render slowdown results for now in a opposite speedup @ playback) http://www.mediafire.com/download.php?lr93jn6pnut54bg = Detail Boost
__________________
all my compares are riddles so please try to decipher them yourselves :) It is about Time Join the Revolution NOW before it is to Late ! http://forum.doom9.org/showthread.php?t=168004 Last edited by CruNcher; 7th November 2011 at 10:23. |
7th November 2011, 12:33 | #5 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Okay, had a look into it. Once you get used to the "plenty" shader code, it becomes so very simple ....
ComplexSharpen2 essentially boils down to this: (default parameters) edge: 2*center - average(8-neighborhood) non-edge: 3*center - 2*(3x3 gauss) Written as plain kernels: Code:
sharpen kernel for is_edge: [ -1 -1 -1 -1 16 -1 -1 -1 -1 ] sharpen kernel for is_NOT_edge: [ -1 -2 -1 -2 20 -2 -1 -2 -1 ]
__________________
- 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!) |
8th November 2011, 07:56 | #6 | Link | |
Registered Amatuer
Join Date: Feb 2007
Posts: 20
|
CruNcher-
Thank you for letting me know about Detail Boost and for posting the vids. It is interesting to see how these filters effect performance. It would be great to be able to compare the effect against other filters. Didée Thank you for looking into the code for me. Coincidentally, I just found a way to also view the filter's code, but its layout is beyond me, as well as being in French. From what I can see, the parameters you posted are not listed in the code I found - perhaps we have different versions? Here it is - Quote:
Last edited by RidgeShark; 8th November 2011 at 08:00. |
|
8th November 2011, 09:04 | #7 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Code:
str1 = 1.0 # sharpen strength 'on-edge' str2 = 1.0 # sharpen strength on 'not-edge' o = last s1 = mt_lutxy(o,o.removegrain(19,-1),"x x y - 0.6 * "+string(str1)+" * +") s2 = mt_lutxy(o,o.removegrain(11,-1),"x x y - 0.6 * "+string(str2)+" * +") mt_merge(s2,s1,o.mt_edge("prewitt",thY1=5,thY2=255),U=2,V=2) Another quick one, working differently Code:
str = 1.49 o = last b = o.removegrain(11).removegrain(4) mt_lutxy(o,b,"x x y - abs 4 / 1 1.4 / ^ 4 * "+string(str)+" * x y - x y - abs 0.9 + / * +",U=2,V=2)
__________________
- 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; 8th November 2011 at 09:07. |
8th November 2011, 14:34 | #8 | Link |
Registered User
Join Date: Jul 2011
Posts: 10
|
Here is the translated version :
Code:
* Sharpen complex v2 (requires ps >= 2a) */ sampler s0 : register(s0); float4 p0 : register(c0); float4 p1 : register(c1); #define width (p0[0]) #define height (p0[1]) // "width" of a pixel #define px (p1[0]) #define py (p1[1]) /* Parameters */ // Blur calculation #define moyenne 0.6 #define dx (moyenne*px) #define dy (moyenne*py) #define CoefFlou 2 #define CoefOri (1+ CoefFlou) // Sharpening #define SharpenEdge 0.2 #define Sharpen_val0 2 #define Sharpen_val1 ((Sharpen_val0-1) / 8.0) float4 main( float2 tex : TEXCOORD0 ) : COLOR { // Retrieves the original pixel float4 ori = tex2D(s0, tex); ; // Calculates blurred image (gaussian blur) float4 c1 = tex2D(s0, tex + float2(-dx,-dy)); float4 c2 = tex2D(s0, tex + float2(0,-dy)); float4 c3 = tex2D(s0, tex + float2(dx,-dy)); float4 c4 = tex2D(s0, tex + float2(-dx,0)); float4 c5 = tex2D(s0, tex + float2(dx,0)); float4 c6 = tex2D(s0, tex + float2(-dx,dy)); float4 c7 = tex2D(s0, tex + float2(0,dy)); float4 c8 = tex2D(s0, tex + float2(dx,dy)); // gaussian blur filter // [ 1, 2 , 1 ] // [ 2, 4 , 2 ] // [ 1, 2 , 1 ] // In order to normalize values, we have to divide by the sum of the coefficients // 1 / (1+2+1+2+4+2+1+2+1) = 1 / 16 = .0625 float4 flou = (c1+c3+c6+c8 + 2*(c2+c4+c5+c7)+ 4*ori)*0.0625; // The blurred image is substracted from the original image float4 cori = CoefOri*ori - CoefFlou*flou; // Edges detection // Retrieves the 9 (pixel ?) "neighbours" // [ c1, c2 , c3 ] // [ c4,ori , c5 ] // [ c6, c7 , c8 ] c1 = tex2D(s0, tex + float2(-px,-py)); c2 = tex2D(s0, tex + float2(0,-py)); c3 = tex2D(s0, tex + float2(px,-py)); c4 = tex2D(s0, tex + float2(-px,0)); c5 = tex2D(s0, tex + float2(px,0)); c6 = tex2D(s0, tex + float2(-px,py)); c7 = tex2D(s0, tex + float2(0,py)); c8 = tex2D(s0, tex + float2(px,py)); // Using Sobel filter // Horizontal gradient // [ -1, 0 ,1 ] // [ -2, 0, 2 ] // [ -1, 0 ,1 ] float delta1 = (c3 + 2*c5 + c8)-(c1 + 2*c4 + c6); // Vertical gradient // [ -1,- 2,-1 ] // [ 0, 0, 0 ] // [ 1, 2, 1 ] float delta2 = (c6 + 2*c7 + c8)-(c1 + 2*c2 + c3); // Calculation if( sqrt( mul(delta1,delta1) + mul(delta2,delta2) ) >SharpenEdge ) { // If edge, sharpening //return float4(1,0,0,0); return ori*Sharpen_val0 - (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 ) * Sharpen_val1 ; } else { // Else, image fixed return cori; } } |
29th November 2011, 02:09 | #10 | Link |
Registered User
Join Date: Dec 2003
Location: Denmark
Posts: 122
|
This seems like a good place to post this.
LumaSharpen is an almost completely rewritten and optimized Sharpen Complex 2, that does it's calculation on the luma channel to avoid color artifacts. It currently still includes the old edge detection mask code from Sharpen Complex 2, but I'm considering taking it out completely because I've found that it lead to artifacts and simply clamping down the sharpen effect gives better results and is much faster. It currently runs about 2.5x as fast as Sharpen Complex 2 with 4 + 1 (the original) samples which equates to a 9-tap gaussian blur (exactly the same as Sharpen Complex 2) , but with only 5 texture lookups instead of 9 (+ 8 if you used the edge dectection mask). It can even use as little as only 1 additional sample ( or 2 or 3 ), resulting in a much faster (up to about 6.23x faster than Sharpen Complex 2 on my GPU), but lower quality sharpen. Use an uneven number of additional samples have a tendency to "pull" the image in the direction of the sample, so I suggest used 2 or 4 samples as they are balanced out. This is a WIP and I haven't even tried it in MPC-HC yet because something seems to be wrong with my MPC-HC setup at the moment and I can't use any shaders. It works with the FXAA injector though in all my Direct3D games although that is a slightly different version tailored for that. That version is here if you want to try that. Extract into a Direct3D game or program directory next to the game or program exe and run your program (PAUSE turns the effect on and off) It works with VLC set to Direct3D output, although that seemed to be unstable on one of my PCs It also compiles fine in GPU Shaderanalyzer so I'm hopeful it will work. If you have ideas or comments, please let me know. Code:
/* _________________ ( ) (() LumaSharpen ()) )_________________( by Christian Cann Schuldt Jensen ~ CeeJay.dk Based on Sharpen Complex 2 from Media Player Classic (I have rewritten most of the code by now though) It blurs the original pixel with the surrounding pixels and then subtracts this blur to sharpen the image. It does this in luma to avoid color artifacts and allows limiting the maximum sharpning to avoid or lessen halo artifacts. This is similar to converting an image to LAB colorspace and using Unsharp Mask on the Lightness channel in Photoshop. Compiles with both shader version 2.0 and 3.0 */ // .----------------------------------------------------._User settings_.---------------------------------------------------. // Set values to calculate the amount of blur to consider for the sharpening pass #define Average 0.5 // I suggest a value between 0.0 and 1.0 - default is 0.5 #define CoefBlur 1.8 // Strength of the sharpening - You should probably use something between 1.2 and 3.0 #define sharp_clamp 0.015 // Limits maximum amount of sharpening a pixel recieves - Default is 0.015 #define texture_lookups 4 // Number of additional texture lookups you want to do. // More texture lookups = More accurate sharpening. // Less = Faster. // Minumum is 1. Max is 4 and the default. // --- Edge detect mask settings --- (I don't use these anymore as clamping the sharpening seems to work better) //#define Use_Edge_Detection //#define Use_High_Quality_Edge_Detection // Set values for the edge sharpening #define SharpenEdge 0.80 #define Sharpen_val0 1.1 // .--------------------------------------------------._Defining constants_.------------------------------------------------. sampler s0 : register(s0); float4 p0 : register(c0); float4 p1 : register(c1); #define width (p0[0]) #define height (p0[1]) #define px (p1[0]) #define py (p1[1]) #define dx (Average*px) #define dy (Average*py) #define CoefOri (1+ CoefBlur) #define Sharpen_val1 ((Sharpen_val0-1) / 8.0) //#define CoefLuma float4(0.2126, 0.7152, 0.0722, 0) // BT.709 & sRBG luma coefficient (Monitors and HD Television) #define CoefLuma float4(0.2125, 0.7154, 0.0721, 0) // BT.709 & sRBG luma coefficient (Monitors and HD Television) //#define CoefLuma float4(0.299, 0.587, 0.114, 0) // BT.601 luma coefficient (SD Television) #define Coefblur_luma ((CoefLuma / texture_lookups) * CoefBlur) // .------------------------------------------------------._Main code_.-----------------------------------------------------. float4 main( float2 tex : TEXCOORD0 ) : COLOR //Use with Shaderanalyzer and MPC-HC { // -- Recover the original pixels -- float4 ori = tex2D(s0, tex); // ori = original pixel float luma = dot(ori, CoefLuma); // luma = relative percieved brightness of the original pixel //float4 alpha = float4(ori.w, ori.w, ori.w, ori.w); // Store the alpha in all channels //float4 chroma = (ori-luma); // chroma = hue relative to luma // -- Gaussian filter -- // [ 1, 2 , 1 ] // [ 2, 4 , 2 ] c1 through c8 are the values of the surrounding samples // [ 1, 2 , 1 ] // -- Interpolated texture lookups -- float4 blur = tex2D(s0, tex + float2(-dx,-dy)); // North West #if texture_lookups >= 4 blur += tex2D(s0, tex + float2(dx,-dy)); // North East #endif #if texture_lookups >= 3 blur += tex2D(s0, tex + float2(-dx,dy)); // South West #endif #if texture_lookups >= 2 blur += tex2D(s0, tex + float2(dx,dy)); // South East #endif // -- Calculate a gaussian blur, normalize it and get its luma -- // float blur_luma = dot((c1+c3+c6+c8), Coefblur_luma); // TODO Looks like I can combine Coefblur_luma and Coefluma in a #define float blur_luma = dot( blur, Coefblur_luma); // -- Subtracting the luminance of the blurred image from the luminance of the original image -- //TODO try and optimize these by using less variables (so far the hlsl compiler does a better job than me) //float sharp_luma = CoefOri*luma - CoefBlur*blur_luma; float sharp_luma = CoefOri*luma - blur_luma; //WIP Trying to limit using clamp instead of mask float sharp = clamp((sharp_luma-luma), -sharp_clamp, sharp_clamp); //TODO Try a curve function instead of a clamp //float sharp = (sharp_luma-luma); float4 done = ori + sharp; // Either combine the original pixel with the sharpen //float4 done = sharp_luma + chroma; // Or combine the shapened luma with the chroma //For tweaking and debugging purposes you can show the sharpen effect or chroma. //float4 done = (sharp*4) + float4(0.5,0.5,0.5,0); // Uncomment to visualize the strength of the sharpen (multiplied by 4 to see it better) //float4 done = chroma + float4(0.6,0.6,0.6,0); // Uncomment to visualize the chroma - remember to uncomment the line that calculates chroma too. //float4 done = alpha; // Visualize the alpha //float4 done = 1.0 - (alpha); // Visualize the inverted alpha // .----------------------------------------------------._Edge_Dection_.---------------------------------------------------. #ifdef Use_Edge_Detection // -- "For higher precision in the calculation of contour, requires slightly more processing power" -- // ?? doubling the amount of extra texture lookups is "slightly" ?? (tripling it, now that I've optimized the number of extra lookups needed to only 4) (Now only 2!) // [ c1, c2 , c3 ] // [ c4, ori, c5 ] // [ c6, c7 , c8 ] #ifdef Use_High_Quality_Edge_Detection c1 = tex2D(s0, tex + float2(-px,-py)); float4 c2 = tex2D(s0, tex + float2(0,-py)); float4 c3 = tex2D(s0, tex + float2(px,-py)); float4 c4 = tex2D(s0, tex + float2(-px,0)); float4 c5 = tex2D(s0, tex + float2(px,0)); float4 c6 = tex2D(s0, tex + float2(-px,py)); float4 c7 = tex2D(s0, tex + float2(0,py)); float4 c8 = tex2D(s0, tex + float2(px,py)); #endif // -- Horizontal gradient -- // [ -1, 0 ,1 ] // [ -2, 0, 2 ] // [ -1, 0 ,1 ] float delta1 = dot((c3 + 2*c5 + c8), CoefLuma) - dot((c1 + 2*c4 + c6), CoefLuma); // -- Vertical gradient -- // [ -1, -2,-1 ] // [ 0, 0, 0 ] // [ 1, 2, 1 ] float delta2 = dot((c6 + 2*c7 + c8), CoefLuma) - dot((c1 + 2*c2 + c3), CoefLuma); //TODO don't use a binary mask - use a gradient and use it to determine the effect of the sharpen //The current implementation causes flickering of pixels. // -- Calculate and sharpen the blurry edges -- if (sqrt( mul(delta1,delta1) + mul(delta2,delta2)) > SharpenEdge) //?? Verify that the mul and sqrt aren't just there to get a positive value. { // -- Contour sharpening -- // To instead display the contour use // return float4(1,0,0,0); return ori*Sharpen_val0 - (c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 ) * Sharpen_val1; } else { // Return corrected image return done; } #endif // .-------------------------------------------------._Returning the output_.-----------------------------------------------. //done = float4(pow(done, 1.0 / 2.2 )); Convert a sRGB colorspace to non-linear gamma 2.2 - Turned off because of precision errors return done; } EDIT: The current settings work fine for me when playing Skyrim. You'll have to tweak them for your particular setup and your taste yourselves. Please share good settings you find. UPDATE: I've halfway fixed my problem with running shaders in MPC-HC (it now works for pre-resize shader, but not post-resize) and tested LumaSharpen and it compiles and works. Last edited by CeeJay.dk; 1st December 2011 at 11:01. |
1st December 2011, 10:59 | #12 | Link |
Registered User
Join Date: Dec 2003
Location: Denmark
Posts: 122
|
I'm an Avisynth newbie so I have no idea. But it seems it would require a plugin that could run shaders on the input and return the output.
Does one exist? I don't know, but if it doesn't someone should make one as it would have so many good uses. Maybe one of the people who have already made a GPU-based plugin - ask around. Otherwise you would have to port the effect to Avisynth, like Didée attempted a few posts back. |
1st December 2011, 14:03 | #13 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Why would first-grade 3x3-kernel operations need to be ported to Avisynth?
__________________
- 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!) |
5th December 2011, 12:41 | #15 | Link | |
Registered User
Join Date: Apr 2009
Posts: 138
|
Quote:
If you have updates or new sharpening scripts for non-edges.. let us know. |
|
5th December 2011, 17:24 | #16 | Link |
The speed of stupid
Join Date: Sep 2011
Posts: 317
|
A quick edge detection would be this:
Code:
RAverageW(last,64,last.RemoveGrain(19,-1),-64,mode=4,u=0,v=0,bias=-128) Code:
msk=RAverageW(last,64,last.RemoveGrain(19,-1),-64,mode=4,u=0,v=0,bias=-196).Mt_Invert().Mt_Deflate() RMerge(last,Sharpen(0.6),msk,mode=255) Edit: Actually, no. Mode 19 is faster than 20. Last edited by Bloax; 5th December 2011 at 18:14. |
5th December 2011, 18:55 | #17 | Link | |
Registered User
Join Date: Apr 2009
Posts: 138
|
@bloax.. I cannt run RedAverage.dll
Quote:
The dll is placed in avisynth/plugins directory. Any other dlls are required to run it?. Something into the system32? MT compatible? (setmtmode (2) here). |
|
5th December 2011, 18:59 | #18 | Link |
The speed of stupid
Join Date: Sep 2011
Posts: 317
|
Strange, and you are using 1.4.3 of it, right?
Because I'm on the exact same setup. (MtMode(2)) I think I've had such an issue with other plugins on another system before, perhaps try manually loading the plugin? Edit: And just a clarification, higher weights 'detect' more edges, not less. EditEdit: Here's a fancier (more stupid) kind of sharpening, that I decided to be "less" powerful at lower brightness levels. -- Code:
edgemsk=RAverageW(last,32,last.RemoveGrain(19,-1),-32,mode=4,u=0,v=0,bias=-128).Mt_Invert().Mt_Inpand().Mt_Inflate() lumamsk=RAverageW(last,2,last,2,mode=4,u=0,v=0,bias=-196) flat=RAverageW(last,-2,last,-2,mode=4,u=0,v=0) //Are there any fast alternatives to making a flat y=0 clip? :P msk=RMerge(edgemsk,flat,lumamsk,mode=255,u=0,v=0) RMerge(last,Sharpen(0.5),msk,mode=255) Last edited by Bloax; 5th December 2011 at 20:03. |
5th December 2011, 19:01 | #19 | Link | |
Registered User
Join Date: Apr 2009
Posts: 138
|
using 1.4.3 here too.. Ill try manual load..
edit.- I was not able to run it yet. I dont know what dll or dependency causes the problem. Currently my fav one is this one: Quote:
Last edited by travolter; 5th December 2011 at 20:39. |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|