Si une image vaut 1 000 mots, quelle quantité d'image pouvez-vous contenir en 140 caractères?
Remarque : c'est tout! La date limite des primes est arrivée, et après quelques délibérations difficiles, j'ai décidé que l'entrée de Boojum venait à peine de devancer celle de Sam Hocevar . Je publierai des notes plus détaillées une fois que j'aurai eu l'occasion de les rédiger. Bien sûr, tout le monde devrait se sentir libre de continuer à soumettre des solutions et à améliorer les solutions pour que les gens votent. Merci à tous ceux qui ont soumis et participé; Je les ai tous appréciés. Cela a été très amusant pour moi de courir, et j'espère que ça a été amusant pour les participants et les spectateurs.
Je suis tombé sur cet article intéressant sur la compression des images dans un commentaire Twitter, et beaucoup de gens dans ce fil (et un fil sur Reddit ) avaient des suggestions sur différentes façons de le faire. Donc, je pense que ce serait un bon défi de codage; laissez les gens placer leur argent là où se trouve leur bouche et montrez comment leurs idées sur l'encodage peuvent donner plus de détails dans l'espace limité dont vous disposez.
Je vous mets au défi de trouver un système à usage général pour encoder les images en messages Twitter de 140 caractères et les décoder à nouveau en une image. Vous pouvez utiliser des caractères Unicode, vous obtenez donc plus de 8 bits par caractère. Même en autorisant les caractères Unicode, cependant, vous devrez compresser les images dans un très petit espace; ce sera certainement une compression avec perte, et il devra donc y avoir des jugements subjectifs sur la qualité de chaque résultat.
Voici le résultat que l'auteur original, Quasimondo , a obtenu de son encodage (l'image est sous licence Creative Commons Attribution-Noncommercial ):
Pouvez-vous faire mieux?
Règles
- Votre programme doit avoir deux modes: encodage et décodage .
- Lors de l' encodage :
- Votre programme doit prendre en entrée un graphique dans n'importe quel format graphique matriciel raisonnable de votre choix. Nous dirons que tout format raster pris en charge par ImageMagick compte comme raisonnable.
- Votre programme doit générer un message qui peut être représenté en 140 points de code Unicode ou moins; 140 points de code dans l'intervalle
U+0000
-U+10FFFF
, à l' exclusion des non-caractères (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
où n est1
-10
hexadécimal, et la gammeU+FDD0
-U+FDEF
) et des points de code de substitution (U+D800
-U+DFFF
). Il peut être sorti dans n'importe quel encodage raisonnable de votre choix; tout codage pris en charge par GNUiconv
sera considéré comme raisonnable, et le codage natif de votre plate-forme ou le codage local serait probablement un bon choix. Voir les notes Unicode ci-dessous pour plus de détails.
- Lors du décodage :
- Votre programme doit prendre en entrée la sortie de votre mode d' encodage .
- Votre programme doit sortir une image dans n'importe quel format raisonnable de votre choix, tel que défini ci-dessus, bien que les formats vectoriels de sortie soient également OK.
- La sortie d'image doit être une approximation de l'image d'entrée; plus vous vous rapprochez de l'image d'entrée, mieux c'est.
- Le processus de décodage peut n'avoir accès à aucune autre sortie du processus de codage autre que la sortie spécifiée ci-dessus; c'est-à-dire que vous ne pouvez pas télécharger l'image quelque part et sortir l'URL pour le processus de décodage à télécharger, ou quelque chose de stupide comme ça.
Par souci de cohérence dans l'interface utilisateur, votre programme doit se comporter comme suit:
- Votre programme doit être un script qui peut être défini sur exécutable sur une plate-forme avec l'interpréteur approprié, ou un programme qui peut être compilé en un exécutable.
- Votre programme doit prendre comme premier argument soit
encode
oudecode
de régler le mode. Votre programme doit prendre des entrées d'une ou plusieurs des manières suivantes (si vous implémentez celui qui prend les noms de fichiers, vous pouvez également lire et écrire à partir de stdin et stdout si les noms de fichiers sont manquants):
Prenez l'entrée de l'entrée standard et produisez la sortie sur la sortie standard.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Prenez l'entrée d'un fichier nommé dans le deuxième argument et produisez la sortie dans le fichier nommé dans le troisième.
my-program encode input.png output.txt my-program decode output.txt output.png
- Pour votre solution, veuillez poster:
- Votre code, dans son intégralité, et / ou un lien vers celui-ci hébergé ailleurs (s'il est très long, ou nécessite de nombreux fichiers à compiler, ou quelque chose).
- Une explication de la façon dont cela fonctionne, si ce n'est pas immédiatement évident d'après le code ou si le code est long et les gens seront intéressés par un résumé.
- Une image d'exemple, avec l'image d'origine, le texte vers lequel elle est compressée et l'image décodée.
- Si vous construisez sur une idée que quelqu'un d'autre avait, veuillez les attribuer. C'est OK pour essayer d'affiner l'idée de quelqu'un d'autre, mais vous devez les attribuer.
Des lignes directrices
Ce sont essentiellement des règles qui peuvent être brisées, des suggestions ou des critères de notation:
- L'esthétique est importante. Je vais juger et suggérer que d'autres personnes jugent, sur la base de:
- La qualité de l'image de sortie et son aspect original.
- Comme c'est joli le texte. Un charabia complètement aléatoire est OK si vous avez un schéma de compression vraiment intelligent, mais je veux aussi voir des réponses qui transforment les images en poèmes multilingues, ou quelque chose d'intelligent comme ça. Notez que l'auteur de la solution originale a décidé de n'utiliser que des caractères chinois, car cela avait l'air plus agréable de cette façon.
- Un code intéressant et des algorithmes intelligents sont toujours bons. J'aime le code court, précis et clair, mais les algorithmes compliqués vraiment intelligents sont aussi OK tant qu'ils produisent de bons résultats.
- La vitesse est également importante, mais pas aussi importante que la qualité du travail de compression de l'image que vous faites. Je préfère avoir un programme qui peut convertir une image en un dixième de seconde plutôt que quelque chose qui exécutera des algorithmes génétiques pendant des jours.
- Je préférerai des solutions plus courtes à des solutions plus longues, pour autant qu'elles soient raisonnablement comparables en qualité; la concision est une vertu.
- Votre programme doit être implémenté dans une langue dont l'implémentation est disponible gratuitement sur Mac OS X, Linux ou Windows. J'aimerais pouvoir exécuter les programmes, mais si vous avez une excellente solution qui ne fonctionne que sous MATLAB ou quelque chose, ça va.
- Votre programme doit être aussi général que possible; cela devrait fonctionner pour autant d'images différentes que possible, bien que certaines puissent produire de meilleurs résultats que d'autres. En particulier:
- Avoir quelques images intégrées dans le programme auquel il correspond et écrit une référence, puis produit l'image correspondante lors du décodage, est assez boiteux et ne couvrira que quelques images.
- Un programme qui peut prendre des images de formes géométriques simples et plates et les décomposer en une primitive vectorielle est assez astucieux, mais s'il échoue sur des images au-delà d'une certaine complexité, il est probablement insuffisamment général.
- Un programme qui ne peut prendre que des images d'un rapport d'aspect fixe particulier mais qui fait du bon travail avec elles serait également OK, mais pas idéal.
- Vous pouvez constater qu'une image en noir et blanc peut obtenir plus d'informations dans un espace plus petit qu'une image en couleur. D'un autre côté, cela peut limiter les types d'images auxquels elle s'applique; les visages ressortent bien en noir et blanc, mais les motifs abstraits peuvent ne pas être aussi bons.
- C'est parfaitement bien si l'image de sortie est plus petite que l'entrée, tout en étant à peu près la même proportion. C'est OK si vous devez redimensionner l'image pour la comparer à l'original; ce qui est important, c'est à quoi ça ressemble.
- Votre programme devrait produire une sortie qui pourrait réellement passer par Twitter et sortir indemne. Ce n'est qu'une directive plutôt qu'une règle, car je n'ai trouvé aucune documentation sur l'ensemble précis de caractères pris en charge, mais vous devriez probablement éviter les caractères de contrôle, les caractères de combinaison invisibles géniaux, les caractères à usage privé, etc.
Rubrique de notation
En tant que guide général sur la façon dont je classerai les solutions lors du choix de ma solution acceptée, disons que je vais probablement évaluer les solutions sur une échelle de 25 points (c'est très approximatif, et je ne noterai rien directement, en utilisant simplement ceci comme ligne directrice de base):
- 15 points pour la façon dont le schéma de codage reproduit une large gamme d'images d'entrée. Il s'agit d'un jugement subjectif et esthétique
- 0 signifie que cela ne fonctionne pas du tout, il renvoie la même image à chaque fois, ou quelque chose
- 5 signifie qu'il peut encoder quelques images, bien que la version décodée semble moche et qu'elle ne fonctionne pas du tout sur des images plus compliquées
- 10 signifie qu'il fonctionne sur une large gamme d'images et produit des images agréables qui peuvent parfois être distinguées
- 15 signifie qu'il produit des répliques parfaites de certaines images, et même pour des images plus grandes et plus complexes, donne quelque chose qui est reconnaissable. Ou, peut-être que cela ne rend pas les images tout à fait reconnaissables, mais produit de belles images qui sont clairement dérivées de l'original.
- 3 points pour une utilisation intelligente du jeu de caractères Unicode
- 0 point pour utiliser simplement l'ensemble des caractères autorisés
- 1 point pour l'utilisation d'un ensemble limité de caractères pouvant être transférés en toute sécurité sur Twitter ou dans une plus grande variété de situations
- 2 points pour l'utilisation d'un sous-ensemble thématique de caractères, comme uniquement les idéogrammes Han ou uniquement les caractères de droite à gauche
- 3 points pour faire quelque chose de vraiment bien, comme générer du texte lisible ou utiliser des caractères qui ressemblent à l'image en question
- 3 points pour des approches algorithmiques intelligentes et un style de code
- 0 point pour quelque chose qui représente 1 000 lignes de code uniquement pour réduire l'image, la traiter comme 1 bit par pixel et encoder en base64 qui
- 1 point pour quelque chose qui utilise une technique d'encodage standard et qui est bien écrit et bref
- 2 points pour quelque chose qui introduit une technique d'encodage relativement nouvelle, ou qui est étonnamment court et propre
- 3 points pour une doublure qui produit réellement de bons résultats, ou quelque chose qui innove dans l'encodage graphique (si cela semble être un faible nombre de points pour innover, rappelez-vous qu'un résultat de ce produit aura probablement un score élevé pour l'esthétique ainsi que)
- 2 points pour la vitesse. Toutes choses étant égales par ailleurs, plus vite c'est mieux, mais les critères ci-dessus sont tous plus importants que la vitesse
- 1 point pour fonctionner sur un logiciel libre (open source), car je préfère le logiciel libre (notez que C # sera toujours éligible pour ce point tant qu'il fonctionnera en Mono, de même le code MATLAB serait éligible s'il s'exécute sur GNU Octave)
- 1 point pour avoir suivi toutes les règles. Ces règles sont devenues un peu grosses et compliquées, donc j'accepterai probablement de bonnes réponses qui se trompent un petit détail, mais je donnerai un point supplémentaire à toute solution qui suit réellement toutes les règles
Images de référence
Certaines personnes ont demandé des images de référence. Voici quelques images de référence que vous pouvez essayer; des versions plus petites sont intégrées ici, elles sont toutes liées à des versions plus grandes de l'image si vous en avez besoin:
Prix
J'offre une prime de 500 représentants (plus les 50 que StackOverflow entre en jeu) pour la solution que j'aime le mieux, en fonction des critères ci-dessus. Bien sûr, j'encourage tout le monde à voter sur leurs solutions préférées ici également.
Remarque sur la date limite
Ce concours se poursuivra jusqu'à épuisement de la prime, vers 18 h le samedi 30 mai. Je ne peux pas dire l'heure exacte à laquelle il se terminera; il peut être de 17 h à 19 h. Je garantirai que je regarderai toutes les entrées soumises avant 14 heures, et je ferai de mon mieux pour regarder toutes les entrées soumises avant 16 heures; si des solutions sont soumises après cela, je n'aurai peut-être pas la possibilité de leur donner un aperçu juste avant de devoir prendre ma décision. De plus, plus vous soumettez tôt, plus vous aurez de chances de voter pour être en mesure de m'aider à choisir la meilleure solution, alors essayez de soumettre plus tôt plutôt que juste à la date limite.
Notes Unicode
Il y a également eu une certaine confusion sur exactement quels caractères Unicode sont autorisés. La plage de points de code Unicode possibles est U+0000
de U+10FFFF
. Il existe certains points de code qui ne sont jamais valables pour être utilisés comme caractères Unicode dans tout échange ouvert de données; ce sont les non- caractères et les points de code de substitution . Non - caractères sont définis dans la norme section 5.1.0 Unidode 16,7 comme les valeurs U+FFFE
, U+FFFF
, U+
nFFFE
, U+
nFFFF
où n est 1
- 10
hexadécimal, et la gamme U+FDD0
-U+FDEF
. Ces valeurs sont destinées à être utilisées pour une utilisation interne spécifique à l'application, et les applications conformes peuvent supprimer ces caractères du texte qu'ils traitent. Les points de code de substitution, définis dans la norme Unicode 5.1.0 section 3.8 as U+D800
- U+DFFF
, sont utilisés pour coder les caractères au-delà du plan multilingue de base en UTF-16; ainsi, il est impossible de représenter ces points de code directement dans le codage UTF-16, et il n'est pas valide de les coder dans un autre codage. Ainsi, aux fins de ce concours, j'autoriserai tout programme qui code des images dans une séquence de 140 points de code Unicode au maximum de la plage U+0000
- U+10FFFF
, à l'exclusion de tous les non-caractères et paires de substitution tels que définis ci-dessus.
Je préférerai des solutions qui n'utilisent que des caractères attribués, et encore mieux celles qui utilisent des sous-ensembles intelligents de caractères attribués ou font quelque chose d'intéressant avec le jeu de caractères qu'ils utilisent. Pour une liste des caractères attribués, consultez la base de données de caractères Unicode ; notez que certains caractères sont répertoriés directement, tandis que certains ne sont répertoriés que comme le début et la fin d'une plage. Notez également que les points de code de substitution sont répertoriés dans la base de données, mais interdits comme mentionné ci-dessus. Si vous souhaitez profiter de certaines propriétés des caractères pour rendre le texte que vous sortez plus intéressant, il existe une variété de bases de données d'informations sur les caractères , telles qu'une liste de blocs de code nommés et diverses propriétés de caractères.
Étant donné que Twitter ne spécifie pas le jeu de caractères exact qu'ils prennent en charge, je me montrerai indulgent vis-à-vis des solutions qui ne fonctionnent pas réellement avec Twitter car certains caractères comptent en plus ou certains caractères sont supprimés. Il est préférable, mais non obligatoire, que toutes les sorties codées puissent être transférées indemnes via Twitter ou un autre service de microblogage tel que identi.ca . J'ai vu de la documentation indiquant que Twitter code les entités <,> et &, et les compte donc comme 4, 4 et 5 caractères respectivement, mais je ne l'ai pas testé moi-même, et leur compteur de caractères JavaScript ne semble pas de les compter de cette façon.
Conseils et liens
- La définition des caractères Unicode valides dans les règles est un peu compliquée. Le choix d'un seul bloc de caractères, comme les idéogrammes unifiés CJC (U + 4E00 – U + 9FCF) peut être plus facile.
- Vous pouvez utiliser des bibliothèques d'images existantes, comme ImageMagick ou Python Imaging Library , pour votre manipulation d'image.
- Si vous avez besoin d'aide pour comprendre le jeu de caractères Unicode et ses différents encodages, consultez ce guide rapide ou cette FAQ détaillée sur UTF-8 sous Linux et Unix .
- Plus tôt vous obtiendrez votre solution, plus je (et les autres personnes votant) devrai y réfléchir. Vous pouvez modifier votre solution si vous l'améliorez; Je baserai ma prime sur la version la plus récente lors de mon dernier examen des solutions.
- Si vous voulez un format d'image facile à analyser et à écrire (et ne voulez pas simplement utiliser un format existant), je vous suggère d'utiliser le format PPM . Il s'agit d'un format basé sur du texte qui est très facile à utiliser, et vous pouvez utiliser ImageMagick pour convertir vers et depuis celui-ci.
la source
Réponses:
D'accord, voici le mien: nanocrunch.cpp et le fichier CMakeLists.txt pour le construire en utilisant CMake. Il s'appuie sur l' API Magick ++ ImageMagick pour la plupart de sa gestion d'image. Il nécessite également la bibliothèque GMP pour l'arithmétique bignum pour son codage de chaînes.
J'ai basé ma solution sur la compression d'image fractale, avec quelques rebondissements uniques. L'idée de base est de prendre l'image, de réduire une copie à 50% et de rechercher des pièces dans différentes orientations qui ressemblent à des blocs qui ne se chevauchent pas dans l'image d'origine. Il faut une approche très brutale pour cette recherche, mais cela facilite simplement l'introduction de mes modifications.
La première modification est qu'au lieu de simplement regarder les rotations et les retournements à quatre-vingt-dix degrés, mon programme considère également les orientations à 45 degrés. C'est un bit de plus par bloc, mais cela aide énormément la qualité de l'image.
L'autre chose est que le stockage d'un ajustement de contraste / luminosité pour chacun des composants de couleur de chaque bloc est beaucoup trop cher. Au lieu de cela, je stocke une couleur fortement quantifiée (la palette n'a que 4 * 4 * 4 = 64 couleurs) qui se mélange simplement dans une certaine proportion. Mathématiquement, cela équivaut à un réglage de luminosité variable et de contraste constant pour chaque couleur. Malheureusement, cela signifie également qu'il n'y a pas de contraste négatif pour inverser les couleurs.
Une fois qu'il a calculé la position, l'orientation et la couleur de chaque bloc, il l'encode en une chaîne UTF-8. Tout d'abord, il génère un très grand bignum pour représenter les données dans la table de blocs et la taille de l'image. L'approche est similaire à la solution de Sam Hocevar - une sorte de grand nombre avec un radix qui varie selon la position.
Ensuite, il convertit cela en une base quelle que soit la taille du jeu de caractères disponible. Par défaut, il utilise pleinement le jeu de caractères Unicode attribué, moins le moins que, plus grand que, l'esperluette, le contrôle, la combinaison et les caractères de substitution et privés. Ce n'est pas joli mais ça marche. Vous pouvez également commenter le tableau par défaut et sélectionner à la place des caractères ASCII imprimables 7 bits (à l'exclusion des caractères <,> et &) ou des idéogrammes CJK Unified. Le tableau des codes de caractères disponibles est stocké dans une longueur codée avec des séquences alternées de caractères non valides et valides.
Quoi qu'il en soit, voici quelques images et heures (mesurées sur mon ancien P4 3.0GHz), et compressées à 140 caractères dans l'ensemble unicode assigné décrit ci-dessus. Dans l'ensemble, je suis assez satisfait de la façon dont ils se sont tous déroulés. Si j'avais plus de temps pour travailler là-dessus, j'essaierais probablement de réduire le blocage des images décompressées. Pourtant, je pense que les résultats sont plutôt bons pour le taux de compression extrême. Les images décompressées sont un peu impressionnistes, mais je trouve relativement facile de voir comment les bits correspondent à l'original.
Logo Stack Overflow (8,6 s pour encoder, 7,9 s pour décoder, 485 octets):
http://i44.tinypic.com/2w7lok1.png
Lena (32,8 s pour coder, 13,0 s pour décoder, 477 octets):
http://i42.tinypic.com/2rr49wg.png http://i40.tinypic.com/2rhxxyu.png
Mona Lisa (43,2 s pour coder, 14,5 s pour décoder, 490 octets):
http://i41.tinypic.com/ekgwp3.png http://i43.tinypic.com/ngsxep.png
Edit: CJK Unified Characters
Sam a demandé dans les commentaires sur l'utilisation de ceci avec CJK. Voici une version de Mona Lisa compressée à 139 caractères du jeu de caractères CJK Unified:
http://i43.tinypic.com/2yxgdfk.png 咏 璘 驞 凄 脒 鵚 据 蛥 鸂 拗 朐 朖 辿 韩 瀦 魷 歪 痫 栘 璯 緍 脲 蕜 抱 揎 頻 蓼 債 鑡 嗞 靊 寞 柮 嚛 嚵 籥 聚 聚隤 慛 絖 銓 馿 渫 櫰 矍 昀 鰛 掾 撄 粂 敽 牙 稉 擎 蔍 螎 葙 峬 覧 絀 蹔 抆 惫 冧 笻 哜 搀 澐 芯 譶 辍 澮 垝 黟 偞 媄 童 竽 梀 韠 镰 猳 閺 狌 而 梀伆 杇 婣 唆 鐤 諽 鷍 鴞 駫 搶 毤 埙 誖 萜 愿 旖 鞰 萗 勹 鈱 哳 垬 濅 鬒 秀 瞛 洆 认 気 狋 異 闥 籴 珵 仾 氙 熜 謋 繴 茴 晋 髭 杍 嚖 熥 勳 縿 餅 髭擸 萿
Les paramètres de réglage en haut du programme que j'ai utilisé pour cela étaient: 19, 19, 4, 4, 3, 10, 11, 1000, 1000. J'ai également commenté la première définition de number_assigned et des codes, et je n'ai pas commenté le dernières définitions pour sélectionner le jeu de caractères CJK Unified.
la source
fichiers image et source python (versions 1 et 2)
Version 1 Voici ma première tentative. Je mettrai à jour au fur et à mesure.
J'ai le logo SO à 300 caractères presque sans perte. Ma technique utilise la conversion en art vectoriel SVG, donc cela fonctionne mieux en ligne. Il s'agit en fait d'un compresseur SVG, il nécessite encore que l'art original passe par une étape de vectorisation.
Pour ma première tentative, j'ai utilisé un service en ligne pour la trace PNG, mais il existe de nombreux outils gratuits et non gratuits qui peuvent gérer cette partie, y compris Potrace (open-source).
Voici les résultats
Logo SO original http://www.warriorhut.org/graphics/svg_to_unicode/so-logo.png Logo SO décodé original http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.png Après encodage et décodage
Caractères : 300
Temps : non mesuré mais pratiquement instantané (sans les étapes de vectorisation / tramage)
La prochaine étape consistera à incorporer 4 symboles (points et commandes de chemin SVG) par caractère unicode. Pour le moment, ma version python n'a pas de support de caractères large UCS4, ce qui limite ma résolution par caractère. J'ai également limité la plage maximale à l'extrémité inférieure de la plage réservée Unicode 0xD800, mais une fois que j'ai construit une liste de caractères autorisés et un filtre pour les éviter, je peux théoriquement pousser le nombre requis de caractères aussi bas que 70-100 pour le logo ci-dessus.
Une limitation de cette méthode à l'heure actuelle est que la taille de sortie n'est pas fixe. Cela dépend du nombre de nœuds / points vectoriels après vectorisation. L'automatisation de cette limite nécessitera soit une pixellisation de l'image (ce qui supprime le principal avantage des vecteurs), soit une répétition de l'exécution des chemins à travers une étape de simplification jusqu'à ce que le nombre de nœuds souhaité soit atteint (ce que je fais actuellement manuellement dans Inkscape).
Version 2
MISE À JOUR : la v2 est maintenant qualifiée pour concourir. Changements:
Caractères : 133
Durée : quelques secondes
v2 décodé http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.png Après encodage et décodage (version 2)
Comme vous pouvez le voir, il y a cette fois quelques artefacts. Ce n'est pas une limitation de la méthode mais une erreur quelque part dans mes conversions. Les artefacts se produisent lorsque les points sortent de la plage de 0,0 à 127,0 et mes tentatives pour les contraindre ont eu un succès mitigé. La solution consiste simplement à réduire l'image, mais j'ai eu du mal à mettre à l'échelle les points réels plutôt que le plan de travail ou la matrice de groupe et je suis trop fatigué maintenant pour m'en soucier. En bref, si vos points sont dans la plage prise en charge, cela fonctionne généralement.
Je crois que le pli au milieu est dû à une poignée se déplaçant de l'autre côté d'une poignée à laquelle il est lié. Fondamentalement, les points sont trop rapprochés en premier lieu. L'exécution d'un filtre simplifié sur l'image source avant de la compresser devrait résoudre ce problème et raser certains caractères inutiles.
MISE À JOUR : Cette méthode convient aux objets simples, j'avais donc besoin d'un moyen de simplifier les chemins complexes et de réduire le bruit. J'ai utilisé Inkscape pour cette tâche. J'ai eu de la chance avec le nettoyage de chemins inutiles à l'aide d'Inkscape, mais je n'ai pas eu le temps d'essayer de l'automatiser. J'ai fait quelques exemples de svgs en utilisant la fonction 'Simplify' d'Inkscape pour réduire le nombre de chemins.
Simplifier fonctionne bien mais cela peut être lent avec autant de chemins.
exemple d'autotrace http://www.warriorhut.org/graphics/svg_to_unicode/autotrace_16_color_manual_reduction.png cornell box http://www.warriorhut.com/graphics/svg_to_unicode/cornell_box_simplified.png lena http: //www.war /svg_to_unicode/lena_std_washed_autotrace.png
vignettes tracées http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png
Voici quelques clichés ultra basse résolution. Ceux-ci seraient plus proches de la limite de 140 caractères, bien qu'une compression intelligente du chemin puisse également être nécessaire.
groomed http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png Simplifié et moucheté.
trianglulated http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png Simplifié, moucheté et triangulé.
CI-DESSUS: Chemins simplifiés utilisant le suivi automatique .
Malheureusement, mon analyseur ne gère pas la sortie de suivi automatique, donc je ne sais pas comment les points peuvent être utilisés ou dans quelle mesure simplifier, malheureusement, il y a peu de temps pour l'écrire avant la date limite. Cependant, il est beaucoup plus facile à analyser que la sortie d'Inkscape.
la source
Ma solution complète se trouve sur http://caca.zoy.org/wiki/img2twit . Il présente les caractéristiques suivantes:
Voici un aperçu approximatif du processus d'encodage:
Et voici le processus de décodage:
Ce que je crois être la partie la plus originale du programme, c'est le bitstream. Au lieu d'emballer des valeurs alignées sur les bits (
stream <<= shift; stream |= value
), j'emballe des valeurs arbitraires qui ne sont pas dans des plages de puissance de deux (stream *= range; stream += value
). Cela nécessite des calculs de bignum et est bien sûr beaucoup plus lent, mais cela me donne 2009,18 bits au lieu de 1960 lorsque j'utilise les 20902 principaux caractères CJK (c'est trois points de plus que je peux mettre dans les données). Et lorsque j'utilise ASCII, cela me donne 917,64 bits au lieu de 840.J'ai choisi une méthode pour le calcul initial de l'image qui aurait nécessité des armes lourdes (détection de coin, extraction de caractéristiques, quantification des couleurs ...) car je n'étais pas sûr au début que cela aiderait vraiment. Maintenant, je me rends compte que la convergence est lente (1 minute est acceptable mais elle est néanmoins lente) et je peux essayer de l'améliorer.
La boucle d'ajustement principale est vaguement inspirée de l'algorithme de tramage Direct Binary Seach (où les pixels sont échangés ou inversés de manière aléatoire jusqu'à obtenir une meilleure demi-teinte). Le calcul d'énergie est une simple distance moyenne quadratique, mais j'effectue d'abord un filtre médian 5x5 sur l'image d'origine. Un flou gaussien représenterait probablement mieux le comportement de l'œil humain, mais je ne voulais pas perdre des arêtes vives. J'ai également décidé de ne pas recuire simulé ou d'autres méthodes difficiles à régler car je n'ai pas de mois pour calibrer le processus. Ainsi, l'indicateur "qualité" représente simplement le nombre d'itérations qui sont effectuées sur chaque point avant la fin du codeur.
Même si toutes les images ne se compressent pas bien, je suis surpris par les résultats et je me demande vraiment quelles autres méthodes existent qui peuvent compresser une image à 250 octets.
J'ai également de petits films sur l'évolution de l' état de l'encodeur à partir d'un état initial aléatoire et d'un "bon" état initial .
Edit : voici comment la méthode de compression se compare au JPEG. À gauche, l'image au-dessus de 536 octets de jamoes. Sur la droite, Mona Lisa compressé à 534 octets en utilisant la méthode décrite ici (les octets mentionnés ici se réfèrent aux octets de données, donc ignorant les bits gaspillés en utilisant des caractères Unicode):
Modifier : vient de remplacer le texte CJK par les dernières versions des images.
la source
Ce qui suit n'est pas une soumission formelle, car mon logiciel n'a été conçu en aucune façon pour la tâche indiquée. DLI peut être décrit comme un codec d'image avec perte à usage général optimisé. Il s'agit du support d'enregistrement PSNR et MS-SSIM pour la compression d'image, et j'ai pensé qu'il serait intéressant de voir comment il fonctionne pour cette tâche particulière. J'ai utilisé l'image de référence Mona Lisa fournie et je l'ai réduite à 100x150, puis j'ai utilisé DLI pour la compresser à 344 octets.
Mona Lisa DLI http://i40.tinypic.com/2md5q4m.png
Pour comparer avec les échantillons compressés JPEG et IMG2TWIT, j'ai également utilisé DLI pour compresser l'image à 534 octets. Le JPEG est de 536 octets et IMG2TWIT est de 534 octets. Les images ont été agrandies à environ la même taille pour une comparaison facile. JPEG est l'image de gauche, IMG2TWIT est le centre et DLI est l'image de droite.
Comparaison http://i42.tinypic.com/302yjdg.png
L'image DLI parvient à conserver certaines des caractéristiques du visage, notamment le célèbre sourire :).
la source
L'aperçu général de ma solution serait:
Je sais que vous demandiez du code, mais je ne veux pas vraiment passer du temps à coder cela. J'ai pensé qu'une conception efficace pourrait au moins inspirer quelqu'un d'autre à coder cela.
Je pense que le principal avantage de ma solution proposée est qu'elle réutilise autant de technologies existantes que possible. Il peut être amusant d'essayer d'écrire un bon algorithme de compression, mais il est garanti qu'il existe un meilleur algorithme, probablement écrit par des personnes qui ont un diplôme en mathématiques supérieures.
Une autre remarque importante est que si l'on décide que utf16 est le codage préféré, alors cette solution s'effondre. les fichiers jpeg ne fonctionnent pas vraiment lorsqu'ils sont compressés à 280 octets. Cependant, il existe peut-être un meilleur algorithme de compression que jpg pour cette déclaration de problème spécifique.
la source
D'accord, je suis en retard dans le jeu, mais j'ai quand même fait mon projet.
Il s'agit d'un algorithme génétique jouet qui utilise des cercles colorés translucides pour recréer l'image initiale.
Fonctionnalités:
Mis-feautres:
Voici un exemple de twit qui représente Lena: 犭 楊 谷 杌 蒝 螦 界 匘 玏 扝 匮 俄 归 晃 客 猘 摈 硰 划 刀 萕 码 摃 斢 嘁 蜁 嚎 耂 澹 簜 僨 砠 偑 婊 內 團 揕 忈 義 倨 襠 凁 梡岂 掂 戇 耔 攋 斘 眐 奡 萛 狂 昸 箆 亲 嬎 廙 栃 兡 塅 受 橯 恰 应 戞 优 猫 僘 瑩 吱 賾 卣 朸 杈 腠 綍 蝘 猕 屐 稱 悡 詬 來 噩 压 罍 尕 熚 帤 厥 噩虲 兙 罨 縨 炘 排 叁 抠 堃 從 弅 慌 螎 熰 標 宑 簫 柢 橙 拃 丨 蜊 缩 昔 儻 舭 勵 癳 冂 囤 璟 彔 榕 兠 摈 侑 蒖 孂 埮 槃 姠 璐 哠 眛 嫡 琠 枀 訜 璐厇 廩 焛 瀻 严 啘 刱 垫 仔
Le code est dans un référentiel Mercurial sur bitbucket.org. Consultez http://bitbucket.org/tkadlubo/circles.lua
la source
Ce qui suit est mon approche du problème et je dois admettre que c'était un projet assez intéressant à travailler, il est définitivement en dehors de mon domaine de travail normal et m'a donné quelque chose de nouveau à apprendre.
L'idée de base derrière la mienne est la suivante:
Il s'avère que cela fonctionne, mais seulement dans une mesure limitée comme vous pouvez le voir sur les exemples d'images ci-dessous. En termes de sortie, ce qui suit est un exemple de tweet, spécifiquement pour l'image Lena montrée dans les exemples.
Comme vous pouvez le voir, j'ai essayé de contraindre un peu le jeu de caractères; cependant, j'ai rencontré des problèmes lors de l'enregistrement des données de couleur de l'image. En outre, ce schéma de codage a également tendance à gaspiller un tas de bits de données qui pourraient être utilisés pour des informations d'image supplémentaires.
En termes de temps d'exécution, pour les petites images, le code est extrêmement rapide, environ 55 ms pour les exemples d'images fournis, mais le temps augmente avec les images plus grandes. Pour l'image de référence Lena 512x512, le temps de fonctionnement était de 1182 ms. Je dois noter que les chances sont assez bonnes que le code lui-même ne soit pas très optimisé pour les performances (par exemple, tout est travaillé avec un bitmap ), donc les temps pourraient baisser un peu après une refactorisation.
N'hésitez pas à me proposer des suggestions sur ce que j'aurais pu faire de mieux ou ce qui pourrait ne pas être bon avec le code. La liste complète des temps d'exécution et des exemples de sortie se trouve à l'emplacement suivant: http://code-zen.info/twitterimage/
Mettre à jour un
J'ai mis à jour le code RLE utilisé lors de la compression de la chaîne de tweet pour faire un retour en arrière et si c'est le cas, utilisez-le pour la sortie. Cela ne fonctionne que pour les paires de valeurs numériques, mais cela enregistre quelques caractères de données. Le temps d'exécution est plus ou moins le même que la qualité d'image, mais les tweets ont tendance à être un peu plus petits. Je mettrai à jour le tableau sur le site Web au fur et à mesure que je termine les tests. Ce qui suit est l'un des exemples de chaînes de tweet, encore une fois pour la petite version de Lena:
Mettre à jour deux
Une autre petite mise à jour, mais j'ai modifié le code pour regrouper les nuances de couleur en groupes de trois au lieu de quatre, cela utilise un peu plus d'espace, mais à moins que je manque quelque chose, cela devrait signifier que les caractères "étranges" n'apparaissent plus là où la couleur les données sont. De plus, j'ai mis à jour un peu plus la compression pour qu'elle puisse maintenant agir sur la chaîne entière au lieu du bloc de comptage des couleurs. Je teste toujours les temps d'exécution, mais ils semblent être nominalement améliorés; cependant, la qualité d'image est toujours la même. Ce qui suit est la dernière version du tweet de Lena:
Logo StackOverflow http://code-zen.info/twitterimage/images/stackoverflow-logo.bmp Cornell Box http://code-zen.info/twitterimage/images/cornell-box.bmp Lena http: // code-zen .info / twitterimage / images / lena.bmp Mona Lisa http://code-zen.info/twitterimage/images/mona-lisa.bmp
la source
Cet algorithme génétique que Roger Alsing a écrit a un bon taux de compression, au détriment des longs temps de compression. Le vecteur de sommets résultant pourrait être encore compressé en utilisant un algorithme avec ou sans perte.
http://rogeralsing.com/2008/12/07/genetic-programming-evolution-of-mona-lisa/
Ce serait un programme intéressant à mettre en œuvre, mais je vais le manquer.
la source
Dans le défi d'origine, la taille limite est définie comme ce que Twitter vous permet toujours d'envoyer si vous collez votre texte dans leur zone de texte et appuyez sur "Mettre à jour". Comme certaines personnes l'ont correctement remarqué, cela est différent de ce que vous pourriez envoyer sous forme de SMS depuis votre mobile.
Ce qui n'est pas explicitement mentionné (mais quelle était ma règle personnelle), c'est que vous devriez pouvoir sélectionner le message tweeté dans votre navigateur, le copier dans le presse-papiers et le coller dans un champ de saisie de texte de votre décodeur afin qu'il puisse l'afficher. Bien sûr, vous êtes également libre d'enregistrer le message sous forme de fichier texte et de le relire ou d'écrire un outil qui accède à l'API Twitter et filtre tout message qui ressemble à un code image (marqueurs spéciaux pour tout le monde? Wink wink ). Mais la règle est que le message doit être passé par Twitter avant d'être autorisé à le décoder.
Bonne chance avec les 350 octets - je doute que vous puissiez les utiliser.
la source
La publication d'une image monochrome ou en niveaux de gris devrait améliorer la taille de l'image qui peut être encodée dans cet espace car vous ne vous souciez pas de la couleur.
Augmentant éventuellement le défi de télécharger trois images qui, lorsqu'elles sont recombinées, vous donnent une image en couleur tout en conservant une version monochrome dans chaque image distincte.
Ajoutez une compression à ce qui précède et cela pourrait commencer à sembler viable ...
Agréable!!! Maintenant, vous avez piqué mon intérêt. Aucun travail ne sera fait pour le reste de la journée ...
la source
Concernant la partie encodage / décodage de ce challenge. base16b.org est ma tentative de spécifier une méthode standard pour coder en toute sécurité et efficacement les données binaires dans les plans Unicode supérieurs.
Certaines fonctionnalités :
Désolé, cette réponse arrive beaucoup trop tard pour le concours d'origine. J'ai commencé le projet indépendamment de ce post, que j'ai découvert à mi-chemin.
la source
L'idée de stocker un tas d'images de référence est intéressante. Serait-il si mal de stocker, disons, 25 Mo d'échantillons d'images, et que l'encodeur essaie de composer une image en utilisant des bits de ceux-ci? Avec un tuyau aussi minuscule, la machinerie à chaque extrémité va nécessairement être beaucoup plus grande que le volume de données qui la traverse, alors quelle est la différence entre 25 Mo de code et 1 Mo de code et 24 Mo de données d'image?
(notez que les directives originales excluaient de restreindre l'entrée aux images déjà dans la bibliothèque - je ne le suggère pas).
la source
Idée stupide, mais
sha1(my_image)
qui aboutirait à une représentation "parfaite" de toute image (en ignorant les collisions). Le problème évident est que le processus de décodage nécessite des quantités excessives de forçage brutal.Le monochrome 1 bit serait un peu plus facile. Chaque pixel devient un 1 ou 0, vous auriez donc 1000 bits de données pour une image de 100 * 100 pixels. Étant donné que le hachage SHA1 est de 41 caractères, nous pouvons en contenir trois dans un seul message, il suffit de forcer brutalement 2 ensembles de 3333 bits et un ensemble de 3334 (bien que même cela soit probablement encore démesuré)
Ce n'est pas exactement pratique. Même avec l'image 1 bit 100 * 100px de longueur fixe, il y a .., en supposant que je ne fais pas de mauvais calculs, 49995000 combinaisons ou 16661667 lorsqu'il est divisé en trois.
la source
Ici, cette compression est bonne.
http://www.intuac.com/userport/john/apt/
http://img86.imageshack.us/img86/4169/imagey.jpg http://img86.imageshack.us/img86/4169/imagey.jpg
J'ai utilisé le fichier batch suivant:
La taille de fichier résultante est de 559 octets.
la source
Idée: pourriez-vous utiliser une police comme palette? Essayez de briser une image dans une série de vecteurs en essayant de les décrire avec une combinaison d'ensembles de vecteurs (chaque caractère est essentiellement un ensemble de vecteurs). Cela utilise la police comme dictionnaire. Je pourrais par exemple utiliser al pour une ligne verticale et a - pour une ligne horizontale? Juste une idée.
la source