Основано на очень успешной задаче кодирования изображений в Twitter в Stack Overflow.
Если изображение стоит 1000 слов, сколько изображения вы можете уместить в 114,97 байтов?
Я призываю вас придумать метод общего назначения для сжатия изображений в стандартный комментарий Twitter, который содержит только печатный текст ASCII .
Правила:
- Вы должны написать программу, которая может взять изображение и вывести закодированный текст.
- Текст, созданный программой, должен содержать не более 140 символов и содержать только символы, кодовые точки которых находятся в диапазоне от 32 до 126 включительно.
- Вы должны написать программу (возможно, ту же самую программу), которая может взять закодированный текст и вывести расшифрованную версию фотографии.
- Ваша программа может использовать внешние библиотеки и файлы, но не требует подключения к Интернету или подключения к другим компьютерам.
- Процесс декодирования не может получить доступ к оригинальным изображениям или содержать их.
- Ваша программа должна принимать изображения как минимум в одном из следующих форматов (необязательно в большем): растровое изображение, JPEG, GIF, TIFF, PNG. Если некоторые или все примеры изображений не в правильном формате, вы можете преобразовать их самостоятельно перед сжатием вашей программой.
Судя:
Это несколько субъективная задача, поэтому победитель будет (в конечном итоге) оценен мной. Я сосредоточу свое суждение на паре важных факторов, перечисленных ниже в порядке убывания важности:
- Способность делать разумную работу по сжатию самых разнообразных изображений, в том числе тех, которые не указаны в качестве образца изображения
- Возможность сохранения контуров основных элементов изображения
- Возможность сжимать цвета основных элементов изображения
- Возможность сохранения контуров и цветов мелких деталей на изображении
- Время сжатия. Хотя не так важно, как хорошо сжато изображение, более быстрые программы лучше, чем более медленные, которые делают то же самое.
Ваша заявка должна включать полученные изображения после распаковки, а также сгенерированный комментарий Twitter. Если возможно, вы также можете дать ссылку на исходный код.
Ответы:
Я улучшил свой метод, добавив фактическое сжатие. Теперь он работает итеративно, выполняя следующее:
Уменьшить изображение, сохранив соотношение сторон (если изображение цветное, цветность выбирается на 1/3 ширины и высоты яркости)
Уменьшить битовую глубину до 4 бит на семпл
Примените медианное прогнозирование к изображению, делая распределение выборки более равномерным
Примените адаптивное сжатие диапазона к изображению.
Смотрите, если размер сжатого изображения <= 112
Наибольшее изображение, которое помещается в 112 байтов, затем используется в качестве конечного изображения, а оставшиеся два байта используются для хранения ширины и высоты сжатого изображения, а также флаг, указывающий, является ли изображение цветным. Для декодирования процесс полностью изменен, и изображение увеличено так, чтобы меньший размер был 128.
Есть некоторые возможности для улучшения, а именно, не все доступные байты используются обычно, но я чувствую, что нахожусь в точке значительного уменьшения отдачи от понижающей дискретизации + сжатия без потерь.
Быстрый и грязный источник C ++
Windows Exe
Мона Лиза (13x20 яркости, 4x6 цветности)
Гинденбург (21x13 яркость)
Горы (яркость 19x14, цветность 6x4)
2D Shapes (21x15 яркость, 7x5 цветность)
источник
Идти
Работает путем рекурсивного деления изображения на регионы. Я пытаюсь разделить регионы с высоким содержанием информации и выбираю разделительную линию, чтобы максимизировать разницу в цвете между двумя регионами.
Каждое деление кодируется с использованием нескольких битов для кодирования разделительной линии. Каждый листовой регион кодируется одним цветом.
Картина Гинденбурга выглядит довольно дерьмово, но другие мне нравятся.
источник
питон
Кодирование требует NumPy , SciPy и Scikit-изображения .
Для декодирования требуется только PIL .
Это метод, основанный на суперпиксельной интерполяции. Для начала каждое изображение делится на 70 одинаковых по размеру областей одинакового цвета. Например, пейзажная картинка делится следующим образом:
Расположен центроид каждой области (до ближайшей растровой точки на сетке, содержащей не более 402 точек), а также ее средний цвет (из 216 цветовой палитры), и каждая из этих областей кодируется как число от 0 до 86832 , который может быть сохранен в виде 2,5 печатных символов ascii (фактически 2.497 , оставляя достаточно места для кодирования в битах оттенков серого).
Если вы внимательны, вы могли заметить, что 140 / 2,5 = 56 регионов, а не 70, как я говорил ранее. Однако обратите внимание, что каждая из этих областей является уникальным сопоставимым объектом, который может быть указан в любом порядке. Из-за этого мы можем использовать перестановку первых 56 областей для кодирования для остальных 14 , а также иметь несколько битов, оставшихся для сохранения соотношения сторон.
Более конкретно, каждая из дополнительных 14 областей преобразуется в число, и затем каждое из этих чисел объединяется вместе (умножая текущее значение на 86832 и добавляя следующее). Это (гигантское) число затем преобразуется в перестановку на 56 объектов.
Например:
будет выводить:
Полученная перестановка затем применяется к исходным 56 областям. Исходное число (и, следовательно, дополнительные 14 областей) также может быть извлечено путем преобразования перестановки 56 кодированных областей в ее числовое представление.
Когда
--greyscale
опция используется с кодировщиком, вместо нее используются 94 области (разделенные 70 , 24 ), с 558 точками растра и 16 оттенками серого.При декодировании каждая из этих областей рассматривается как трехмерный конус, вытянутый в бесконечность, с вершиной в центре тяжести области, если смотреть сверху (он же диаграмма Вороного). Затем границы смешиваются для создания конечного продукта.
Будущие улучшения
Размеры Моны Лизы немного отличаются, из-за того, как я храню соотношение сторон. Мне нужно использовать другую систему.Исправлено, предполагая, что исходное соотношение сторон находится где-то между 1:21 и 21: 1, что я считаю разумным предположением.Гинденбург мог бы быть значительно улучшен. Цветовая палитра, которую я использую, имеет только 6 оттенков серого. Если бы я ввел режим только в оттенках серого, я мог бы использовать дополнительную информацию для увеличения глубины цвета, количества областей, количества растровых точек или любой комбинации этих трех.Я добавил--greyscale
опцию в кодировщик, который выполняет все три.2d Shapes, вероятно, будет выглядеть лучше с выключенным смешиванием. Я, вероятно, добавлю флаг для этого.Добавлена опция кодировщика для управления коэффициентом сегментации и опция декодера для отключения смешивания.а также
Второй кодируется с
--greyscale
опцией.Закодировано с
--greyscale
опцией.Закодировано с
--ratio 60
, и расшифровано с--no-blending
вариантами.encoder.py
decoder.py
my_geom.py
источник
PHP
ОК, у меня ушло некоторое время, но вот оно. Все изображения в оттенках серого. Цвета заняли слишком много бит для кодирования для моего метода: P
Мона Лиза
47 Цветов Монохромная
101- байтовая строка.
2D Shapes
36 Colours Monochrome
105- байтовая строка.
Гинденбург
62 Цвета Монохромный
112 знаков.
Горы
63 Цвета Монохромный
122 знака.
Мой метод
Я кодирую свой битовый поток с типом кодировки base64. Перед тем, как закодировать в читаемый текст, вот что происходит.
Я загружаю исходное изображение и изменяю его размеры до максимальной высоты или ширины (в зависимости от ориентации, портрета / ландшафта) в 20 пикселей.
Затем я перекрашиваю каждый пиксель нового изображения в наиболее близкое соответствие на 6-цветной палитре оттенков серого.
После этого я создаю строку с каждым цветом пикселей, представленным буквами [AF].
Затем я вычисляю распределение 6 различных букв в строке и выбираю наиболее оптимизированное двоичное дерево для кодирования на основе частот букв. Есть 15 возможных бинарных деревьев.
Я начинаю свой битовый поток с одного бита, в
[1|0]
зависимости от того, высокое изображение или широкое. Затем я использую следующие 4 бита в потоке, чтобы сообщить декодеру, какое двоичное дерево следует использовать для декодирования изображения.Далее следует поток битов, представляющих изображение. Каждый пиксель и его цвет представлены 2 или 3 битами. Это позволяет мне хранить информацию размером не менее 2 и не более 3 пикселей для каждого печатного символа ascii. Вот пример бинарного дерева
1110
, которое использует Мона Лиза:Буквы E
00
и F10
являются наиболее распространенными цветами в Мона Лиза. A010
, B011
, C110
и D111
являются наименее частыми.Двоичные деревья работают следующим образом:
0
переходя от одного к другому, значит идти налево,1
значит идти направо. Продолжайте идти, пока не столкнетесь с листом дерева или тупиком. Лист, на котором вы оказались, - это тот персонаж, который вам нужен.В любом случае, я кодирую двоичный код в символы base64. При декодировании строки процесс выполняется в обратном порядке, назначая все пиксели соответствующему цвету, а затем изображение масштабируется вдвое по сравнению с кодированным размером (максимум 40 пикселей по X или Y, в зависимости от того, что больше), а затем сверточная матрица применяется ко всему, чтобы сгладить цвета.
В любом случае, вот текущий код: « вставить ссылку »
Это некрасиво, но если вы видите какие-либо возможности для улучшений, дайте мне знать. Я взломал это вместе, как я хочу вместе. Я ИЗУЧИЛ МНОГО ОТ ЭТОГО ВЫЗОВА. Спасибо ОП за размещение!
источник
Моя первая попытка Это имеет место для улучшения. Я думаю, что сам формат на самом деле работает, проблема в кодировщике. Это, и я пропускаю отдельные биты из моего вывода ... мой файл (немного более высокого качества, чем здесь) в итоге получил 144 символа, тогда как некоторые из них должны были остаться. (и мне бы очень хотелось - различия между этими и теми заметны). Я понял, что никогда не переоцениваю, насколько велик 140 символов ...
Я приведу его к модифицированной версии палитры RISC-OS - в основном, потому что мне нужна 32-цветовая палитра, и это казалось достаточно хорошим местом для начала. Я думаю, это тоже может быть связано с некоторыми изменениями.
Я разбил его на следующие формы: и разделил изображение на блоки палитры (в данном случае 2x2 пикселя) переднего и заднего цветов.
Результаты:
Ниже приведены твиты, оригиналы и способ их расшифровки.
Я знаю, что цвета неправильные, но на самом деле мне нравится Monalisa. Если бы я убрал размытие (что не было бы слишком сложно), это разумное кубистское впечатление: p
Мне нужно работать над
Позже я дам еще немного работы, чтобы попытаться исправить это и улучшить кодировщик. Эти дополнительные 20 или около того персонажей имеют огромное количество различий. Я хотел бы их вернуть.
Исходный текст и цветовая палитра C # находятся на https://dl.dropboxusercontent.com/u/46145976/Base96.zip - хотя, оглядываясь назад, они могут не работать идеально при отдельном запуске (поскольку пробелы в аргументах программ не так Что ж).
Кодер на моей довольно средней машине занимает меньше пары секунд.
источник
Я отказался от попыток сохранить цвет и стал черным и белым, поскольку все, что я пробовал с цветом, было неузнаваемо.
По сути, все, что он делает, это разделяет пиксели на 3 примерно равные части: черный, серый и белый. Это также не сохраняет размер.
Гинденбург
Мона Лиза
Горы
Формы
Вот программа.
python compress.py -c img.png
сжимаетimg.png
и печатает твит.python compress.py -d img.png
берет твит со стандартного ввода и сохраняет изображение вimg.png
.источник
Мой скромный вклад в R:
Идея состоит в том, чтобы просто уменьшить растр (файл должен быть в формате png) до матрицы, чей номер ячейки меньше 140, тогда твиты представляют собой серию цветов (в 64 цветах), перед которыми стоят два символа, обозначающие количество строк. и столбцы растра.
источник
Не полное решение, просто использование метода. (Matlab)
Я использовал 16 цветовой палитры и 40 позиций для создания взвешенной диаграммы Вороного . Используется генетический алгоритм и простой алгоритм восхождения на холм, чтобы соответствовать изображению.
Альбом с оригинальным изображением, и у меня также есть 16-байтовая версия с 4 цветами и фиксированными позициями там. :)
(Могу ли я изменить размер изображения здесь?)
источник
C #
Обновление - версия 2
Я предпринял еще одну попытку, теперь использую MagickImage.NET ( https://magick.codeplex.com/ ) для кодирования данных JPEG, я также написал некоторый базовый код для лучшей обработки данных заголовка JPEG (как и предполагал primo), я также использовал GuassianBlur на выходе, который помогает смягчить некоторые сжатия JPEG. Поскольку новая версия лучше преформируется, я обновил свой пост, чтобы отразить новый метод.
метод
Я попробовал что-то уникальное (надеюсь) вместо того, чтобы пытаться манипулировать глубиной цвета или идентификацией краев, или пытаться использовать различные способы для уменьшения размера изображений самостоятельно. Я использовал алгоритм JPEG при максимальном сжатии в уменьшенных версиях изображения, затем удалив все, кроме «StartOfScan» ( http://en.wikipedia.org/wiki/JPEG#Syntax_and_structure ) и нескольких ключевых элементов заголовка, и я могу уменьшить размер до приемлемого уровня. На самом деле результаты довольно впечатляющие для 140 символов, что дает мне новое уважение к JPEG:
Гинденбург
Горы
Мона Лиза
Формы
Код
Версия 2 - http://pastebin.com/Tgr8XZUQ
Я действительно начинаю скучать по ReSharper + У меня есть множество вещей, которые можно улучшить, все еще здесь идет много жесткого кодирования, хотя интересно поэкспериментировать (помните, что вам нужны библиотеки MagickImage, чтобы заставить его работать в VS)
Оригинал (устарел) - http://pastebin.com/BDPT0BKT
Все еще немного беспорядка.
источник
Python 3
метод
Сначала программа уменьшает масштаб изображения, значительно уменьшая его размер.
Во-вторых, он преобразует значения rgb в двоичные и отбирает последние несколько цифр.
Затем он преобразует данные базы 2 в базу 10, где добавляет размеры изображения.
Затем он преобразует данные из базы 10 в базу 95, используя все, что я смог найти. Однако я не мог использовать / x01 и тому подобное из-за его способности отменять функцию, записывающую текстовый файл.
И (для дополнительной неоднозначности) функция декодирования делает это в обратном порядке.
compress.py
decode.py
Крик
Мона Лиза
Spheres
источник