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

Documents pareils