Algo Remplacement palette couleurs par une autre
15 sujets de 1 à 15 (sur un total de 17)
- 1
- 2
-
Ouais c’est de la réduction de couleur quoi. Moi dans mon plugin pour grafx2 (source fournies), je fais comme ca (en simplifiant):
1) si la palette finale n’est pas prédéfinie, la définir à partir de l’image initiale. Cela passe par un algo de réduction de couleurs. Il y en a beaucoup, mais l’un de ceux qui marche le mieux est basé sur l’oct-tree
2) Une fois la palette (pré)définie, pour chaque pixel de l’image, trouver la couleur de la palette la plus proche et sortir un pixel avec cette couleur. Pour cela il faut déterminer une « proximité » entre deux couleurs. Il y a des algos plus ou moins sophistiqués pour ca, mais le plus simple est d’utiliser la distance euclidienne entre les composantes R/G/B de la couleur à remplacer et la couleur de la palette. On affiche alors la couleur de la palette qui a la plus petite distance euclidienne avec la couleur source. Avec ca tu as déjà un 1er niveau de conversion qui rend pas mal, mais suivant le fait que la différence de couleur entre l’image de départ et la palette utilisée est important on peut avoir une image visuellement nettement moins belle que celle d’origine.
3) (optionnel) Pour amméiorer la qualité, en plus de remplacer la couleur d’origine par la plus proche dans la palette, on peut calculer un terme d’erreur qu’on répends sur les pixels non encore converti. Cela s’appelle la diffusion d’erreur. Il y en a plein, mais la plus connue est l’algorithme de Floyd-Steinberg.
Points clefs:
* Réduction de couleur : https://en.wikipedia.org/wiki/Color_quantization
* octtree : http://www.leptonica.com/papers/colorquant.pdf ou http://www.cubic.org/docs/octree.htm
* Proximité entre couleur : https://en.wikipedia.org/wiki/Color_difference
* Diffusion d’erreur : https://en.wikipedia.org/wiki/Error_diffusionSinon si tu ne veux pas coder, il y a plein d’outils qui te feront cela en quelque clics.
Samuel.
Amiga A500 + GVP530 (8Mo/fpu/mmu/scsi) - en panne 🙁
A500 (+ 1Mo PPS), A1200 (Blizzard-IV/fpu/64Mo)
A500 Vampire V2+ ^8^ 🙂
(mais aussi TO8, TO8D, TO9. Groupe PULS.)_sam_
Merci pour ton retour en faite c’est surtout la partie « Proximité entre couleur » qui m’intéresse vu que je code en hollywood (lua) les fonctions réduction de couleur et diffusion d’erreur existent déjà
Sinon lien que tu donne pour « Proximité entre couleur » c’est des formules et là je n’y capte rien :-/
PS: bravo pour tes algo graphx2 tu t’es bien cassé la tête visiblement 🙂
Ah ben la distance entre couleur c’est essentiellement du calcul en effet. Il n’est pas besoin de les comprendre, il faut juste les coder comme il faut et ca marche.
Comme tu connais LUA tu peux regdarder mon fichier « Color.lua », il contient un certain nombre de ces calculs.
Samuel.
Amiga A500 + GVP530 (8Mo/fpu/mmu/scsi) - en panne 🙁
A500 (+ 1Mo PPS), A1200 (Blizzard-IV/fpu/64Mo)
A500 Vampire V2+ ^8^ 🙂
(mais aussi TO8, TO8D, TO9. Groupe PULS.)J’ai regarder ton code c’est chaud pour moi :-/
Je vais essayer de le faire à ma façon
Mais j’ai encore une question du coup!
Je prend une image je la converti en 8 couleurs
J’ai une couleur par exemple qui vaut : 128,0,0
et dans la palette que je veux utilisé pour convertir les couleurs de mon image j’ai deux couleurs qui on la même distance:
par exemple : 127,0,0 et 129,0,0 donc comment je fait pour choisir??
Hello
En fait tout est basé sur l’erreur : cad la distance entre la couleur r g b voulue et celle r2 g2 b2 finalement choisie
cad pour un pixel r g b voulu
on a (disons) 16 couleurs possibles de la palette
r[0] à r[15]
g[0] à g[15]
b[0] à b[15]Pour chaque pixel r g b de l’image
{Pour chaque couleurs possibles de la palette on fait la différence
{
dr=r – r[n]; // distance en rouge
dg=g – g[n]; // distance en vert
db=b – b[n]; // distance en bleu
distance2 = dr*dr + dg*dg + db*db; // distance couleur au carré
si(n==0)
min=distance2; // init du min par defaut
si(min>distance2) // si couleur la plus proche
{
min=distance2;
col=n;
}
}r2=r[col];
g2=g[col];
b2=b[col];}
> j’ai deux couleurs qui on la même distance comment je fait pour choisir?
pour alterner automatiquement ces 2 couleurs il faut garder l’erreur d’un pixel à l’autre
Au début on a erreurR=0; erreurG=0; erreurB=0; puisqu’on a pas commencé 😛Donc au tout début on ajoute l’erreur au pixel voulu (cad la quantité de couleur qu’on a pas pu intéger au pixel précédent)
r=erreurR + r;
g=erreurG + g;
b=erreurB + b;A la toute fin on obtient la nouvelle erreur (cad la quantité de couleur qu’on a pas pu intéger à ce pixel r2 g2 b2)
erreurR = r – r2;
erreurG = g – g2;
erreurB = b – b2;pour résumer:
Pour chaque ligne de l’image
{
erreurR=0; erreurG=0; erreurB=0;Pour chaque pixel r g b de cette ligne de l’image
{
r=erreurR + r;
g=erreurG + g;
b=erreurB + b;Pour chaque couleurs possibles de la palette on fait la différence
{
dr=r – r[n]; // distance en rouge
dg=g – g[n]; // distance en vert
db=b – b[n]; // distance en bleu
distance2 = dr*dr + dg*dg + db*db; // distance couleur au carré
si(n==0)
min=distance2; // init du min par defaut
si(min>distance2) // si couleur la plus proche
{
min=distance2;
col=n;
}
}r2=r[col];
g2=g[col];
b2=b[col];erreurR = r – r2;
erreurG = g – g2;
erreurB = b – b2;}
}J’ai une couleur par exemple qui vaut : 128,0,0
et dans la palette que je veux utilisé pour convertir les couleurs de mon image j’ai deux couleurs qui on la même distance:
par exemple : 127,0,0 et 129,0,0 donc comment je fait pour choisir??
Tout dépend de la fonction distance utilisée. Avec la distance euclidienne, tes deux dernières couleurs sont à égale distance de 128,0,0. Mais en utilisant une autre fonction de distance ce n’est pas forcément le cas. Typiquement tu peux prendre une fonction de distance qui respecte un peu mieux la proximité de couleurs perçue par l’oeuil humain que la distance euclidienne.
Il y en a tout plein de décrites ici: https://en.wikipedia.org/wiki/Color_difference qui sont plus ou moins sophistiquées. La version pondérée de la distance euclidienne est déjà une première approximation utilisable: https://www.compuphase.com/cmetric.htm
Maintenant, en pratique, tu aura toujours 2 couleurs à égale distance. Mais ca n’est pas grave, leur égale distance signifie que l’une n’est pas meilleure que l’autre, donc tu peux utiliser au choix l’une ou l’autre (avec par exemple un tirage aléatoire pour choisir entre les 2 si tu veux maintenir une certaine diversité.)
Samuel.
Amiga A500 + GVP530 (8Mo/fpu/mmu/scsi) - en panne 🙁
A500 (+ 1Mo PPS), A1200 (Blizzard-IV/fpu/64Mo)
A500 Vampire V2+ ^8^ 🙂
(mais aussi TO8, TO8D, TO9. Groupe PULS.)>couleurs au choix l’une ou l’autre (avec par exemple un tirage aléatoire pour choisir entre les 2 si tu veux maintenir une certaine diversité
Je vois que vous n’avez pas assimilé le concept de transmission d’erreur et pourquoi il résout ce problème de la meilleure manière en créant des tramage reconstituant la bonne teinte
Couleur voulue
128 0 0
Palette
127 0 0
129 0 01er pixel: on prend 129 0 0 car mon algo explore la palette dans l’ordre et cette couleur est la dernière qui convient (aussi)
erreur -1 0 0 (cad 128-129 0-0 0-0)2eme pixel: couleur voulue 128-1 0+0 0+0 (couleur voulue + erreur)
==> cette fois on va prendre 127 0 0
erreur 0 0 03eme pixel: couleur voulue 128+0 0+0 0+0 (couleur voulue + erreur)
on prend 129 0 0 car mon algo explore la palette dans l’ordre et cette couleur est la dernière qui convient (aussi)
erreur -1 0 0 (cad 128 – 129 )4eme pixel: couleur voulue 128-1 0+0 0+0 (couleur voulue + erreur)
==> cette fois on va prendre 127 0 0
erreur 0 0 0Attention de ne pas transmettre l’erreur à la ligne suivante ce qui serait laid donc erreur = 0 0 0 en début de ligne
Je vois que vous n’avez pas assimilé le concept de transmission d’erreur
lol, tu n’as visiblement pas lu ce que sinisrus a écrit:
Par contre je ne travail pas pixel par pixel mais directement sur la palette de l’image
Le monsieur ne travaille pas au niveau de l’image mais de la palette et de la palette seule. Donc exit la dispersion d’erreur. C’est un tout autre sujet.
(en passant, si on veut faire de la dispersion d’erreur, il ne faut pas la disperser sur le prochain pixel à traiter à droite/gauche, mais aussi sur la ou les lignes en dessous, cf la matrice de Jarvis: https://en.wikipedia.org/wiki/Error_diffusion (rien à voir avec iron-man 🙂 ), ou encore avec des matrices dynamiques respectant la structure de l’image: https://liris.cnrs.fr/victor.ostromoukhov/publications/pdf/SIGGRAPH-ASIA09_saed.pdf)
Samuel.
Amiga A500 + GVP530 (8Mo/fpu/mmu/scsi) - en panne 🙁
A500 (+ 1Mo PPS), A1200 (Blizzard-IV/fpu/64Mo)
A500 Vampire V2+ ^8^ 🙂
(mais aussi TO8, TO8D, TO9. Groupe PULS.)J’ai une autre question
Je ne trouve pas comment faire autrement pour créer la liste des couleurs contenu dans une image
je converti mon image en tableau et je cherche les couleurs que j’ajoute dans un autre tableau.
Le problème c’est que plus l’image est grande plus c’est long!!!
Il doit bien y avoir un moyen plus rapide par exemple dans le fichier image il doit bien y avoir un index avec la liste des couleurs??
15 sujets de 1 à 15 (sur un total de 17)
- 1
- 2
- Vous devez être connecté pour répondre à ce sujet.
› Forums › AmigaOS, MorphOS et AROS › Développement › Algo Remplacement palette couleurs par une autre