Vous êtes donné une image en vraies couleurs. Votre tâche consiste à générer une version de cette image, qui semble avoir été peinte à l'aide de peinture par numéros (l'activité des enfants, et non les non- graphiques). En plus de l'image, vous avez deux paramètres: P , la taille maximale de la palette de couleurs (c'est-à-dire le nombre maximal de couleurs distinctes à utiliser) et N , le nombre maximal de cellules à utiliser. Votre algorithme ne doit pas nécessairement utiliser toutes les couleurs P et N cellules, mais il ne doit pas en utiliser plus. L'image de sortie doit avoir les mêmes dimensions que l'entrée.
Une cellule est définie comme une zone contiguë de pixels qui ont tous la même couleur. Les pixels se touchant uniquement dans un coin ne sont pas considérés comme contigus. Les cellules peuvent avoir des trous.
En bref, vous devez approximer l’image d’entrée avec seulement N zones d’ombre / couleurs unies et P couleurs différentes.
Juste pour visualiser les paramètres, voici un exemple très simple (sans image d'entrée particulière; montrant mes compétences en peinture folles). L'image suivante a P = 6 et N = 11 :
Voici quelques images pour tester votre algorithme (principalement nos suspects habituels). Cliquez sur les images pour les versions plus grandes.
Veuillez inclure une poignée de résultats pour différents paramètres. Si vous souhaitez afficher un grand nombre de résultats, vous pouvez créer une galerie sur imgur.com , afin que la taille des réponses reste raisonnable. Vous pouvez également placer des vignettes dans votre message et les lier à de plus grandes images, comme je l’ai fait ci-dessus. Aussi, n'hésitez pas à utiliser d'autres images de test, si vous trouvez quelque chose de bien.
Je suppose que les paramètres autour de N ≥ 500 , P ~ 30 seraient similaires à de véritables modèles de peinture par numéro.
Ceci est un concours de popularité, donc la réponse avec le plus grand nombre de votes nets gagne. Les électeurs sont encouragés à juger les réponses par
- comment bien les images originales sont approchées.
- l'efficacité de l'algorithme sur différents types d'images (les peintures sont probablement généralement plus simples que les photographies).
- comment bien l'algorithme fonctionne avec des paramètres très restrictifs.
- comment organique / lisse les formes des cellules.
J'utiliserai le script Mathematica suivant pour valider les résultats:
image = <pastedimagehere> // ImageData;
palette = Union[Join @@ image];
Print["P = ", Length@palette];
grid = GridGraph[Reverse@Most@Dimensions@image];
image = Flatten[image /. Thread[palette -> Range@Length@palette]];
Print["N = ",
Length@ConnectedComponents[
Graph[Cases[EdgeList[grid],
m_ <-> n_ /; image[[m]] == image[[n]]]]]]
Sp3000 a eu la gentillesse d’écrire un vérificateur dans Python 2 à l’aide de PIL, que vous trouverez dans ce pastebin .
la source
Réponses:
Python 2 avec PIL ( Galerie )
Temps de mise à jour! Cette mise à jour propose un algorithme de lissage simple pour rendre les images moins floues. Si j'effectue une nouvelle mise à jour, je devrai réorganiser une bonne partie de mon code, car cela devient compliqué et que je perds mon temps de parole.
J'ai également créé des couleurs de poids k-means en fonction de la taille des cellules, ce qui perd certains détails pour des paramètres plus restrictifs (par exemple le centre de la nébuleuse et la fourche de l'American Gothic), mais rend le choix de couleur global plus net et plus élégant. Fait intéressant, il perd tout le fond des sphères tracées par rayons pour P = 5.
Résumé de l'algorithme:
Le temps de traitement de chaque image dépend fortement de sa taille et de sa complexité, avec des durées allant de 20 secondes à 7 minutes pour les images testées.
Étant donné que l'algorithme utilise la randomisation (par exemple, la fusion, k-moyennes), vous pouvez obtenir des résultats différents sur différentes exécutions. Voici une comparaison de deux parcours pour l'image de l'ours, avec N = 50 et P = 10:
Remarque: toutes les images ci-dessous sont des liens. La plupart de ces images sont directement issues de la première utilisation, mais si je n'aimais pas le résultat, je me permettais jusqu'à trois tentatives pour être juste.
N = 50, P = 10
N = 500, P = 30
Mais je suis assez paresseux quand il s'agit de peindre par couleurs, alors juste pour le plaisir ...
N = 20, P = 5
De plus, il est amusant de voir ce qui se passe lorsque vous essayez de presser 1 million de couleurs dans N = 500, P = 30:
Voici une procédure pas à pas de l'algorithme pour l'image sous-marine avec N = 500 et P = 30, sous forme GIF animé:
J'ai également fait une galerie pour les versions précédentes de l'algorithme ici . Voici quelques-uns de mes favoris de la dernière version (à partir du moment où la nébuleuse avait plus d'étoiles et que l'ours avait l'air fourreur):
la source
im = im.convert("RGB")
certaines images soient nécessaires. Je mettrai cela après avoir restructuré le code un peu.Python 2 avec PIL
Également une solution Python et probablement un travail en cours:
L'algorithme suit une approche différente de celle de SP3000, en commençant par les couleurs:
Recherchez une palette de couleurs de P couleurs par regroupement k-signifie et peignez l'image dans cette palette réduite.
Appliquez un léger filtre médian pour éliminer le bruit.
Faites une liste de toutes les cellules monochromatiques et triez-les par taille.
Fusionnez les plus petites cellules avec leur plus grand voisin respectif jusqu'à ce qu'il ne reste plus que N cellules.
Il y a encore beaucoup à faire, à la fois en termes de rapidité et de qualité des résultats. En particulier, l'étape de fusion de cellules peut prendre plusieurs minutes et donner des résultats loin d'être optimaux.
P = 5, N = 45
P = 10, N = 50
P = 4, N = 250
P = 11, N = 500
la source
Mathematica
Pour le moment, cela prend le nombre de couleurs et le rayon gaussien à utiliser dans le filtre gaussien. Plus le rayon est grand, plus le flou et la fusion des couleurs sont importants.
Parce qu'il ne permet pas de saisir le nombre de cellules, il ne répond à aucune des exigences de base du défi.
La sortie inclut le nombre de cellules pour chaque couleur ainsi que le nombre total de cellules.
Mise à jour
quantImage2
permet de spécifier le nombre de cellules souhaité en entrée. Il détermine le meilleur rayon gaussien en effectuant une boucle dans des scénarios avec des rayons plus importants jusqu'à ce qu'une correspondance étroite soit trouvée.quantImage2
sorties (image, cellules demandées, cellules utilisées, erreur, rayon gaussien utilisé).C'est cependant très lent. Pour gagner du temps, vous pouvez commencer par un rayon initial dont la valeur par défaut est 0.
Exemple pour lequel nous spécifions le nombre de cellules souhaité dans la sortie.
Exemple demandant 90 cellules avec 25 couleurs. La solution renvoie 88 cellules, erreur de 2%. La fonction a choisi le rayon gaussien de 55. (Beaucoup de distorsion).
Exemples pour lesquels l'entrée comprend le rayon gaussien, mais pas le nombre de cellules.
25 couleurs, rayon gaussien de 5 pixels
Trois couleurs, rayon de 17 pixels
Vingt couleurs, rayon de 17 pixels
Nous avons augmenté le nombre de couleurs mais pas la mise au point. Notez l'augmentation du nombre de cellules.
Six couleurs, rayon de 4 pixels
Nuit étoilée
Avec seulement 6 couleurs et 60 cellules. Les couleurs utilisées dans les
showColors
revendications ne correspondent pas aux couleurs . (Le jaune n'apparaît pas parmi les 5 couleurs mais il est utilisé dans le dessin.) Je verrai si je peux comprendre cela.la source
showColors
, en parcourant une plage de nombres de couleurs et de rayons et en choisissant la combinaison la plus proche du nombre de cellules souhaité. Pas sûr si j'ai le gaz pour le faire pour le moment. Peut-être plus tard.Python 2 avec PIL
C'est encore un peu un travail en cours. En outre, le code ci-dessous est un horrible fouillis de spaghettis et ne doit pas être utilisé comme une inspiration. :)
Comment ça marche
Le programme divise la toile en
P
régions, chacune d'entre elles étant composée d'un certain nombre de cellules sans trous. Initialement, la toile est simplement divisée en carrés approximatifs, attribués de manière aléatoire aux régions. Ensuite, ces régions sont "déformées" dans un processus itératif, où un pixel donné peut changer de région siCette dernière condition peut être appliquée localement, le processus est donc un peu comme un automate cellulaire. De cette façon, nous n’avons pas à faire de cheminement ou autre, ce qui accélère considérablement le processus. Cependant, comme les cellules ne peuvent pas être brisées, certaines d’entre elles se transforment en longs "filaments" qui bordent d’autres cellules et inhibent leur croissance. Pour résoudre ce problème, il existe un processus appelé "coupe de filament", qui casse parfois une cellule en forme de filament en deux, s'il y en a moins que les
N
cellules à ce moment-là. Les cellules peuvent également disparaître si leur taille est égale à 1, ce qui laisse de la place pour les coupes de filaments.Le processus se termine lorsqu'aucun pixel n'est incité à changer de région. Après cela, chaque région est simplement colorée par sa couleur moyenne. Habituellement, il restera quelques filaments dans la sortie, comme on peut le voir dans les exemples ci-dessous, en particulier dans la nébuleuse.
P = 30, N = 500
Plus de photos plus tard.
Certaines propriétés intéressantes de mon programme sont qu’il est probabiliste, de sorte que les résultats peuvent varier d’une exécution à l’autre, à moins que vous utilisiez la même valeur de départ pseudo-aléatoire bien sûr. Le caractère aléatoire n’est pas essentiel, cependant, je voulais simplement éviter tout artefact accidentel pouvant résulter de la façon dont Python parcourt un ensemble de coordonnées ou quelque chose de similaire. Le programme a tendance à utiliser toutes les
P
couleurs et presque toutes lesN
cellules, et les cellules ne contiennent jamais de trous par leur conception. En outre, le processus de déformation est assez lent. Les boules colorées ont pris presque 15 minutes pour produire sur ma machine. Sur le dessus, si vous allumez leGRAPHICAL_LOGGING
En option, vous obtiendrez une série d'images intéressantes du processus de déformation. J'ai transformé celles de Mona Lisa en animations GIF (réduites de 50% pour réduire la taille du fichier). Si vous regardez attentivement son visage et ses cheveux, vous pouvez voir le processus de coupe de filament en action.la source