Voici un combo avisynth-pixel shaders pour le post-traitement de sources 1080p. Il est plutôt respectueux de la douceur caractéristique de l'image cinéma sur un projo avec un CR ANSI moyen. Il n'y a rien de très novateur ds la mise en oeuvre mais il applique un filtrage dissymétrique pour minimiser les artefacts. La difficulté a surtout été de trouver le bon enchaînement et les bons niveaux de sharpen. Il y a pas de denoiser. La charge CPU est légère sur un i7 et la charge GPU quasi nulle. C'est donc une config très light...
Je l'utilise actuellement sur un projo data triLCoS fullHD Canon wux450. Les convergences et la qualité optique de ce projo sont très bonnes pour un LCoS. Il est utilisé sur un écran blanc de 5m de base avec une courbure sphérique (placo peint).
Ce combo a également été rapidement testé sur un monoDLP fullHD Benq W2000 (avec netteté sur 7 qui semble correspondre au "neutre") sur une petite base de 1m80 avec un écran gris (placo peint). Le résultat était un peu trop sharpé à mon goût du fait du CR ANSI supérieur de ce projo. Je n'ai pas eu le temps de modifier les settings pour les adapter.
Pour des projos avec une qualité optique supérieure, les settings proposés seront trop forts...
(a) Fichiers *.avsi nécessaires (à placer dans le dossier "plugins" de avisynth) :
Fichier "LimitedSharpenFasterHC.avsi"
Code : Tout sélectionner
function LimitedSharpenFasterHC(clip clp, float "strength")
{
ox = clp.width
oy = clp.height
strength = default( strength, 40 )
overshoot = 1
undershoot= 1
clp.isYV12() ? clp : clp.converttoyv12()
tmp = last
dark_limit = tmp.mt_inpand()
bright_limit = tmp.mt_expand()
minmaxavg = mt_average(dark_limit, bright_limit)
Str=string(strength/100.0)
normsharp = mt_lutxy(tmp,minmaxavg,yexpr="x x y - "+Str+" * +")
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+" - ?")
mt_clamp(normsharp, bright_limit, dark_limit, overshoot, undershoot)
AMNT = string(0)
AMNT2 = string(100)
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 ?")
clp.isYV12() ? clp.mergeluma(last) : clp.mergeluma(last.converttoyuy2())
return last
}
Fichier "NaturalFullHD.avsi"
Code : Tout sélectionner
function NaturalFullHD(clip clp, float "ss", float "LSFstr", float "usHQstr", int "usHQth")
{
ss = default( ss, 1.333)
LSFstr = default( LSFstr, 25.0)
usHQstr = default( usHQstr, 0.24)
usHQth = default( usHQth, 28)
# Gestion Upsampling / sharpening / downscaling
ox = clp.width
oy = clp.height
ss_x = round(ss * ox /8)*8
ss_y = round(ss * oy /8)*8
BlackmanResize(clp,taps=4,ss_x,oy)
BlackmanResize(taps=4,last.width,ss_y)
UnsharpHQ(THRESHOLD=usHQth,SHARPSTR=usHQstr,sMOOTH=0,SHOW=false)
LimitedSharpenFasterHC(strength=LSFstr)
Sharpen(0,0.1045)
BlackmanResize(taps=4,last.width,oy)
BlackmanResize(taps=4,ox,last.height)
Sharpen(0.25,0)
return last
}
ffdshow doit contenir successivement :
1. Filtre avisynth :
SetMemoryMax(768)
SetMTMode(3,8)
ffdshow_source()
SetMTMode(2)
NaturalFullHD(LSFstr=21.25,usHQstr=0.23)
SetMTMode(1)
GetMTMode(false) > 0 ? distributor() : last
2. Filtre Sharpen : swscaler avec les settings :
Luminance sharpening : 1.3
Chroma sharpening : 0
Le rôle de ce filtre est de rétablir un rendu correct des hautes fréquences sur une mire 1-2-3 pixels N&B (horizontale, verticale, damier). Par ailleurs, il donne une image typée "moniteur" avec l'illusion d'un white peak supérieur à 48 nits. Vous pouvez le baisser si nécessaire (en contrôlant sur mire 1-2-3 pixels ce que ça fait...).
(b) Fichiers *.hlsl nécessaires (à placer dans le dossier "Shaders" de MPC-HC) :
Fichier "Gamma Adaptatif.hlsl"
Code : Tout sélectionner
#define FinesseRendu 0 // 0: très fin, 1: fin, 2: moyen, 3: grossier
#define diff 0.49
#define ICG 5.0
sampler s0 : register(s0);
float4 p1 : register(c1);
#define dx (p1[0])
#define dy (p1[1])
float4 main( float2 tex : TEXCOORD0 ) : COLOR
{
// pixels original et corrigé
float4 ori = tex2D(s0, tex);
float4 cori;
float seuil = 0.82 + FinesseRendu/100;
// récupération de la matrice de 9 points
// [ 1, 2 , 3 ]
// [ 4,ori, 5 ]
// [ 6, 7 , 8 ]
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));
// détection des contours
// par filtre de sobel
float delta1,delta2,value;
// Gradient horizontal sur image N&B REC709
// [ -1, 0 ,1 ]
// [ -2, 0, 2 ]
// [ -1, 0 ,1 ]
delta1 = dot((c3 + 2*c5 + c8)-(c1 + 2*c4 + c6),float4(0.2126,0.7152,0.0722,0));
// Gradient vertical sur image N&B REC709
// [ -1,- 2,-1 ]
// [ 0, 0, 0 ]
// [ 1, 2, 1 ]
delta2 = dot((c6 + 2*c7 + c8)-(c1 + 2*c2 + c3),float4(0.2126,0.7152,0.0722,0));
// calcul
value = sqrt(mul(delta1,delta1) + mul(delta2,delta2)) ;
// Gamma adaptatif à proximité d'une transition
cori = ori;
if ((value >= seuil-diff*1.15)&&(value <= seuil)) cori = pow(ori,1./(1-value/(10.5-ICG/10)));
return cori;
}
Fichier "Gamma Lineaire.hlsl"
Code : Tout sélectionner
sampler s0 : register(s0);
float4 p1 : register(c1);
#define dy (p1[1])
#define g 1.056 // à adapter au diffuseur
float4 main( float2 tex : TEXCOORD0 ) : COLOR
{ float4 color;
color = tex2D(s0, tex);
return pow(color,g);
}
Dans le fichier "Gamma Lineaire.hlsl", la valeur g à 1.056 est celle qui a été utilisée pour le Benq W2000 réglé sur un gamma natif de 2.2 pour augmenter son gamma à une valeur cohérente par rapport au traitement fait par le gamma adaptatif (afin de s'approcher d'un gamma 2.4 en induisant une sensation d'augmentation de dynamique). Vous pouvez la modifier comme bon vous semble.
Dans "Effets vidéo" de MPC-HC : créer le profil suivant qui doit agir dans "Effets post-redimensionnement" :
Gamma Adaptatif
Gamma Lineaire
L'image qui rentre dans le renderer madVR est en 1920x1080. Aucun sharpen n'est nécessaire ds madVR. Pour l'upscaling du chroma 4:2:0 vers 4:4:4, vous prenez l'algo qui vous fait plaisir... MadVR n'a aucun role de post-traitement sur un diffuseur fullHD (il en aurait un sur un diffuseur UHD pour faire l'upsampling x2).
@+
Emmanuel