voici un petit code assez basique pour un equalizer vidéo implanté en PS.
On peut sans pb adapter le code pour mettre autant de point de contrôle qu'on veut.
L'interpolation est linéaire entre chaque point donc ça reste basique mais en général suffisant pour des corrections légères.
Je n'ai pas optimisé le code pour gagner en lisibilité.
L'exemple fourni correspond à une courbe "physiologique" en M qui fonctionne bien pour les projos avec une résiduelle élevée, un CR on:off limité et une bonne luminosité (DLP par exemple).
Ca consiste à booster le CR ds les bas et moyen IRE, à le tasser un peu puis à le rebooster un peu ds les IRE élevés et à le tasser tranquillement sur la fin.
En équivalence audio, c'est comme un léger boost ds le grave/bas médium, un petit creux ds le haut médium puis un petit boost ds l'aigu et un tassement ds l'extrême aigu.
En générale, ça booste bien l'image...
On définit les points de contrôle l1, l2, l3 etc. dans un intervalle compris entre 0 et 255 (entrées in).
les corrections d correspondantes sont des offsets verticaux par rapport à une sortie linéaire c-à-d que pour chaque point de contrôle, on a :
out = in + d
Entre les pts de contrôle, l'interpolation du niv de sortie est linéaire.
Avant cet ajustement, on peut faire une correction gamma classique en ajustant le param gamma. C'est en général comme cela que c'est implémenté sur les projos qui permettent un ajustement du coeff gamma suivi d'un ajustement fin par equalizer vidéo pour peaufiner les niveaux de sortie.
Ce pixel shader est à mettre en bout de chaîne et est uniqt adapté à des niveaux de sortie entre 0 et 255 (hdmi étendu).
A noter que le programme serait facilement adaptable pour faire une correction 1D-LUT de la courbe des gris ... Il suffit d'ajouter des corrections indépendantes pour chaque canal au lieu d'avoir des corrections identiques.
- Code: Tout sélectionner
// vidéo equalizer basique par interpolation linéaire
sampler s0 : register(s0);
float4 p1 : register(c1);
// correction gamma dépendante du gamma natif du projo
#define gamma 1.0
// Video equalizer avec 7 points de contrôle entre 0 et 255
#define l1 32
#define d1 2
#define l2 64
#define d2 2.25
#define l3 96
#define d3 2.5
#define l4 128
#define d4 2.25
#define l5 160
#define d5 2.5
#define l6 192
#define d6 2.25
#define l7 224
#define d7 2
float4 main( float2 tex : TEXCOORD0 ) : COLOR
{ float4 color;
float g1, g2, g3, g4, g5, g6, g7;
float o1, o2, o3, o4, o5, o6, o7;
color = pow(tex2D(s0, tex),gamma);
g1 = 1.0*l1/255; o1 = 1.0*d1/255;
g2 = 1.0*l2/255; o2 = 1.0*d2/255;
g3 = 1.0*l3/255; o3 = 1.0*d3/255;
g4 = 1.0*l4/255; o4 = 1.0*d4/255;
g5 = 1.0*l5/255; o5 = 1.0*d5/255;
g6 = 1.0*l6/255; o6 = 1.0*d6/255;
g7 = 1.0*l7/255; o7 = 1.0*d7/255;
// traitement du rouge
if (color.r <= g1) color.r = (g1+o1)/g1*color.r;
else if (color.r <= g2) color.r = ((g2-g1+o2-o1)*color.r + o1*g2-o2*g1)/(g2-g1);
else if (color.r <= g3) color.r = ((g3-g2+o3-o2)*color.r + o2*g3-o3*g2)/(g3-g2);
else if (color.r <= g4) color.r = ((g4-g3+o4-o3)*color.r + o3*g4-o4*g3)/(g4-g3);
else if (color.r <= g5) color.r = ((g5-g4+o5-o4)*color.r + o4*g5-o5*g4)/(g5-g4);
else if (color.r <= g6) color.r = ((g6-g5+o6-o5)*color.r + o5*g6-o6*g5)/(g6-g5);
else if (color.r <= g7) color.r = ((g7-g6+o7-o6)*color.r + o6*g7-o7*g6)/(g7-g6);
else color.r = ((1.0-g7-o7)*color.r + o7)/(1.0-g7);
// traitement du vert
if (color.g <= g1) color.g = (g1+o1)/g1*color.g;
else if (color.g <= g2) color.g = ((g2-g1+o2-o1)*color.g + o1*g2-o2*g1)/(g2-g1);
else if (color.g <= g3) color.g = ((g3-g2+o3-o2)*color.g + o2*g3-o3*g2)/(g3-g2);
else if (color.g <= g4) color.g = ((g4-g3+o4-o3)*color.g + o3*g4-o4*g3)/(g4-g3);
else if (color.g <= g5) color.g = ((g5-g4+o5-o4)*color.g + o4*g5-o5*g4)/(g5-g4);
else if (color.g <= g6) color.g = ((g6-g5+o6-o5)*color.g + o5*g6-o6*g5)/(g6-g5);
else if (color.g <= g7) color.g = ((g7-g6+o7-o6)*color.g + o6*g7-o7*g6)/(g7-g6);
else color.g = ((1.0-g7-o7)*color.g + o7)/(1.0-g7);
// traitement du bleu
if (color.b <= g1) color.b = (g1+o1)/g1*color.b;
else if (color.b <= g2) color.b = ((g2-g1+o2-o1)*color.b + o1*g2-o2*g1)/(g2-g1);
else if (color.b <= g3) color.b = ((g3-g2+o3-o2)*color.b + o2*g3-o3*g2)/(g3-g2);
else if (color.b <= g4) color.b = ((g4-g3+o4-o3)*color.b + o3*g4-o4*g3)/(g4-g3);
else if (color.b <= g5) color.b = ((g5-g4+o5-o4)*color.b + o4*g5-o5*g4)/(g5-g4);
else if (color.b <= g6) color.b = ((g6-g5+o6-o5)*color.b + o5*g6-o6*g5)/(g6-g5);
else if (color.b <= g7) color.b = ((g7-g6+o7-o6)*color.b + o6*g7-o7*g6)/(g7-g6);
else color.b = ((1.0-g7-o7)*color.b + o7)/(1.0-g7);
return color;
}
@+
Emmanuel