Вам дано истинное цветное изображение. Ваша задача - создать версию этого изображения, которая выглядит так, как будто она была нарисована с использованием рисования по номерам (детская деятельность, а не нонограммы). Наряду с изображением вам задаются два параметра: P - максимальный размер цветовой палитры (т.е. максимальное количество используемых цветов) и N - максимальное количество используемых ячеек . Ваш алгоритм не должен использовать все цвета P и N ячеек, но он не должен использовать больше, чем это. Выходное изображение должно иметь те же размеры, что и входное.
Клетка определяются как непрерывная область пикселей , которые все имеют один и тот же цвет. Пиксели, соприкасающиеся только с углом, не считаются смежными. Клетки могут иметь отверстия.
Короче говоря, вы должны аппроксимировать входное изображение только N плоскими / сплошными областями и P различными цветами.
Просто для наглядности параметров, вот очень простой пример (без какого-либо конкретного входного изображения; демонстрируя мои безумные навыки рисования). Следующее изображение имеет P = 6 и N = 11 :
Вот несколько изображений для проверки вашего алгоритма (в основном наши обычные подозреваемые). Нажмите на картинку для увеличения.
Пожалуйста, включите несколько результатов для различных параметров. Если вы хотите показать большое количество результатов, вы можете создать галерею на imgur.com , чтобы размер ответов был разумным. В качестве альтернативы, поместите миниатюры в свой пост и сделайте их ссылками на большие изображения, как я делал выше. Кроме того, не стесняйтесь использовать другие тестовые изображения, если вы найдете что-то хорошее.
Я предполагаю, что параметры около N ≥ 500 , P ~ 30 будут аналогичны реальным шаблонам рисования по номерам.
Это конкурс популярности, поэтому победит ответ с наибольшим количеством голосов. Избирателям предлагается судить ответы по
- насколько хорошо исходные изображения являются приблизительными.
- насколько хорошо алгоритм работает на разных видах изображений (картины, как правило, проще, чем фотографии).
- насколько хорошо алгоритм работает с очень строгими параметрами.
- как органично / гладко выглядят клеточные формы.
Я буду использовать следующий скрипт Mathematica для проверки результатов:
image = <pastedimagehere> // ImageData;
palette = Union[Join @@ image];
Print["P = ", Length@palette];
grid = GridGraph[Reverse@Most@Dimensions@image];
image = Flatten[image /. Thread[palette -> Range@Length@palette]];
Print["N = ",
Length@ConnectedComponents[
Graph[Cases[EdgeList[grid],
m_ <-> n_ /; image[[m]] == image[[n]]]]]]
Sp3000 был достаточно любезен, чтобы написать верификатор в Python 2, используя PIL, который вы можете найти на этой вставке .
источник
Ответы:
Python 2 с PIL ( Галерея )
Время обновления! Это обновление имеет простой алгоритм сглаживания, чтобы сделать изображение менее размытым. Если я обновлюсь снова, мне придется переделывать значительную часть моего кода, хотя, потому что он становится грязным, и я собираюсь изменить его.
Я также сделал весовые коэффициенты k-средних на основе размеров ячеек, что приводит к потере некоторых деталей для более ограничительных параметров (например, центра туманности и вил американской готики), но делает общий выбор цветов более четким и приятным. Интересно, что он теряет весь фон для трассированных лучей сфер при P = 5.
Краткое изложение алгоритма:
Время обработки каждого изображения в значительной степени зависит от его размера и сложности, а время для тестовых изображений составляет от 20 секунд до 7 минут.
Поскольку алгоритм использует рандомизацию (например, слияние, k-средних), вы можете получить разные результаты на разных прогонах. Вот сравнение двух серий для изображения медведя с N = 50 и P = 10:
Примечание: все изображения ниже являются ссылками. Большинство этих изображений прямо с первого запуска, но если мне не понравился результат, я позволил себе до трех попыток быть честным.
N = 50, P = 10
N = 500, P = 30
Но я довольно ленив, когда дело доходит до рисования цветами, так что просто для удовольствия ...
N = 20, P = 5
Кроме того, забавно видеть, что происходит, когда вы пытаетесь сжать 1 миллион цветов в N = 500, P = 30:
Вот пошаговое пошаговое руководство по алгоритму для подводного изображения с N = 500 и P = 30 в анимированной форме GIF:
Я также сделал галерею для предыдущих версий алгоритма здесь . Вот некоторые из моих любимых из последней версии (с того момента, когда на туманности было больше звезд, а медведь выглядел более меховым):
источник
im = im.convert("RGB")
это необходимо для некоторых фотографий. Я добавлю это после небольшой реструктуризации кода.Python 2 с PIL
Также решение Python и, вероятно, очень много в стадии разработки:
Алгоритм следует другому подходу, нежели SP3000, начиная с цветов:
Найдите цветовую палитру P цветов с помощью k-средних кластеров и раскрасьте изображение в этой уменьшенной палитре.
Примените небольшой средний фильтр, чтобы избавиться от шума.
Составьте список всех монохроматических ячеек и отсортируйте их по размеру.
Объединяйте наименьшие ячейки с соответствующими соседями, пока не останется только N ячеек.
Существует достаточно возможностей для улучшения, как с точки зрения скорости, так и качества результатов. Особенно этап слияния клеток может занимать много минут и дает далеко не оптимальные результаты.
P = 5, N = 45
P = 10, N = 50
P = 4, N = 250
P = 11, N = 500
источник
Mathematica
В данный момент для этого требуется количество цветов и гауссов радиус, которые будут использоваться в фильтре Гаусса. Чем больше радиус, тем больше размытие и слияние цветов.
Поскольку он не позволяет вводить количество ячеек, он не соответствует одному из основных требований задачи.
Вывод включает в себя количество ячеек для каждого цвета, а также общее количество ячеек.
Обновить
quantImage2
позволяет указать желаемое количество ячеек в качестве входных данных. Он определяет лучший радиус Гаусса, просматривая сценарии с большими радиусами, пока не будет найдено близкое соответствие.quantImage2
выходы (изображение, запрошенные ячейки, использованные ячейки, ошибка, использованный радиус Гаусса).Это, однако, очень медленно. Чтобы сэкономить время, вы можете начать с начального радиуса, значение по умолчанию которого равно 0.
Пример, для которого мы указываем желаемое количество ячеек в выводе.
Пример запроса 90 ячеек с 25 цветами. Решение возвращает 88 клеток, ошибка 2%. Функция выбрала радиус Гаусса 55. (много искажений).
Примеры, для которых ввод включает в себя радиус Гаусса, но не количество ячеек.
25 цветов, гауссов радиус 5 пикселей
Три цвета, радиус 17 пикселей
Двадцать цветов, радиус 17 пикселей
Мы увеличили количество цветов, но не фокус. Обратите внимание на увеличение количества клеток.
Шесть цветов, радиус 4 пикселя
Звездная ночь
Всего 6 цветов и 60 ячеек. Существует несоответствие цветов в цветах, которые
showColors
он использует. (Желтый не появляется среди 5 цветов, но он используется на рисунке.) Я посмотрю, смогу ли я понять это.источник
showColors
, просматривая диапазон цветов и радиусов и выбирая комбинацию, наиболее близкую к требуемому количеству ячеек. Не уверен, что у меня есть газ, чтобы сделать это в данный момент. Возможно позже.Python 2 с PIL
Это все еще в стадии разработки. Кроме того, приведенный ниже код представляет собой ужасный беспорядок спагетти, и его не следует использовать в качестве вдохновения. :)
Как это работает
Программа делит холст на
P
области, каждая из которых состоит из некоторого количества ячеек без отверстий. Изначально холст просто делится на приблизительные квадраты, которые случайным образом назначаются регионам. Затем эти области «деформируются» в итеративном процессе, где данный пиксель может изменить свою область, еслиПоследнее условие может быть применено локально, поэтому процесс немного напоминает клеточный автомат. Таким образом, нам не нужно выполнять поиск пути или что-то подобное, что значительно ускоряет процесс. Однако, поскольку клетки не могут быть разрушены, некоторые из них в конечном итоге становятся длинными "нитями", которые граничат с другими клетками и препятствуют их росту. Чтобы это исправить, существует процесс, называемый «разрезание нити», который иногда разбивает ячейку в форме нити на две части, если
N
в это время клеток меньше . Клетки также могут исчезнуть, если их размер равен 1, и это освобождает место для порезов нитей.Процесс заканчивается, когда ни у одного пикселя нет стимула для переключения областей, и после этого каждая область просто окрашивается своим средним цветом. Обычно на выходе остаются нити, как видно из приведенных ниже примеров, особенно в туманности.
P = 30, N = 500
Больше фотографий позже.
Некоторые интересные свойства моей программы заключаются в том, что она вероятностная, поэтому результаты могут отличаться в зависимости от разных прогонов, если, конечно, вы не используете одно и то же псевдослучайное начальное число. Случайность не является существенной, однако, я просто хотел избежать любых случайных артефактов, которые могут возникнуть в результате того, как Python пересекает набор координат или что-то подобное. Программа имеет тенденцию использовать все
P
цвета и почти всеN
ячейки, и ячейки никогда не содержат отверстий по дизайну. Кроме того, процесс деформации довольно медленный. Цветные шары заняли почти 15 минут, чтобы произвести на моей машине. С другой стороны, вы включаетеGRAPHICAL_LOGGING
вариант, вы получите классную серию фотографий процесса деформации. Я сделал из Mona Lisa анимацию в формате GIF (уменьшил на 50%, чтобы уменьшить размер файла). Если вы присмотритесь к ее лицу и волосам, вы сможете увидеть процесс резки нитей в действии.источник