Wenn ein Bild 1000 Wörter wert ist, wie viel von einem Bild können Sie in 140 Zeichen passen?
Hinweis : Das ist es Leute! Die Bounty-Frist ist da, und nach einigen harten Überlegungen habe ich entschieden, dass Boojums Eintrag Sam Hocevars kaum übertrifft . Ich werde detailliertere Notizen veröffentlichen, sobald ich die Gelegenheit hatte, sie aufzuschreiben. Natürlich sollte sich jeder frei fühlen, weiterhin Lösungen einzureichen und Lösungen zu verbessern, über die die Menschen abstimmen können. Vielen Dank an alle, die eingereicht und eingereicht haben; Ich habe sie alle genossen. Das Laufen hat mir sehr viel Spaß gemacht und ich hoffe, es hat sowohl den Teilnehmern als auch den Zuschauern Spaß gemacht.
Ich bin auf diesen interessanten Beitrag gestoßen, in dem versucht wurde, Bilder in einen Twitter-Kommentar zu komprimieren, und viele Leute in diesem Thread (und einem Thread auf Reddit ) hatten Vorschläge, wie Sie dies tun könnten. Ich denke, es wäre eine gute Herausforderung beim Codieren. Lassen Sie die Leute ihr Geld dort einsetzen, wo ihr Mund ist, und zeigen Sie, wie ihre Ideen zur Codierung auf dem begrenzten Platz, den Sie zur Verfügung haben, zu mehr Details führen können.
Ich fordere Sie auf, ein Allzwecksystem zu entwickeln, mit dem Bilder in Twitter-Nachrichten mit 140 Zeichen codiert und erneut in ein Bild decodiert werden können. Sie können Unicode-Zeichen verwenden, sodass Sie mehr als 8 Bit pro Zeichen erhalten. Selbst wenn Sie Unicode-Zeichen zulassen, müssen Sie Bilder auf kleinstem Raum komprimieren. Dies wird sicherlich eine verlustbehaftete Komprimierung sein, und daher muss subjektiv beurteilt werden, wie gut jedes Ergebnis aussieht.
Hier ist das Ergebnis, das der ursprüngliche Autor, Quasimondo , aus seiner Codierung erhalten hat (das Bild ist unter einer Creative Commons Attribution-Noncommercial-Lizenz lizenziert ):
Kannst du es besser machen?
Regeln
- Ihr Programm muss zwei Modi haben: Codierung und Decodierung .
- Bei der Codierung :
- Ihr Programm muss eine Grafik in einem angemessenen Raster- Grafikformat Ihrer Wahl als Eingabe verwenden . Wir werden sagen, dass jedes von ImageMagick unterstützte Rasterformat als angemessen gilt.
- Ihr Programm muss eine Nachricht ausgeben, die in 140 oder weniger Unicode-Codepunkten dargestellt werden kann. 140 Codepunkte im Bereich
U+0000
-U+10FFFF
, ohne nicht-Zeichen (U+FFFE
,U+FFFF
,U+
nFFFE
,U+
nFFFF
, wo n ist1
-10
hexadezimal, und der BereichU+FDD0
-U+FDEF
) sowie Ersatzcodepunkte (U+D800
-U+DFFF
). Es kann in einer angemessenen Codierung Ihrer Wahl ausgegeben werden. Jede von GNUiconv
unterstützte Codierung wird als angemessen angesehen, und Ihre native Plattform- oder Gebietsschema-Codierung ist wahrscheinlich eine gute Wahl. Weitere Informationen finden Sie in den folgenden Unicode-Hinweisen .
- Beim Dekodieren :
- Ihr Programm sollte die Ausgabe Ihres Codierungsmodus als Eingabe verwenden .
- Ihr Programm muss ein Bild in einem angemessenen Format Ihrer Wahl ausgeben, wie oben definiert, obwohl die Ausgabevektorformate ebenfalls in Ordnung sind.
- Die Bildausgabe sollte eine Annäherung an das Eingabebild sein; Je näher Sie dem Eingabebild kommen, desto besser.
- Der Decodierungsprozess hat möglicherweise keinen Zugriff auf eine andere Ausgabe des Codierungsprozesses als die oben angegebene Ausgabe. Das heißt, Sie können das Bild nicht irgendwo hochladen und die URL für den Dekodierungsprozess zum Herunterladen oder ähnliches ausgeben.
Aus Gründen der Konsistenz der Benutzeroberfläche muss sich Ihr Programm wie folgt verhalten:
- Ihr Programm muss ein Skript sein, das auf einer Plattform mit dem entsprechenden Interpreter als ausführbar festgelegt werden kann, oder ein Programm, das zu einer ausführbaren Datei kompiliert werden kann.
- Ihr Programm muss entweder als erstes Argument
encode
oderdecode
zum Festlegen des Modus verwenden. Ihr Programm muss auf eine oder mehrere der folgenden Arten Eingaben vornehmen (wenn Sie die implementieren, die Dateinamen verwendet, können Sie auch von stdin und stdout lesen und schreiben, wenn Dateinamen fehlen):
Nehmen Sie Eingaben von Standard-In und erzeugen Sie Ausgabe von Standard-Out.
my-program encode <input.png >output.txt my-program decode <output.txt >output.png
Nehmen Sie Eingaben aus einer im zweiten Argument genannten Datei und erzeugen Sie Ausgaben in der im dritten Argument genannten Datei.
my-program encode input.png output.txt my-program decode output.txt output.png
- Für Ihre Lösung schreiben Sie bitte:
- Ihr vollständiger Code und / oder ein Link dazu, der an anderer Stelle gehostet wird (wenn er sehr lang ist oder viele Dateien zum Kompilieren benötigt oder so).
- Eine Erklärung, wie es funktioniert, wenn es nicht sofort aus dem Code ersichtlich ist oder wenn der Code lang ist und die Leute an einer Zusammenfassung interessiert sind.
- Ein Beispielbild mit dem Originalbild, dem zu komprimierenden Text und dem dekodierten Bild.
- Wenn Sie auf einer Idee aufbauen, die jemand anderes hatte, schreiben Sie ihn bitte zu. Es ist in Ordnung zu versuchen, die Idee eines anderen zu verfeinern, aber Sie müssen ihn zuschreiben.
Richtlinien
Dies sind im Grunde genommen Regeln, gegen die verstoßen werden kann, Vorschläge oder Bewertungskriterien:
- Ästhetik ist wichtig. Ich werde urteilen und vorschlagen, dass andere Leute urteilen, basierend auf:
- Wie gut das Ausgabebild aussieht und wie sehr es dem Original ähnelt.
- Wie schön der Text aussieht. Völlig zufälliges Gobbledigook ist in Ordnung, wenn Sie ein wirklich cleveres Komprimierungsschema haben, aber ich möchte auch Antworten sehen, die Bilder in mehrsprachige Gedichte verwandeln, oder so etwas Kluges. Beachten Sie, dass der Autor der ursprünglichen Lösung beschlossen hat, nur chinesische Schriftzeichen zu verwenden, da dies so besser aussah.
- Interessanter Code und clevere Algorithmen sind immer gut. Ich mag kurzen, präzisen und klaren Code, aber auch wirklich clevere, komplizierte Algorithmen sind in Ordnung, solange sie gute Ergebnisse liefern.
- Geschwindigkeit ist ebenfalls wichtig, wenn auch nicht so wichtig wie die Komprimierung des Bildes. Ich hätte lieber ein Programm, das ein Bild in einer Zehntelsekunde konvertieren kann, als etwas, das tagelang genetische Algorithmen ausführt.
- Ich werde kürzere Lösungen längeren vorziehen, solange sie in ihrer Qualität einigermaßen vergleichbar sind. Prägnanz ist eine Tugend.
- Ihr Programm sollte in einer Sprache implementiert sein, die unter Mac OS X, Linux oder Windows frei verfügbar ist. Ich würde gerne die Programme ausführen können, aber wenn Sie eine großartige Lösung haben, die nur unter MATLAB oder so läuft , ist das in Ordnung.
- Ihr Programm sollte so allgemein wie möglich sein. Es sollte für so viele verschiedene Bilder wie möglich funktionieren, obwohl einige möglicherweise bessere Ergebnisse erzielen als andere. Bestimmtes:
- Es ist ziemlich lahm, ein paar Bilder in das Programm eingebaut zu haben, mit denen es übereinstimmt und auf die es verweist, und dann beim Entschlüsseln das passende Bild zu erzeugen. Es deckt nur wenige Bilder ab.
- Ein Programm, das Bilder von einfachen, flachen, geometrischen Formen aufnehmen und in ein Vektorprimitiv zerlegen kann, ist ziemlich geschickt, aber wenn es bei Bildern ab einer bestimmten Komplexität fehlschlägt, ist es wahrscheinlich nicht allgemein genug.
- Ein Programm, das nur Bilder mit einem bestimmten festen Seitenverhältnis aufnehmen kann, aber gute Arbeit damit leistet, wäre ebenfalls in Ordnung, aber nicht ideal.
- Möglicherweise stellen Sie fest, dass ein Schwarzweißbild mehr Informationen auf kleinerem Raum als ein Farbbild liefert. Auf der anderen Seite kann dies die Bildtypen einschränken, auf die es anwendbar ist. Gesichter kommen in Schwarz und Weiß gut zur Geltung, aber abstrakte Designs schneiden möglicherweise nicht so gut ab.
- Es ist vollkommen in Ordnung, wenn das Ausgabebild kleiner als das Eingabebild ist und ungefähr das gleiche Verhältnis aufweist. Es ist in Ordnung, wenn Sie das Bild vergrößern müssen, um es mit dem Original zu vergleichen. Wichtig ist, wie es aussieht.
- Ihr Programm sollte eine Ausgabe produzieren, die tatsächlich über Twitter gesendet werden kann und unversehrt bleibt. Dies ist nur eine Richtlinie und keine Regel, da ich keine Dokumentation zu den genauen unterstützten Zeichensätzen finden konnte, aber Sie sollten wahrscheinlich Steuerzeichen, funky unsichtbare Kombinationszeichen, Zeichen für den privaten Gebrauch und dergleichen vermeiden.
Bewertungsrubrik
Nehmen wir als allgemeinen Leitfaden für die Einstufung von Lösungen bei der Auswahl meiner akzeptierten Lösung an, dass ich wahrscheinlich Lösungen auf einer 25-Punkte-Skala bewerten werde (dies ist sehr grob und ich werde nichts direkt bewerten, nur mit dies als grundlegende Richtlinie):
- 15 Punkte dafür, wie gut das Codierungsschema eine Vielzahl von Eingabebildern wiedergibt. Dies ist ein subjektives, ästhetisches Urteil
- 0 bedeutet, dass es überhaupt nicht funktioniert, es gibt jedes Mal das gleiche Bild zurück oder so
- 5 bedeutet, dass einige Bilder codiert werden können, obwohl die decodierte Version hässlich aussieht und bei komplizierteren Bildern möglicherweise überhaupt nicht funktioniert
- 10 bedeutet, dass es mit einer Vielzahl von Bildern arbeitet und angenehm aussehende Bilder erzeugt, die gelegentlich unterscheidbar sein können
- 15 bedeutet, dass es perfekte Nachbildungen einiger Bilder erzeugt und selbst bei größeren und komplexeren Bildern etwas erkennbares ergibt. Oder es macht vielleicht keine Bilder, die gut erkennbar sind, sondern schöne Bilder, die eindeutig vom Original abgeleitet sind.
- 3 Punkte für die geschickte Verwendung des Unicode-Zeichensatzes
- 0 Punkte für die einfache Verwendung des gesamten Satzes zulässiger Zeichen
- 1 Punkt für die Verwendung eines begrenzten Satzes von Zeichen, die für die Übertragung über Twitter oder in einer größeren Vielfalt von Situationen sicher sind
- 2 Punkte für die Verwendung einer thematischen Teilmenge von Zeichen, z. B. nur Han-Ideogramme oder nur Zeichen von rechts nach links
- 3 Punkte, um etwas wirklich Ordentliches zu tun, z. B. lesbaren Text zu generieren oder Zeichen zu verwenden, die wie das betreffende Bild aussehen
- 3 Punkte für clevere algorithmische Ansätze und Codestil
- 0 Punkte für 1000 Codezeilen, um das Bild zu verkleinern, als 1 Bit pro Pixel zu behandeln und base64 zu codieren
- 1 Punkt für etwas, das eine Standardcodierungstechnik verwendet und gut geschrieben und kurz ist
- 2 Punkte für etwas, das eine relativ neuartige Codierungstechnik einführt oder das überraschend kurz und sauber ist
- 3 Punkte für einen Einzeiler, der tatsächlich gute Ergebnisse liefert, oder etwas, das neue Wege in der Grafikcodierung beschreitet (wenn dies wie eine geringe Anzahl von Punkten für Neuland erscheint, denken Sie daran, dass ein so gutes Ergebnis wahrscheinlich eine hohe Punktzahl für die Ästhetik hat auch)
- 2 Punkte für Geschwindigkeit. Wenn alles andere gleich ist, ist schneller besser, aber die oben genannten Kriterien sind alle wichtiger als die Geschwindigkeit
- 1 Punkt für die Ausführung auf freier (Open Source) Software, da ich freie Software bevorzuge (beachten Sie, dass C # für diesen Punkt weiterhin berechtigt ist, solange es auf Mono ausgeführt wird, ebenso wäre MATLAB-Code zulässig, wenn es auf GNU Octave ausgeführt wird).
- 1 Punkt für die tatsächliche Einhaltung aller Regeln. Diese Regeln sind etwas umfangreich und kompliziert geworden, daher werde ich wahrscheinlich ansonsten gute Antworten akzeptieren, bei denen ein kleines Detail falsch ist, aber ich werde jeder Lösung, die tatsächlich allen Regeln folgt, einen zusätzlichen Punkt geben
Referenzbilder
Einige Leute haben nach Referenzbildern gefragt. Hier sind einige Referenzbilder, die Sie ausprobieren können. Hier sind kleinere Versionen eingebettet, die alle auf größere Versionen des Bildes verweisen, wenn Sie diese benötigen:
Preis
Ich biete eine Prämie von 500 Wiederholungen (plus die 50, die StackOverflow einsetzt) für die Lösung an, die mir am besten gefällt, basierend auf den oben genannten Kriterien. Natürlich ermutige ich alle anderen, auch hier über ihre Lieblingslösungen abzustimmen.
Hinweis zur Frist
Dieser Wettbewerb läuft, bis das Kopfgeld aufgebraucht ist, am Samstag, den 30. Mai, gegen 18 Uhr. Ich kann nicht genau sagen, wann es enden wird. Es kann zwischen 17 und 19 Uhr sein. Ich werde garantieren, dass ich alle bis 14 Uhr eingereichten Beiträge einsehen werde, und ich werde mein Bestes tun, um alle bis 16 Uhr eingereichten Beiträge zu prüfen. Wenn danach Lösungen eingereicht werden, habe ich möglicherweise keine Chance, sie fair zu betrachten, bevor ich meine Entscheidung treffen muss. Je früher Sie einreichen, desto größer ist auch die Chance, dass Sie abstimmen können, um mir bei der Auswahl der besten Lösung zu helfen. Versuchen Sie also, früher als rechtzeitig einzureichen.
Unicode-Notizen
Es gab auch einige Unklarheiten darüber, welche Unicode-Zeichen genau zulässig sind. Der Bereich möglicher Unicode-Codepunkte liegt U+0000
bei U+10FFFF
. Es gibt einige Codepunkte, deren Verwendung als Unicode-Zeichen in einem offenen Datenaustausch niemals gültig ist. das sind die noncharacters und die Surrogat - Codepunkte . Noncharacters ist in dem definierten Unidode Norm 5.1.0 Abschnitt 16.7 als die Werte U+FFFE
, U+FFFF
, U+
nFFFE
, U+
nFFFF
, wo n ist 1
- 10
hexadezimal, und der Bereich U+FDD0
-U+FDEF
. Diese Werte sind für die anwendungsspezifische interne Verwendung vorgesehen, und konforme Anwendungen können diese Zeichen aus dem von ihnen verarbeiteten Text entfernen. Ersatzcodepunkte, die im Unicode Standard 5.1.0 Abschnitt 3.8 als U+D800
- definiert sind U+DFFF
, werden zum Codieren von Zeichen verwendet, die über die mehrsprachige Grundebene in UTF-16 hinausgehen. Daher ist es unmöglich, diese Codepunkte direkt in der UTF-16-Codierung darzustellen, und es ist ungültig, sie in einer anderen Codierung zu codieren. Für den Zweck dieses Wettbewerbs erlaube ich daher jedem Programm, das Bilder in eine Folge von nicht mehr als 140 Unicode-Codepunkten aus dem Bereich codiert U+0000
- U+10FFFF
mit Ausnahme aller oben definierten Nichtzeichen und Ersatzpaare.
Ich werde Lösungen bevorzugen , die nur zugewiesene Zeichen verwenden, und noch bessere, die clevere Teilmengen von zugewiesenen Zeichen verwenden oder mit dem von ihnen verwendeten Zeichensatz etwas Interessantes tun. Eine Liste der zugewiesenen Zeichen finden Sie in der Unicode- Zeichendatenbank . Beachten Sie, dass einige Zeichen direkt aufgeführt sind, während andere nur als Anfang und Ende eines Bereichs aufgeführt sind. Beachten Sie auch, dass Ersatzcodepunkte in der Datenbank aufgeführt sind, jedoch wie oben erwähnt verboten sind. Wenn Sie bestimmte Eigenschaften von Zeichen nutzen möchten, um den von Ihnen ausgegebenen Text interessanter zu gestalten, stehen verschiedene Datenbanken mit Zeicheninformationen zur Verfügung, z. B. eine Liste benannter Codeblöcke und verschiedene Zeicheneigenschaften.
Da Twitter nicht den genauen Zeichensatz angibt, den sie unterstützen, werde ich bei Lösungen, die mit Twitter nicht funktionieren, nachsichtig sein, da bestimmte Zeichen zusätzlich zählen oder bestimmte Zeichen entfernt werden. Es wird bevorzugt, aber nicht benötigt, dass alle codierten Ausgaben unbeschadet über Twitter oder einen anderen Microblogging-Dienst wie identi.ca übertragen werden können . Ich habe einige Dokumentationen gesehen, die besagen, dass Twitter-Entitäten <,> und & codieren und diese daher als 4, 4 bzw. 5 Zeichen zählen, aber ich habe das nicht selbst getestet, und ihr JavaScript-Zeichenzähler scheint nicht zu sein um sie so zu zählen.
Tipps & Links
- Die Definition gültiger Unicode-Zeichen in den Regeln ist etwas kompliziert. Die Auswahl eines einzelnen Zeichenblocks, z. B. CJK Unified Ideographs (U + 4E00 - U + 9FCF), ist möglicherweise einfacher.
- Sie können vorhandene Bildbibliotheken wie ImageMagick oder Python Imaging Library für Ihre Bildbearbeitung verwenden.
- Wenn Sie Hilfe zum Verständnis des Unicode-Zeichensatzes und seiner verschiedenen Codierungen benötigen, lesen Sie diese Kurzanleitung oder diese ausführlichen FAQ zu UTF-8 unter Linux und Unix .
- Je früher Sie Ihre Lösung erhalten, desto mehr Zeit muss ich (und andere abstimmende Personen) damit verbringen. Sie können Ihre Lösung bearbeiten, wenn Sie sie verbessern. Ich werde mein Kopfgeld auf die neueste Version stützen, wenn ich die Lösungen zum letzten Mal durchschaue.
- Wenn Sie ein einfaches Bildformat zum Parsen und Schreiben wünschen (und nicht nur ein vorhandenes Format verwenden möchten), würde ich die Verwendung des PPM-Formats empfehlen . Es ist ein textbasiertes Format, mit dem man sehr einfach arbeiten kann, und Sie können ImageMagick verwenden , um es zu konvertieren.
quelle
Antworten:
Okay, hier ist meine: nanocrunch.cpp und die Datei CMakeLists.txt , um sie mit CMake zu erstellen . Für den größten Teil der Bildverarbeitung wird die Magick ++ ImageMagick-API verwendet. Für die Zeichenfolgencodierung ist außerdem die GMP- Bibliothek für die Bignum-Arithmetik erforderlich .
Ich habe meine Lösung auf der fraktalen Bildkomprimierung mit ein paar einzigartigen Wendungen basiert. Die Grundidee besteht darin, das Bild aufzunehmen, eine Kopie auf 50% zu verkleinern und nach Stücken in verschiedenen Ausrichtungen zu suchen, die nicht überlappenden Blöcken im Originalbild ähneln. Diese Suche erfordert einen sehr brutalen Ansatz, aber das macht es einfacher, meine Modifikationen einzuführen.
Die erste Modifikation ist, dass mein Programm nicht nur 90-Grad-Rotationen und -Flips betrachtet, sondern auch 45-Grad-Orientierungen berücksichtigt. Es ist ein Bit mehr pro Block, aber es verbessert die Bildqualität immens.
Die andere Sache ist, dass das Speichern einer Kontrast- / Helligkeitsanpassung für jede Farbkomponente jedes Blocks viel zu teuer ist. Stattdessen speichere ich eine stark quantisierte Farbe (die Palette hat nur 4 * 4 * 4 = 64 Farben), die einfach in einem bestimmten Verhältnis eingeblendet wird. Mathematisch entspricht dies einer variablen Helligkeit und einer konstanten Kontrastanpassung für jede Farbe. Leider bedeutet dies auch, dass es keinen negativen Kontrast gibt, um die Farben umzudrehen.
Sobald die Position, Ausrichtung und Farbe für jeden Block berechnet wurde, wird diese in eine UTF-8-Zeichenfolge codiert. Zunächst wird ein sehr großes Bignum generiert, um die Daten in der Blocktabelle und die Bildgröße darzustellen. Der Ansatz hierfür ähnelt der Lösung von Sam Hocevar - eine Art große Zahl mit einem Radix, der je nach Position variiert.
Dann wandelt es das in eine Basis um, unabhängig von der Größe des verfügbaren Zeichensatzes. Standardmäßig wird der zugewiesene Unicode-Zeichensatz vollständig verwendet, abzüglich der Zeichen für "kaufmännisches Und", "Steuern", "Kombinieren" sowie "Ersatz" und "Privat". Es ist nicht schön, aber es funktioniert. Sie können auch die Standardtabelle auskommentieren und stattdessen druckbares 7-Bit-ASCII (wiederum ohne <,> und & Zeichen) oder CJK Unified Ideographs auswählen. In der Tabelle, für die Zeichencodes verfügbar sind, wird eine Lauflänge gespeichert, die mit abwechselnden Läufen ungültiger und gültiger Zeichen codiert ist.
Wie auch immer, hier sind einige Bilder und Zeiten (gemessen auf meinem alten 3,0-GHz-P4), die im oben beschriebenen vollständig zugewiesenen Unicode-Satz auf 140 Zeichen komprimiert wurden. Insgesamt bin ich ziemlich zufrieden mit dem Ergebnis. Wenn ich mehr Zeit hätte, um daran zu arbeiten, würde ich wahrscheinlich versuchen, die Blockade der dekomprimierten Bilder zu verringern. Trotzdem denke ich, dass die Ergebnisse für das extreme Kompressionsverhältnis ziemlich gut sind. Die dekomprimierten Bilder sind etwas impressionistisch, aber ich finde es relativ einfach zu sehen, wie Bits dem Original entsprechen.
Stapelüberlauf-Logo (8,6 Sekunden zum Codieren, 7,9 Sekunden zum Decodieren, 485 Byte):
http://i44.tinypic.com/2w7lok1.png
Lena (32,8 Sekunden zum Codieren, 13,0 Sekunden zum Decodieren, 477 Byte):
http://i42.tinypic.com/2rr49wg.png http://i40.tinypic.com/2rhxxyu.png
Mona Lisa (43,2 Sekunden zum Codieren, 14,5 Sekunden zum Decodieren, 490 Byte):
http://i41.tinypic.com/ekgwp3.png http://i43.tinypic.com/ngsxep.png
Bearbeiten: CJK Unified Characters
Sam fragte in den Kommentaren nach der Verwendung mit CJK. Hier ist eine Version der Mona Lisa, die aus dem CJK Unified-Zeichensatz auf 139 Zeichen komprimiert wurde:
http://i43.tinypic.com/2yxgdfk.png 咏 璘 璘 凄 脒 鵚 据 蛥 鸂 拗 朐 朖 辿 韩 瀦 魷 歪隤 慛 絖 銓 馿 渫 櫰 矍 昀 鰛 掾 撄 粂 敽 牙 稉 擎 蔍 螎 葙 覧 絀 蹔 惫 冧 笻 哜 搀 澐伆 杇 婣 唆 鐤 諽 鷍 鴞 駫 搶 毤 埙 誖 萜 愿 旖 鞰 萗 勹 鈱 垬 濅 鬒 瞛 洆 认 気 狋 異擸 萿
Die Abstimmungsparameter oben im Programm, die ich dafür verwendet habe, waren: 19, 19, 4, 4, 3, 10, 11, 1000, 1000. Ich habe auch die erste Definition von number_assigned und Codes auskommentiert und die kommentiert letzte Definitionen von ihnen, um den CJK Unified-Zeichensatz auszuwählen.
quelle
Bilddateien und Python-Quelle (Version 1 und 2)
Version 1 Hier ist mein erster Versuch. Ich werde aktualisieren, wenn ich gehe.
Ich habe das SO-Logo auf 300 Zeichen fast verlustfrei reduziert. Meine Technik verwendet die Konvertierung in SVG-Vektorgrafiken, sodass sie am besten für Online-Grafiken funktioniert. Es ist eigentlich ein SVG-Kompressor, es erfordert immer noch, dass die ursprüngliche Kunst eine Vektorisierungsstufe durchläuft.
Für meinen ersten Versuch habe ich einen Onlinedienst für die PNG-Ablaufverfolgung verwendet. Es gibt jedoch VIELE kostenlose und nicht kostenlose Tools, die diesen Teil verarbeiten können, einschließlich Potrace (Open Source).
Hier sind die Ergebnisse
Originales SO-Logo http://www.warriorhut.org/graphics/svg_to_unicode/so-logo.png Originales decodiertes SO-Logo http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded.png Nach dem Codieren und Dekodierung
Zeichen : 300
Zeit : Nicht gemessen, aber praktisch sofort (ohne Vektorisierungs- / Rasterisierungsschritte)
In der nächsten Phase werden 4 Symbole (SVG-Pfadpunkte und -Befehle) pro Unicode-Zeichen eingebettet. Im Moment hat mein Python-Build keine breite Zeichenunterstützung UCS4, was meine Auflösung pro Zeichen begrenzt. Ich habe auch den maximalen Bereich auf das untere Ende des reservierten Unicode-Bereichs 0xD800 beschränkt. Sobald ich jedoch eine Liste der zulässigen Zeichen und einen Filter erstellt habe, um sie zu vermeiden, kann ich theoretisch die erforderliche Anzahl von Zeichen auf 70-100 für das verschieben Logo oben.
Eine Einschränkung dieser Methode ist derzeit, dass die Ausgabegröße nicht festgelegt ist. Dies hängt von der Anzahl der Vektorknoten / -punkte nach der Vektorisierung ab. Um diese Grenze zu automatisieren, muss entweder das Bild pixelig gemacht werden (wodurch der Hauptvorteil von Vektoren entfällt) oder die Pfade werden wiederholt durch eine Vereinfachungsstufe geführt, bis die gewünschte Knotenanzahl erreicht ist (was ich derzeit manuell in Inkscape mache).
Version 2
UPDATE : v2 ist jetzt für den Wettbewerb qualifiziert. Änderungen:
Zeichen : 133
Zeit : Einige Sekunden
v2 decodiert http://www.warriorhut.org/graphics/svg_to_unicode/so-logo-decoded-v2.png Nach dem Codieren und Decodieren (Version 2)
Wie Sie sehen können, gibt es diesmal einige Artefakte. Es ist keine Einschränkung der Methode, sondern ein Fehler irgendwo in meinen Konvertierungen. Die Artefakte treten auf, wenn die Punkte außerhalb des Bereichs von 0,0 bis 127,0 liegen und meine Versuche, sie einzuschränken, gemischten Erfolg hatten. Die Lösung besteht einfach darin, das Bild zu verkleinern. Ich hatte jedoch Probleme, die tatsächlichen Punkte und nicht die Zeichenfläche oder die Gruppenmatrix zu skalieren, und bin jetzt zu müde, um mich darum zu kümmern. Kurz gesagt, wenn Ihre Punkte im unterstützten Bereich liegen, funktioniert dies im Allgemeinen.
Ich glaube, der Knick in der Mitte ist darauf zurückzuführen, dass sich ein Griff auf die andere Seite eines Griffs bewegt, mit dem er verbunden ist. Grundsätzlich sind die Punkte in erster Linie zu nahe beieinander. Wenn Sie vor dem Komprimieren einen Vereinfachungsfilter über dem Quellbild ausführen, sollte dies behoben und einige unnötige Zeichen entfernt werden.
UPDATE : Diese Methode eignet sich gut für einfache Objekte, daher brauchte ich eine Möglichkeit, komplexe Pfade zu vereinfachen und Rauschen zu reduzieren. Ich habe Inkscape für diese Aufgabe verwendet. Ich hatte etwas Glück damit, unnötige Pfade mit Inkscape zu entfernen, hatte aber keine Zeit, sie zu automatisieren. Ich habe einige Beispiel-SVGs mit der Inkscape-Funktion "Vereinfachen" erstellt, um die Anzahl der Pfade zu verringern.
Simplify funktioniert in Ordnung, kann aber bei so vielen Pfaden langsam sein.
Autotrace Beispiel 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.warriorhut.com/graphics /svg_to_unicode/lena_std_washed_autotrace.png
Thumbnails verfolgt http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_autotrace.png
Hier sind einige Aufnahmen mit extrem niedriger Auflösung. Diese liegen näher an der Beschränkung auf 140 Zeichen, obwohl möglicherweise auch eine clevere Pfadkomprimierung erforderlich ist.
gepflegt http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_groomed.png Vereinfacht und entfleckt.
trianglulated http://www.warriorhut.org/graphics/svg_to_unicode/competition_thumbnails_triangulated.png Vereinfacht, entfleckt und trianguliert.
OBEN: Vereinfachte Pfade mit Autotrace .
Leider verarbeitet mein Parser die Autotrace-Ausgabe nicht, sodass ich nicht weiß, wie Punkte verwendet werden können oder wie weit sie zu vereinfachen sind. Leider bleibt wenig Zeit, um sie vor Ablauf der Frist zu schreiben. Es ist jedoch viel einfacher zu analysieren als die Inkscape-Ausgabe.
quelle
Meine vollständige Lösung finden Sie unter http://caca.zoy.org/wiki/img2twit . Es hat die folgenden Funktionen:
Hier ist eine grobe Übersicht über den Kodierungsprozess:
Und das ist der Dekodierungsprozess:
Was ich für den originellsten Teil des Programms halte, ist der Bitstream. Anstatt bitausgerichtete Werte (
stream <<= shift; stream |= value
) zu packen, packe ich beliebige Werte, die nicht im Zweierpotenzbereich liegen (stream *= range; stream += value
). Dies erfordert Bignum-Berechnungen und ist natürlich viel langsamer, aber es gibt mir 2009,18 Bit anstelle von 1960, wenn ich die 20902-CJK-Hauptzeichen verwende (das sind drei weitere Punkte, die ich in die Daten einfügen kann). Und wenn ich ASCII verwende, bekomme ich 917,64 Bit anstelle von 840.Ich entschied mich gegen eine Methode für die anfängliche Bildberechnung, die schwere Waffen erfordert hätte (Eckenerkennung, Merkmalsextraktion, Farbquantisierung ...), weil ich zunächst nicht sicher war, ob dies wirklich helfen würde. Jetzt ist mir klar, dass die Konvergenz langsam ist (1 Minute ist akzeptabel, aber dennoch langsam), und ich kann versuchen, dies zu verbessern.
Die Hauptanpassungsschleife ist lose vom Direct Binary Seach-Dithering-Algorithmus inspiriert (bei dem Pixel zufällig vertauscht oder gespiegelt werden, bis ein besserer Halbton erzielt wird). Die Energieberechnung ist ein einfacher quadratischer Mittelwertabstand, aber ich führe zuerst einen 5x5-Medianfilter für das Originalbild durch. Eine Gaußsche Unschärfe würde wahrscheinlich das Verhalten des menschlichen Auges besser darstellen, aber ich wollte keine scharfen Kanten verlieren. Ich habe mich auch gegen simuliertes Tempern oder andere schwer einstellbare Methoden entschieden, da ich keine Monate Zeit habe, um den Prozess zu kalibrieren. Somit repräsentiert das "Qualitäts" -Flag nur die Anzahl der Iterationen, die an jedem Punkt ausgeführt werden, bevor der Codierer endet.
Obwohl nicht alle Bilder gut komprimiert werden, bin ich von den Ergebnissen überrascht und frage mich wirklich, welche anderen Methoden es gibt, mit denen ein Bild auf 250 Byte komprimiert werden kann.
Ich habe auch kleine Filme über die Entwicklung des Encoder-Zustands von einem zufälligen Anfangszustand und von einem "guten" Anfangszustand .
Bearbeiten : So wird die Komprimierungsmethode mit JPEG verglichen. Links das über 536-Byte-Bild von Jamoes. Auf der rechten Seite hat Mona Lisa mit der hier beschriebenen Methode auf 534 Bytes komprimiert (die hier genannten Bytes beziehen sich auf Datenbytes und ignorieren daher Bits, die durch die Verwendung von Unicode-Zeichen verschwendet wurden):
Bearbeiten : CJK-Text wurde gerade durch die neuesten Versionen der Bilder ersetzt.
quelle
Das Folgende ist keine formelle Einreichung, da meine Software in keiner Weise auf die angegebene Aufgabe zugeschnitten wurde. DLI kann als optimierender verlustbehafteter Allzweck-Bildcodec beschrieben werden. Es ist der PSNR- und MS-SSIM-Datensatzhalter für die Bildkomprimierung, und ich dachte, es wäre interessant zu sehen, wie er für diese bestimmte Aufgabe funktioniert. Ich habe das bereitgestellte Referenzbild von Mona Lisa verwendet und es auf 100 x 150 verkleinert. Dann habe ich DLI verwendet, um es auf 344 Byte zu komprimieren.
Mona Lisa DLI http://i40.tinypic.com/2md5q4m.png
Zum Vergleich mit den komprimierten JPEG- und IMG2TWIT-Samples habe ich DLI verwendet, um das Bild ebenfalls auf 534 Byte zu komprimieren. Das JPEG beträgt 536 Bytes und IMG2TWIT 534 Bytes. Die Bilder wurden zum einfachen Vergleich auf ungefähr die gleiche Größe skaliert. JPEG ist das linke Bild, IMG2TWIT ist die Mitte und DLI ist das rechte Bild.
Vergleich http://i42.tinypic.com/302yjdg.png
Das DLI-Bild schafft es, einige der Gesichtszüge zu bewahren, insbesondere das berühmte Lächeln :).
quelle
Der allgemeine Überblick über meine Lösung wäre:
Ich weiß, dass Sie nach Code gefragt haben, aber ich möchte nicht wirklich die Zeit damit verbringen, dies tatsächlich zu codieren. Ich dachte mir, dass ein effizientes Design zumindest jemand anderen dazu inspirieren könnte, dies zu codieren.
Ich denke, der Hauptvorteil meiner vorgeschlagenen Lösung besteht darin, dass so viel vorhandene Technologie wie möglich wiederverwendet wird. Es mag Spaß machen, einen guten Komprimierungsalgorithmus zu schreiben, aber es gibt garantiert einen besseren Algorithmus, der höchstwahrscheinlich von Leuten geschrieben wurde, die einen Abschluss in höherer Mathematik haben.
Ein weiterer wichtiger Hinweis ist jedoch, dass diese Lösung auseinanderfällt, wenn entschieden wird, dass utf16 die bevorzugte Codierung ist. JPEGs funktionieren nicht wirklich, wenn sie auf 280 Bytes komprimiert sind. Vielleicht gibt es für diese spezielle Problemstellung einen besseren Komprimierungsalgorithmus als jpg.
quelle
Okay, ich bin zu spät zum Spiel, aber trotzdem habe ich mein Projekt gemacht.
Es ist ein spielzeuggenetischer Algorithmus, der durchscheinende bunte Kreise verwendet, um das ursprüngliche Bild wiederherzustellen.
Eigenschaften:
Fehlfunktionen:
Hier ist ein Beispiel für Lena, das Lena darstellt:岂 掂 戇 耔 攋 斘 眐 奡 萛 狂 昸 箆 亲 嬎 廙 栃 兡 塅 受 橯 应 戞 优 僘 瑩 吱虲 兙 罨 縨 炘 排 叁 抠 堃 從 弅 慌 螎 熰 標 宑 簫 柢 橙 拃 蜊 缩 昔 舭 勵 癳厇 廩 焛 瀻 严 严 刱 刱 垫
Der Code befindet sich in einem Mercurial-Repository unter bitbucket.org. Schauen Sie sich http://bitbucket.org/tkadlubo/circles.lua an
quelle
Das Folgende ist meine Herangehensweise an das Problem und ich muss zugeben, dass dies ein ziemlich interessantes Projekt war, an dem ich arbeiten musste. Es liegt definitiv außerhalb meines normalen Arbeitsbereichs und hat mir etwas Neues gegeben, über das ich lernen kann.
Die Grundidee hinter mir ist wie folgt:
Es stellt sich heraus, dass dies funktioniert, jedoch nur in begrenztem Umfang, wie Sie den folgenden Beispielbildern entnehmen können. In Bezug auf die Ausgabe folgt ein Beispiel-Tweet, speziell für das in den Beispielen gezeigte Lena-Bild.
Wie Sie sehen können, habe ich versucht, den Zeichensatz ein wenig einzuschränken. Beim Speichern der Bildfarbdaten sind jedoch Probleme aufgetreten. Außerdem neigt dieses Codierungsschema dazu, eine Reihe von Datenbits zu verschwenden, die für zusätzliche Bildinformationen verwendet werden könnten.
In Bezug auf die Laufzeit ist der Code für kleine Bilder extrem schnell, etwa 55 ms für die bereitgestellten Beispielbilder, aber die Zeit nimmt mit größeren Bildern zu. Für das 512 x 512 Lena-Referenzbild betrug die Laufzeit 1182 ms. Ich sollte beachten, dass die Chancen ziemlich gut stehen, dass der Code selbst nicht sehr leistungsoptimiert ist (z. B. wird alles als Bitmap verarbeitet ), sodass die Zeiten nach einigen Umgestaltungen etwas sinken können.
Bitte zögern Sie nicht, mir Vorschläge zu machen, was ich hätte besser machen können oder was mit dem Code falsch sein könnte. Die vollständige Liste der Laufzeiten und der Beispielausgabe finden Sie unter folgendem Speicherort: http://code-zen.info/twitterimage/
Update Eins
Ich habe den RLE-Code aktualisiert, der beim Komprimieren der Tweet-Zeichenfolge verwendet wird, um einen grundlegenden Rückblick zu ermöglichen, und wenn ja, verwenden Sie diesen für die Ausgabe. Dies funktioniert nur für die Zahlenwertpaare, speichert jedoch einige Datenzeichen. Die Laufzeit ist mehr oder weniger gleich wie die Bildqualität, aber die Tweets sind tendenziell etwas kleiner. Ich werde das Diagramm auf der Website aktualisieren, wenn ich die Tests abgeschlossen habe. Was folgt, ist eine der Beispiel-Tweet-Zeichenfolgen, wiederum für die kleine Version von Lena:
Update Zwei
Ein weiteres kleines Update, aber ich habe den Code geändert, um die Farbtöne in Dreiergruppen anstatt in Vier zu packen. Dies beansprucht etwas mehr Platz. Wenn mir jedoch etwas fehlt, sollte dies bedeuten, dass "ungerade" Zeichen nicht mehr dort erscheinen, wo die Farbe ist Daten sind. Außerdem habe ich die Komprimierung etwas weiter aktualisiert, sodass sie jetzt auf die gesamte Zeichenfolge und nicht nur auf den Farbzählblock angewendet werden kann. Ich teste immer noch die Laufzeiten, aber sie scheinen nominell verbessert zu sein. Die Bildqualität ist jedoch immer noch dieselbe. Was folgt, ist die neueste Version des Lena-Tweets:
StackOverflow-Logo 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
quelle
Dieser genetische Algorithmus, den Roger Alsing geschrieben hat, hat ein gutes Kompressionsverhältnis auf Kosten langer Kompressionszeiten. Der resultierende Vektor von Eckpunkten könnte unter Verwendung eines verlustbehafteten oder verlustfreien Algorithmus weiter komprimiert werden.
http://rogeralsing.com/2008/12/07/genetic-programming-evolution-of-mona-lisa/
Wäre ein interessantes Programm, aber ich werde es verpassen.
quelle
In der ursprünglichen Herausforderung ist die Größenbeschränkung als das definiert, was Twitter noch senden kann, wenn Sie Ihren Text in das Textfeld einfügen und auf "Aktualisieren" klicken. Wie einige Leute richtig bemerkt haben, unterscheidet sich dies von dem, was Sie als SMS-Textnachricht von Ihrem Handy aus senden könnten.
Was nicht explizit erwähnt wird (aber was meine persönliche Regel war), ist, dass Sie in der Lage sein sollten, die getwitterte Nachricht in Ihrem Browser auszuwählen, sie in die Zwischenablage zu kopieren und in ein Texteingabefeld Ihres Decoders einzufügen, damit sie angezeigt werden kann. Natürlich können Sie die Nachricht auch als Textdatei speichern und wieder einlesen oder ein Tool schreiben, das auf die Twitter-API zugreift und jede Nachricht herausfiltert, die wie ein Bildcode aussieht (spezielle Markierungen, jemand? Zwinker zwinker ). Die Regel ist jedoch, dass die Nachricht über Twitter gesendet werden muss, bevor Sie sie entschlüsseln dürfen.
Viel Glück mit den 350 Bytes - ich bezweifle, dass Sie sie nutzen können.
quelle
Durch das Posten eines Schwarzweiß- oder Graustufenbilds sollte die Größe des Bilds verbessert werden, das in diesen Bereich codiert werden kann, da Sie sich nicht für Farbe interessieren.
Möglicherweise wird die Herausforderung, drei Bilder hochzuladen, noch größer. Wenn Sie sie neu kombinieren, erhalten Sie ein Vollfarbbild, während in jedem einzelnen Bild eine monochrome Version beibehalten wird.
Fügen Sie etwas Komprimierung zu dem oben genannten hinzu und es könnte anfangen, brauchbar auszusehen ...
Nett!!! Jetzt habt ihr mein Interesse geweckt. Für den Rest des Tages wird keine Arbeit erledigt ...
quelle
In Bezug auf den Codierungs- / Decodierungsteil dieser Herausforderung. base16b.org ist mein Versuch, eine Standardmethode für die sichere und effiziente Codierung von Binärdaten in den höheren Unicode-Ebenen anzugeben.
Einige Eigenschaften :
Entschuldigung, diese Antwort kommt viel zu spät für den ursprünglichen Wettbewerb. Ich habe das Projekt unabhängig von diesem Beitrag gestartet, den ich auf halbem Weg entdeckt habe.
quelle
Die Idee, eine Reihe von Referenzbildern zu speichern, ist interessant. Wäre es so falsch, beispielsweise 25 MB Beispielbilder zu speichern und den Encoder versuchen zu lassen, ein Bild mit Bits davon zu erstellen? Mit solch einer winzigen Pipe wird die Maschinerie an beiden Enden notwendigerweise viel größer sein als das durchgelassene Datenvolumen. Was ist also der Unterschied zwischen 25 MB Code und 1 MB Code und 24 MB Bilddaten?
(Beachten Sie, dass die ursprünglichen Richtlinien ausgeschlossen haben, dass die Eingabe auf Bilder beschränkt wird, die sich bereits in der Bibliothek befinden - das schlage ich nicht vor).
quelle
Dumme Idee,
sha1(my_image)
würde aber zu einer "perfekten" Darstellung jedes Bildes führen (Kollisionen ignorieren). Das offensichtliche Problem ist, dass der Dekodierungsprozess übermäßig viel Brute-Forcing erfordert.1-Bit-Monochrom wäre etwas einfacher. Jedes Pixel wird zu 1 oder 0, sodass Sie 1000 Datenbits für ein 100 * 100-Pixel-Bild haben würden. Da der SHA1-Hash 41 Zeichen hat, können wir drei in eine Nachricht einfügen, müssen nur 2 Sätze von 3333 Bits und einen Satz von 3334 brutal erzwingen (obwohl selbst das wahrscheinlich immer noch unangemessen ist)
Es ist nicht gerade praktisch. Selbst mit dem 1-Bit-100 * 100px-Bild mit fester Länge gibt es .., vorausgesetzt, ich berechne nicht falsch, 49995000 Kombinationen oder 16661667, wenn es in drei geteilt wird.
quelle
Hier ist diese Komprimierung gut.
http://www.intuac.com/userport/john/apt/
http://img86.imageshack.us/img86/4169/imagey.jpg http://img86.imageshack.us/img86/4169/imagey.jpg
Ich habe die folgende Batch-Datei verwendet:
Die resultierende Dateigröße beträgt 559 Byte.
quelle
Idee: Könnten Sie eine Schriftart als Palette verwenden? Versuchen Sie, ein Bild in eine Reihe von Vektoren zu unterteilen, um sie mit einer Kombination von Vektorsätzen zu beschreiben (jedes Zeichen ist im Wesentlichen ein Satz von Vektoren). Hierbei wird die Schriftart als Wörterbuch verwendet. Ich könnte zum Beispiel al für eine vertikale Linie und a - für eine horizontale Linie verwenden? Nur eine Idee.
quelle