[résolu] Génération palette RVB pour avoir des superpositions uniques

Génération palette RVB pour avoir des superpositions uniques [résolu] - Algo - Programmation

Marsh Posté le 22-02-2024 à 13:37:30    

Bonjour,
Je cherche un moyen de générer une palette de couleurs RVB (au moins 20) de manière à ce quelle que soit la superposition par addition de ces couleurs sur un pixel donné, ça me donne un code RVB unique, me permettant ainsi de retrouver la combinaison de couleurs ayant donné lieu à ce code couleur. Bien évidemment, si j'additionne les toutes les couleurs de ma palette, ça ne doit pas dépasser 255, 255, 255. Une même couleurs ne peut être présente qu'une seule fois dans l'addition des couleurs d'un pixel.
 
Ex avec 3 couleurs
C1 = 128, 0, 0
C2 = 0, 128, 0
C3 = 0, 0, 128
 
On voit bien que si j'ai un pixel qui vaut 128, 128, 0, je sais dire que c'est C1 + C2.
 
Merci :)
 
Edit : j'ai bien pensé aux puissances de 2 (2, 4, 8, 16, ..., 128) mais ça ne me fait "que" 19 couleurs. Le 0, 0, 0 ne compte pas.


Message édité par rufo le 25-02-2024 à 16:34:51

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 22-02-2024 à 13:37:30   

Reply

Marsh Posté le 22-02-2024 à 18:00:54    

Je dirais a vue de nez que tu ne peux avoir que les valeur 1, 2, 4, 8, 16, 32, 64, 128 pour chaque canal donc 8 x 3 couleurs 24 coloris, c'est déjà pas mal, et ça te garantit l'unicité.
Il n'y qu'une façon d'avoir chaque chiffre entre 1 et 255 inclus et je ne suis pas sur qu'on puisse faire mieux que ça...
Après pour voir si tu as une valeur dans un canal tu fait un truc de ce genre.

Code :
  1. if (($pixels['r'] & 128) == 128)


Mais je ne sais plus comment on appelle cette façon de comparer.
J'avais fait un truc comme ça pour gérer des droits basique sous forme numérique en m'inspirant du chmod mais c'est vieux tout ça...  :o


---------------
D3
Reply

Marsh Posté le 22-02-2024 à 19:06:59    

Ca s'appelle le masquage de bit où tu peux faire varier la valeur du masque (ici, 128). Je me sers de cette technique en BD quand j'ai une série d'options qu'un objet peut avoir ou pas. Plutôt que de faire un champ par option, j'utilise un seul champ de type entier où chaque bit de ce nb représente une option. Du coup, la recherche des objets dans une table d'une BD qui ont telle(s) ou telle(s) option(s) se fait très simplement avec un "WHERE mon-champ & masque" ou "masque" représente les options à 1. Ca semble plsu trop enseigné en IUT, BTS ou école d'ingé cette façon de faire, j'ai l'impression. Mes 2 derniers stagiaires n'en avaient jamais entendu parler :/
 
Pour l'instant, c'est cette fonction que j'utilise pour générer ma palette de couleurs. C'était juste par curiosité mathématique que je me demandais s'il n'existait pas d'autres fonctions de ce type.
Mais effectivement, 24 couleurs, ça devrait être suffisant pour mon cas d'usage.


Message édité par rufo le 22-02-2024 à 19:10:14

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 23-02-2024 à 08:43:38    

Masquage de bit, merci, je m'en étais servi pour la même chose (sur une aplli j'étais monté jusqu'à 2048 à force d'ajouter des droits [:nedurb] ).
 
Après j'ai repensé cette nuit que tu ne pourrais pas vraiment faire 3 x 8 car les canaux de couleurs sont indépendant et une fois additionné tu ne pourras pas distinguer certain empilement de couleurs.
Par exemple si on a cette palette :
c1:1,2,4
c2:2,1,4
c3:1,2,1
c4:2,1,1
Et qu'un pixel à la valeur : 3,3,5 on a malheureusement deux façon de le faire...
 
C'est ptet possible en éliminant des combinaisons (tirage aléatoire sans remise :o => 8+7+6 => 21 combinaisons), genre si tu as 1 en R tu ne peux pas l'avoir en G ou en B et si tu as 2 en G il sera aussi interdit en B.
Mais comme tu appliques un grand nombres de couleurs additionné sur le même pixel, je penses que ça ne va pas suffire, j'ai bien peur qu'il faille vraiment que chaque canal soit "unique"....


---------------
D3
Reply

Marsh Posté le 23-02-2024 à 09:38:57    

Avec l'ex que tu donnes, ta palette a bien plus que 21 (ou 24) couleurs en tout. Ma palette a des canaux à une composante > 0. Je vais donc avoir :
c1 : 2, 0, 0
c2 : 0, 2, 0
c3 : 0, 0, 2
c4 : 4, 0, 0
...
Donc a priori, pas de pb quand je vais faire des sommes. Une couleur ayant 2 ou 3 canaux > 0 me permettra de savoir que c'est forcément issu d'une somme et pas d'une couleur de ma palette.
Mon hypothèse de base est que si sur un canal, la valeur issue d'une somme ne peut être décomposée que d'une manière unique et que les couleurs de ma palette ont qu'une seule composante > 0, alors les couleurs obtenus seront issue d'une somme unique des 3 composantes et je pourrai retrouver facilement les couleurs d'origine en décomposant la valeur de chaque composante de la valeur issue de la somme. :)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 23-02-2024 à 09:43:17    

Edit: ah oui ok, j'étais sur 8*8*8 puis sur 8*7*6, n'importe quoi [:nedurb], donc ça peut le faire...


Message édité par mechkurt le 23-02-2024 à 09:47:34

---------------
D3
Reply

Marsh Posté le 23-02-2024 à 09:51:28    

Normalement oui. J'ai 3 sommes indépendantes, chacune pouvant être décomposée de manière unique.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 25-02-2024 à 10:38:52    

Si C note l'ensemble {0, 1, 2, 4, 8, 16, 32, 64, 128}, je ne vois pas mieux (ni même autrement que C, si tu veux l'unicité de la décomposition) que l'ensemble des triplets de la forme (c, 0, 0) ou (0, c, 0) ou (0, 0, c) ou c est un élément de C.
Ça fait donc 9+9+9-2 (car (0, 0, 0) est commun aux trois sortes de triplets, soit 25 couleurs "de base".
Si C* note {0, 1, 2, 4, 8, 16, 32, 64, 128}, pour chaque couleur (r, v, b)  
- soit la couleur est (0, 0, 0)  
- soit tu peux la décomposer en une somme de 1 a au plus 3 composants (r, 0, 0), (0, v, 0) et (0, 0, b) avec alors r, v, b dans C*
  Ça se ramène donc a décomposer chacun de ces 1 a 3 composants, donc a la décomposition unique de r, v ou b (dans C*) en somme de valeurs dans {1, 2, 4, 8, 16, 32, 64, 128}. Et l'algo de décomposition d'une valeur n est immédiat :  
               trouver la première valeur x en parcourant {1, 2, 4, 8, 16, 32, 64, 128} de manière décroissante, ajouter x a la liste des valeurs de décomposition
               si (n-x = 0) arrêter, sinon reboucler l'algo avec (n-x)
 
En fait, avec ton critère de décomposition unique en une somme de couleurs de ta palette, chacune ne figurant qu'une seule fois, on voit même que c'est la seule solution :
On met le cas de (0, 0, 0) a part.
On regarde le cas de (r, 0, 0) ou r est dans 1..255, ça équivaut à la décomposition de r. Donc il faut trouver un ensemble S d'entiers tel que tout entier naturel entre 1 et 255 se décompose en une somme unique d'éléments de S, chacun ne pouvant figurer qu'une seule fois dans la somme.
On peut voir facilement que S doit être {1, 2, 4, 8, 16, 32, 64, 128} :  
Si n est un entier positif alors tout entier positif strictement inférieur a 2^n se décompose en une somme unique Somme de 0 a n-1 de c(i)*2^i ou c(i) est 0 ou 1
Ça se démontre par récurrence :  
si n = 1, alors le seul entier positif strictement inférieur a 2^1 est 1 qui vaut a la décomposition unique 2^0
Si la propriété est vraie jusqu'à n-1, alors soit m un entier positif strictement inférieur a 2^n.
 - soit m est un entier positif strictement inférieur a 2^(n-1) et donc il a une décomposition unique
 - soit il vaut 2^(n-1) et on a la décomposition unique (facile a montrer en utilisant le fait que Somme de 0 a k de 2^i vaut (2^(k+1))-1 qui se montre aussi par récurrence)
 - soit m est compris entre 2^(n-1)+1 et (2^n)-1 et donc il peut s'écrire sous la forme 2^(n-1) + m', avec m' compris entre 1 et ((2^n)-1)-(2^(n-1)) = 2^(n-1) + 2^(n-1) - 1 - 2^(n-1) = 2^(n-1) - 1 bref m' est un entier positif strictement inférieur a 2^(n-1) et il a une décomposition unique, d’où la décomposition unique de m.
 
Bon, une fois ceci établi, on voit que la palette a 25 couleurs est suffisante, via la décomposition indiquée plus haut.
On peut montrer qu'elle est nécessaire, car aucune des couleurs de la palette ne peut être générée comme somme des autres couleurs de la palette.
 
A+,


Message édité par gilou le 25-02-2024 à 12:35:22

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 25-02-2024 à 16:34:25    

Merci Gilou d'avoir pris le temps de formaliser mathématiquement ce que mon intuition me disait. A noter que la couleur noir 0,0,0 n'est pas dans ma palette car c'est la couleur de fond de mes images. Par ailleurs, je dois m'arrêter à 128 sur chacune des composantes pour pas que la somme totale de touts le couleurs précédentes sur une même composante dépasse 255.
En fait, pour avoir une décomposition unique et pas dépasser 255 sur une composante, ma suite doit avoir comme propriété que le terme N doit être > à la somme de ses termes précédents et le dernier terme doit être <= 128.
Du coup, il n'y a que la suite des puissances de 2 qui répond à ces critères. Ca me fait 24 couleurs, c'est suffisant pour le pb qui m'occupe :)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed