La couleur dans le système HSV
Transcription
La couleur dans le système HSV
La couleur dans le système HSV 1. Introduction Le système HSV (Hue, Saturation, Value) est un mode de coloration des images qui se révèle souvent plus efficace que le système classique RGB (Red, Green, Blue), notamment pour les images fractales. Dans cet article nous verrons comment passer d'un système à l'autre, grâce à des procédures écrites en PANORAMIC. 2. Description du système HSV Le système HSV est représenté en coordonnées cylindriques sur cette image tirée de Wikipedia : • La teinte (Hue) se lit sur un cercle : elle est codée par un angle entre 0 et 360°. En fixant la saturation et la luminosité (Value) à leurs valeurs maximales, on a les correspondances suivantes : H 0 60 120 180 240 300 R 255 255 0 0 0 255 G 0 255 255 255 0 0 B 0 0 0 255 255 255 1 Couleur Rouge Jaune Vert Turquoise (Cyan) Bleu Magenta Dans les mêmes conditions (S = V = 1), en faisant varier H de 0 à 360° on obtient un gradient de couleurs : • La saturation se lit sur le rayon du cercle : elle est codée par un nombre entre 0 et 1 (ou par un pourcentage). La saturation traduit la vivacité de la couleur. Les fortes valeurs correspondent à des couleurs vives, les valeurs intermédiaires à des tons pastels. Aux très faibles valeurs, on n'a plus que du gris plus ou moins foncé suivant la luminosité. En prenant comme exemple la couleur rouge (H = 0), en fixant V = 1 (luminosité maximale) et en faisant varier S de 0 à 1 on obtient un gradient qui va du blanc jusqu'au rouge vif : • La luminosité (Value) se lit sur la coordonnée verticale : tout comme la saturation, elle s'exprime par un nombre entre 0 et 1. En augmentant la luminosité, on va du noir vers la couleur spécifiée par H. En gardant la couleur rouge (H = 0), en fixant S = 1 (saturation maximale) et en faisant varier V de 0 à 1 on obtient un gradient qui va du noir jusqu'au rouge vif : • Si maintenant on se place au centre du cercle (S = 0 et H quelconque) et que l'on fasse varier V de 0 à 1 on obtient une échelle de gris : Note : tous les gradients présentés dans ce paragraphe ont été générés à l'aide de la procédure HSV_Gradient écrite en PANORAMIC et que nous décrirons plus loin. 2 3. La conversion RGB/HSV Les algorithmes de conversion sont classiques. On les trouve par exemple sur Wikipedia. Ici nous les avons codés sous la forme d'une bibliothèque de procédures (SUBs) pour PANORAMIC. Comme pour nos autres bibliothèques, nous utilisons deux fichiers à inclure : • un fichier rgb_vars.inc contenant les déclarations des variables globales : ' ******************************************************************* ' Variables globales des procedures de conversion RGB/HSV ' ******************************************************************* dim RGB_R%, RGB_G%, RGB_B% dim HSV_H dim HSV_S, HSV_V : ' 0..255 : ' 0..360 : ' 0..1 dim RGB_Hex$ : ' Code RGB en hexadecimal (ex. 0A1B2C) ' ******************************************************************* • un fichier rgb_subs.inc contenant les procédures : ' ******************************************************************* ' Procedures de conversion RGB/HSV ' ******************************************************************* ' Adapte de http://www.cs.rit.edu/~ncs/color/t_convert.html ' R, G, B = [0..255] ' H = [0..360], S = [0..1], V = [0..1] ' si S = 0, H = 0 par defaut ' ******************************************************************* sub RGBtoHSV(R%, G%, B%) ' Conversion RGB --> HSV ' Resultat dans HSV_H, HSV_S, HSV_V dim_local RR, GG, BB, Mini, Maxi, Delta RR = R% / 255 GG = G% / 255 BB = B% / 255 Mini = RR if GG < Mini then Mini = GG if BB < Mini then Mini = BB 3 Maxi = RR if GG > Maxi then Maxi = GG if BB > Maxi then Maxi = BB HSV_V = Maxi if (Maxi = 0) or (Maxi = Mini) HSV_S = 0 HSV_H = 0 exit_sub end_if Delta = Maxi - Mini HSV_S = Delta / Maxi if RR = Maxi then HSV_H = (GG - BB) / Delta : ' entre jaune & magenta if GG = Maxi then HSV_H = 2 + (BB - RR) / Delta : ' entre cyan & jaune if BB = Maxi then HSV_H = 4 + (RR - GG) / Delta : ' entre magenta & cyan HSV_H = HSV_H * 60 if HSV_H < 0 then HSV_H = HSV_H + 360 : ' degres end_sub sub HSVtoRGB(H, S, V) ' Conversion HSV --> RGB ' Resultat dans RGB_R%, RGB_G%, RGB_B% if S = 0 RGB_R% = int(V * 255) RGB_G% = RGB_R% RGB_B% = RGB_R% exit_sub end_if dim_local I%, Z, F, P, Q, T, RR, GG, BB Z = H / 60 I% = int(Z) F = frac(Z) P = V * (1 - S) Q = V * (1 - S * F) T = V * (1 - S * (1 - F)) 4 select I% case 0 RR = V : GG = T : BB = P case 1 RR = Q : GG = V : BB = P case 2 RR = P : GG = V : BB = T case 3 RR = P : GG = Q : BB = V case 4 RR = T : GG = P : BB = V case 5 RR = V : GG = P : BB = Q end_select RGB_R% = int(RR * 255) RGB_G% = int(GG * 255) RGB_B% = int(BB * 255) end_sub sub RGBtoHex(R%, G%, B%) ' Convertit le code RGB en une chaine de 6 caracteres ("0A0BCC" ...) ' Resultat dans RGB_Hex$ dim_local RH$, GH$, BH$ RH$ = Hex$(R%) : if R% < 16 then RH$ = "0" + RH$ GH$ = Hex$(G%) : if G% < 16 then GH$ = "0" + GH$ BH$ = Hex$(B%) : if B% < 16 then BH$ = "0" + BH$ RGB_Hex$ = RH$ + GH$ + BH$ end_sub sub HSV_Gradient(Object%, Orient%, iP%, Pmin, Pmax, PC1, PC2) ' Dessine un gradient de couleurs en faisant varier un des ' parametres H, S ou V tout en maintenant les 2 autres constants ' Object% = numero de l'objet sur lequel on dessine ' Orient% = orientation du gradient : 1 = vertical, 2 = horizontal ' iP% = indice du parametre variable : 1 = H, 2 = S, 3 = V ' Pmin, Pmax = bornes du parametre variable ' PC1, PC2 = valeurs des parametres constants (dans l'ordre H, S, V) 5 dim_local h%, w%, i%, imax%, Scale, P h% = height(Object%) w% = width(Object%) select Orient% case 1 : imax% = w% case 2 : imax% = h% end_select Scale = (Pmax - Pmin) / imax% 2d_target_is Object% for i% = 0 to imax% P = Pmin + i% * Scale if iP% = 1 HSVtoRGB(P, PC1, PC2) else if iP% = 2 HSVtoRGB(PC1, P, PC2) else HSVtoRGB(PC1, PC2, P) end_if end_if 2d_pen_color RGB_R%, RGB_G%, RGB_B% select Orient% case 1 : 2d_line i%, 0, i%, h% case 2 : 2d_line 0, i%, w%, i% end_select next i% end_sub 6 4. Un programme de conversion en PANORAMIC Le programme suivant permet de passer d'un système à l'autre, ainsi que d'exprimer les codes RGB sous forme hexadécimale (utilisée par exemple dans les pages HTML). Ce programme utilise les procédures KGF_OBJ de Klaus pour définir les objets. Vous aurez besoin du fichier à inclure KGF_OBJ.bas, que l'on trouve ici ' ******************************************************************* ' Conversion RGB/HSV ' ******************************************************************* ' Variables globales des procedures #include "rgb_vars.inc" ' Variables globales du programme principal dim R%, G%, B%, H, S, V ' ------------------------------------------' Description des objets ' ------------------------------------------' Fenêtre principale (0) top 0, 200 left 0, 220 width 0, 390 height 0, 250 caption 0, "Conversion HSV / RGB" ' Spins 1-6 (Saisie des données) xSpin( 30, 20, 75, 0, 0, 360) : ' (1) Teinte (Hue) xSpin( 80, 20, 75, 0, 0, 100) : ' (2) Saturation xSpin(130, 20, 75, 0, 0, 100) : ' (3) Luminosite (Value) xSpin( 30, 290, 75, 0, 0, 255) : ' (4) Rouge xSpin( 80, 290, 75, 0, 0, 255) : ' (5) Vert xSpin(130, 290, 75, 0, 0, 255) : ' (6) Bleu ' Boutons 7-8 (Conversions) xButton(180, 20, 75, 0, "HSV --> RGB") 7 xButton(180, 290, 75, 0, "RGB --> HSV") ' Picture 9 (Affichage de la couleur) xPicture(10, 120, 140, 150, 0) ' Labels 10-16 (Etiquettes) xAlpha(185, 120, 0, 8, "Hexadécimal") xAlpha( 10, 20, 0, 8, "Teinte (H)") xAlpha( 60, 20, 0, 8, "Saturation (S)") xAlpha(110, 20, 0, 8, "Luminosité (V)") xAlpha( 10, 290, 0, 8, "Rouge (R)") xAlpha( 60, 290, 0, 8, "Vert (G)") xAlpha(110, 290, 0, 8, "Bleu (B)") ' Edit 17 (Code hexadecimal) xEdit(180, 190, 70, 0, 1) ' ---------------------------------------------' Affectation des sous-programmes aux événements ' ---------------------------------------------label Show_HSV, Show_RGB, HSV_RGB, RGB_HSV on_change 1, Show_HSV on_change 2, Show_HSV on_change 3, Show_HSV on_change 4, Show_RGB on_change 5, Show_RGB on_change 6, Show_RGB on_click 7, HSV_RGB on_click 8, RGB_HSV ' ------------------------------------------' Programme principal ' ------------------------------------------' Demarrer avec un rouge vif 8 position 1, 0 : ' H position 2, 100 : ' S (%) position 3, 100 : ' V (%) position 4, 255 : ' R position 5, 0 : ' G position 6, 0 : ' B gosub Show_RGB end ' ------------------------------------------' Sous-programmes ' ------------------------------------------Show_HSV: H = position(1) S = position(2) / 100 V = position(3) / 100 HSVtoRGB(H, S, V) RGBtoHex(RGB_R%, RGB_G%, RGB_B%) color 9, RGB_R%, RGB_G%, RGB_B% text 17, "#" + RGB_Hex$ return Show_RGB: R% = position(4) G% = position(5) B% = position(6) RGBtoHex(R%, G%, B%) color 9, R%, G%, B% text 17, "#" + RGB_Hex$ return HSV_RGB: HSVtoRGB(H, S, V) position 4, RGB_R% position 5, RGB_G% position 6, RGB_B% 9 return RGB_HSV: RGBtoHSV(R%, G%, B%) position 1, int(HSV_H) position 2, int(100 * HSV_S) position 3, int(100 * HSV_V) return ' ------------------------------------------' Procedures ' ------------------------------------------#include "rgb_subs.inc" #include "KGF_OBJ.bas" A l'exécution, la fenêtre du programme se présente ainsi : La couleur du carré central, ainsi que la valeur hexadécimale, sont mises à jour automatiquement lorsqu'on modifie les valeurs des paramètres. La conversion s'obtient en cliquant sur les boutons. Notez que la saturation et la luminosité sont exprimées en pourcentages. Par ailleurs, les paramètres H, S et V sont arrondis en valeurs entières. Cela peut provoquer de petits décalages lorsqu'on convertit plusieurs fois dans les deux sens. 10 5. Un générateur de gradients en PANORAMIC Ce programme génère des gradients de couleurs en faisant varier un des paramètres H, S ou V tout en maintenant les deux autres fixes. ' ******************************************************************* ' Gradient de couleurs ' ******************************************************************* ' Variables globales des procedures RGB/HSV #include "rgb_vars.inc" ' Variables globales du programme dim xmax%, ymax% xmax% = 400 ymax% = 40 ' ------------------------------------------' Description des objets ' ------------------------------------------' Fenetre principale (0) top 0, 100 left 0, 100 width 0, xmax% + 30 height 0, ymax% + 60 caption 0, "Gradient de couleurs" ' Picture (1) xPicture(10, 10, xmax%, ymax%, 0) ' ------------------------------------------' Programme principal ' ------------------------------------------' Ici on fait varier la teinte (H) de 0 à 360° ' La saturation (S) et la luminosité (V) ont leur valeur maximale (= 1) HSV_Gradient(1, 1, 1, 0, 360, 1, 1) 11 file_save 1, "gradient.bmp" end ' ------------------------------------------' Procedures ' ------------------------------------------#include "rgb_subs.inc" #include "KGF_OBJ.bas" Cet exemple dessine le premier gradient de couleurs du paragraphe 2. Les instructions pour générer les autres gradients sont les suivantes : • Pour le gradient de saturation : HSV_Gradient(1, 1, 2, 0, 1, 0, 1) • Pour le gradient de luminosité : HSV_Gradient(1, 1, 3, 0, 1, 0, 1) • Pour l'échelle de gris : HSV_Gradient(1, 1, 3, 0, 1, 0, 0) 6. Conclusion Nous avons vu dans cet article les bases du système HSV. Ces notions seront utilisées dans un prochain article sur la coloration des images fractales. 12