Dither une image en niveaux de gris en noir et blanc pur avec votre propre algorithme.
Lignes directrices: Vous devez créer votre propre nouvel algorithme. Vous ne pouvez pas utiliser d'algorithmes préexistants (ex. Floyd-Steinburg) mais vous pouvez utiliser la technique générale. Votre programme doit pouvoir lire une image et produire une image de la même taille. Il s'agit d'un concours de popularité, donc celui qui produit le meilleur (le plus proche de l'original) et le plus créatif (déterminé par les votes) gagne. Bonus si le code est court, mais ce n'est pas nécessaire.
Vous pouvez utiliser n'importe quelle image en niveaux de gris que vous souhaitez comme entrée, elle doit être supérieure à 300x300. Tout format de fichier est correct.
Exemple d'entrée:
Exemple de sortie:
C'est un très bon travail, mais il reste des lignes et des motifs visibles.
Réponses:
Fortran
D'accord, j'utilise un format d'image obscur appelé FITS qui est utilisé pour l'astronomie. Cela signifie qu'il existe une bibliothèque Fortran pour lire et écrire ces images. En outre, ImageMagick et Gimp peuvent tous deux lire / écrire des images FITS.
L'algorithme que j'utilise est basé sur le tramage "Sierra Lite", mais avec deux améliorations:
a) Je réduit l'erreur propagée d'un facteur 4/5.
b) J'introduis une variation aléatoire dans la matrice de diffusion tout en gardant sa somme constante.
Ensemble, ils éliminent presque complètement les schémas observés dans l'exemple des PO.
En supposant que la bibliothèque CFITSIO soit installée, compilez avec
Les noms de fichiers sont codés en dur (cela ne pouvait pas être dérangé pour résoudre ce problème).
Code:
Exemple de sortie pour l'image de chiot dans OPs post:
OPs exemple de sortie:
la source
GraphicsMagick / ImageMagick
Dither commandé:
Avant de me plaindre de mon utilisation d'un "algorithme établi", veuillez lire le ChangeLog pour GraphicsMagick et ImageMagick pour avril 2003 où vous verrez que j'ai implémenté l'algorithme dans ces applications. En outre, la combinaison de "-gamma .45455" avec "-ordered-dither" est nouvelle.
Le "-gamma .45455" veille à ce que l'image soit trop claire. Le paramètre "all" n'est nécessaire qu'avec GraphicsMagick.
Il y a des bandes car il n'y a que 17 niveaux de gris dans une image de tramage ordonné 4x4. L'apparence des bandes peut être réduite en utilisant un tramage ordonné 8x8 qui a 65 niveaux.
Voici l'image originale, la sortie tramée ordonnée 4x4 et 8x8 et la sortie à seuil aléatoire:
Je préfère la version de tramage ordonné, mais j'inclus la version à seuil aléatoire pour être complète.
Le "10x90%" signifie rendre en dessous de 10% des pixels d'intensité en noir pur et au-dessus de 90% en blanc pur, pour éviter d'avoir quelques taches solitaires dans ces zones.
Il est probablement intéressant de noter que les deux sont aussi économes en mémoire que possible. Il n'y a pas non plus de diffusion, ils fonctionnent donc un pixel à la fois, même lors de l'écriture de blocs de tramage ordonné, et n'ont besoin de rien savoir sur les pixels voisins. ImageMagick et GraphicsMagick traitent une ligne à la fois, mais ce n'est pas nécessaire pour ces méthodes. Les conversions de tramage ordonné prennent moins de 0,04 seconde en temps réel sur mon ancien ordinateur x86_64.
la source
Je m'excuse pour le style de code, j'ai jeté cela ensemble en utilisant certaines bibliothèques que nous venons de construire dans ma classe java, et il y a un mauvais cas de copier-coller et de nombres magiques. L'algorithme sélectionne des rectangles aléatoires dans l'image et vérifie si la luminosité moyenne est supérieure dans l'image tramée ou l'image d'origine. Il active ou désactive ensuite un pixel pour rapprocher les luminosités, en choisissant de préférence des pixels plus différents de l'image d'origine. Je pense que cela fait un meilleur travail en faisant ressortir des détails fins comme les cheveux du chiot, mais l'image est plus bruyante car elle essaie de faire ressortir les détails même dans les zones sans aucun.
la source
Ghostscript (avec peu d'aide d'ImageMagick)
Loin d'être mon «nouvel algorithme», mais, désolé, je n'ai pas pu y résister.
Bien sûr, cela fonctionne mieux sans contrainte de «même taille».
la source
JAVA
Voici ma soumission. Prend une image JPG, calcule la luminosité pixel par pixel (merci à Bonan dans cette question SO), puis vérifie-la par rapport à un motif aléatoire pour savoir si le pixel résultant sera noir ou blanc. Les pixels les plus sombres seront toujours noirs et les pixels les plus lumineux seront toujours blancs pour préserver les détails de l'image.
Autres exemples:
Fonctionne également avec des images en couleur:
la source
CJam
95 octets :)
Il utilise le format ASCII PGM (P2) sans ligne de commentaire, pour l'entrée et la sortie.
La méthode est très basique: elle additionne des carrés de 2 * 2 pixels, convertit dans la plage 0..4, puis utilise un motif correspondant de 4 bits pour générer 2 * 2 pixels en noir et blanc.
Cela signifie également que la largeur et la hauteur doivent être égales.
Échantillon:
Et un algorithme aléatoire en seulement 27 octets:
Il utilise le même format de fichier.
Échantillon:
Et enfin une approche mixte: tramage aléatoire avec un biais vers un damier; 44 octets:
Échantillon:
la source
Java (1.4+)
Je ne sais pas si je réinvente la roue ici, mais je pense qu'elle peut être unique ...
Avec des séquences aléatoires limitées
Tramage aléatoire pur
Image de la ville de la réponse Averroes
L'algorithme utilise le concept d'énergie de luminosité localisée et de normalisation pour conserver les caractéristiques. La version initiale a ensuite utilisé une gigue aléatoire pour produire un regard tramé sur des zones de luminosité similaire. Mais ce n'était pas si attrayant visuellement. Pour contrer cela, un ensemble limité de séquences aléatoires limitées sont mappées à la luminosité des pixels d'entrée bruts et les échantillons sont utilisés de manière itérative et répétée pour produire des arrière-plans d'aspect tramé.
la source
Python
L'idée est la suivante: l'image est divisée en
n x n
tuiles. Nous calculons la couleur moyenne de chacune de ces tuiles. Ensuite, nous mappons la plage de couleurs0 - 255
sur la plage0 - n*n
qui nous donne une nouvelle valeurv
. Ensuite, nous colorions tous les pixels de cette tuile en noir et colorions au hasard lesv
pixels de cette tuile en blanc. C'est loin d'être optimal mais nous donne quand même des résultats reconnaissables. Selon la résolution, cela fonctionne généralement mieux àn=2
oun=3
. Pendant quen=2
vous y êtes, vous pouvez déjà trouver des artefacts de la 'profondeur de couleur simulée, au cas oùn=3
cela pourrait déjà devenir quelque peu flou. J'ai supposé que les images devraient rester de la même taille, mais vous pouvez bien sûr également utiliser cette méthode et simplement doubler / tripler la taille de l'image générée afin d'obtenir plus de détails.PS: Je sais que je suis un peu en retard à la fête, je me souviens que je n'avais aucune idée quand le challenge a commencé mais maintenant je viens d'avoir cette vague cérébrale =)
Résultats:
n=2:
n=3:
la source
Définissons un format de fichier théorique très compact pour cette question car tous les formats de fichiers existants ont trop de surcharge pour écrire une réponse rapide.
Laissez les quatre premiers octets du fichier image définir la largeur et la hauteur de l'image en pixels, respectivement:
suivi d'
w * h
octets de valeurs de niveaux de gris de 0 à 255:Ensuite, nous pouvons définir un morceau de code en Python (145 octets) qui prendra cette image et fera:
qui "trament" en renvoyant du blanc ou du noir avec une probabilité égale à la valeur en niveaux de gris de ce pixel.
Appliqué sur l'exemple d'image, il donne quelque chose comme ceci:
Ce n'est pas trop joli, mais il semble très similaire lorsqu'il est réduit dans un aperçu, et pour seulement 145 octets de Python, je ne pense pas que vous puissiez faire beaucoup mieux.
la source
Cobra
Prend un fichier PNG / BMP 24 bits ou 32 bits (JPG produit une sortie avec quelques gris). Il est également extensible aux fichiers contenant de la couleur.
Il utilise ELA à vitesse optimisée pour tramer l'image en couleur 3 bits, qui reviendra en noir / blanc lorsque vous recevrez votre image de test.
Ai-je mentionné que c'est vraiment rapide?
la source
col
et de laisser laimage.setPixel(x,y,col)
jusqu'à la fin?Java
Code de bas niveau, utilisant PNGJ et un ajout de bruit plus une diffusion de base. Cette implémentation nécessite une source PNG 8 bits en niveaux de gris.
(Ajoutez ce pot à votre chemin de construction si vous voulez l'essayer).
En prime: il est extrêmement efficace dans l'utilisation de la mémoire (il ne stocke que trois lignes) et peut donc être utilisé pour des images énormes.
la source
Java
Juste un algorithme simple basé sur RNG, plus une logique pour traiter les images en couleur. A une probabilité b de définir un pixel donné sur blanc, sinon il le définit sur noir; où b est la luminosité d'origine de ce pixel.
Voici un résultat potentiel pour l'image du chien:
la source