Algo Remplacement palette couleurs par une autre

15 sujets de 1 à 15 (sur un total de 17)

  • 1
  • 2
  • sinisrus

      #300792

      Salut,

       

      Je cherche un algo pour remplacer la palette d’une image par une autre

      Par example => pour convertir une image avec les couleurs Pico8 ou Ninendo nes etc…

      Merci

      __sam__

        #300817

        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_diffusion

        Sinon 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.)

        sinisrus

          #300844

          _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 🙂

           

          __sam__

            #300848

            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.)

            sinisrus

              #300849

              Ok je regarde ça

              Merci sam 🙂

              sinisrus

                #300850

                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??

                 

                 

                 

                thellier

                  #300851

                  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;

                  sinisrus

                    #300853

                    Merci alain

                    Il faut que je digère ça maintenant 😉

                    thellier

                      #300855

                      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;

                      }
                      }

                      sinisrus

                        #300858

                        Par contre je ne travail pas pixel par pixel mais directement sur la palette de l’image (ça me semble moins lourd) que je remplace par une autre palette

                        __sam__

                          #300926

                          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.)

                          thellier

                            #300930

                            >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 0

                            1er 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 0

                            3eme 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 0

                            Attention de ne pas transmettre l’erreur à la ligne suivante ce qui serait laid donc erreur = 0 0 0 en début de ligne

                            __sam__

                              #300931

                              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.)

                              sinisrus

                                #300935

                                Merci les gars 🙂

                                sinisrus

                                  #301292

                                  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

                                Amiga Impact