Bonjour,
Je possède une image que je veux recréer de la manière la plus réaliste "visuellement". Mais l'image retournée doit être composée uniquement d'une certaine palette de couleurs données. De plus, chacune de ces couleurs ne peut être utilisé qu'un nombre limité de fois. L'image est également redimensionnée (on redéfinit sa hauteur et on garde la proportion), mais ce n'est qu'un détail...
Données:
- image
- liste des couleurs (palette)
- liste des nombres de pixels maximaux pour chaque couleur
- nouvelle hauteur
Résultat:
- image la plus réaliste selon les contraintes
Concrètement, pour moi, cet algorithme sert à générer une image en dominos à partir d'une image d'un ordinateur
pour passer de ça par exemple...
... à ça:
...d'où une contrainte sur les couleurs et le nombre de dominos (pixels).
Dans un premier temps, j'aborde le problème seulement selon les couleurs (pas de limite sur leurs nombres d'utilisation). Une première approche "naïve" consiste alors à définir une distance entre 2 couleurs, et d'affecter à chaque pixel de l'image finale la couleur qui est la plus "proche". [Algo 1]
Dans la mesure où la résolution d'arrivée sera généralement très faible (de l'ordre de 20-30 pixels de hauteur), on ne peut pas envisager par exemple d'alterner des pixels rouges et bleus pour obtenir du violet.
Dans un second temps, en considérant le problème avec les limites de pixels de couleur, j'ai imaginé deux moyens de le prendre en compte:
Le premier est le suivant [Algo 2]:
1) on affecte à chaque couleur de la palette des poids initialement à 1.
2) on applique l'algorithme précédent (Algo 1), en comptant le nombre de chaque pixel utilisé.
3) si une couleur est utilisée trop de fois, on augmente son poids
4) on recommence à l'étape 2), en retenant prenant en compte les poids pour favoriser les couleurs de poids faible.
A chaque itération le nombre de pixels pour chaque couleurs devrait se rapprocher de leur limite, et finir par tous passer en dessous.
Cependant, on ne peut pas savoir de combien augmenter les poids à chaque fois, et la terminaison n'est pas assurée...
Le second est le suivant [Algo 3]: (plus compliqué...)
1) Pour chaque couleur de la palette, on crée une liste contenant chaque pixel de l'image source (on retient leurs instances, donc leurs couleurs ET position), et on la trie par ordre croissant de la distance à la couleur de la palette.
2) On choisit la liste pour laquelle le premier élément (pixel) est le plus proche de couleur correspondante à la liste (on ne considère que les listes associées à des couleurs pour lesquelles on n'a pas atteint la limite)
3) On place ce pixel (1er élément de la liste) sur notre image finale.
4) On supprime alors ce pixel dans toutes les listes.
5) On recommence à l'étape 2) jusqu'à ce que toutes les listes soient vides.
Voilà ce que j'ai imaginé pour le moment, mais c'est loin d'être parfait, d'autant plus que l'on ne prend à aucun moment l'aspect "spatial" de l'image (aucun idée de voisinage entre les pixels) qui est important pour un bon rendu "visuel".
C'est pourquoi je fais appelle à votre aide pour des suggestions d'améliorations, ou de reprises complètes des algorithmes.
Merci d'avance pour votre aide !
Partager