Представьте себе непрерывный двухмерный путь, который может поворачивать только влево, вправо или идти прямо, не может пересекаться сам и должен заполнять прямоугольную сетку, например сетку пикселей на изображении. Мы назовем этот путь змеей .
Этот увеличенный пример показывает путь змеи в сетке 10 × 4, который начинается красным и увеличивается на 2% на каждом шаге, пока не станет фиолетовым. (Черные линии только для того, чтобы подчеркнуть направление, в котором они движутся.)
Цель
Цель этого конкурса популярности - написать алгоритм, который пытается воссоздать данное изображение, используя одну змею, цвет которой постоянно меняется на небольшие величины.
Ваша программа должна принимать изображение истинного цвета любого размера, а также значение с плавающей запятой от 0 до 1 включительно, допуск .
Допуск определяет максимальную величину, которую цвет змеи может изменять на каждом шаге в пикселях. Мы определим расстояние между двумя цветами RGB как евклидово расстояние между двумя точками RGB, когда они расположены на цветном кубе RGB . Расстояние будет нормализовано, поэтому максимальное расстояние равно 1, а минимальное расстояние равно 0.
Псевдокод цветового расстояния: (Предполагается, что все входные значения являются целыми числами в диапазоне [0, 255]
; выход нормализован.)
function ColorDistance(r1, g1, b1, r2, g2, b2)
d = sqrt((r2 - r1)^2 + (g2 - g1)^2 + (b2 - b1)^2)
return d / (255 * sqrt(3))
Если результат вызова этой функции для текущего цвета змеи и другого цвета больше заданного допуска, то змея может не смениться на этот другой цвет.
Если вы предпочитаете, вы можете использовать другую функцию цветового расстояния. Это должно быть что-то точное и хорошо задокументированное, например, перечисленное на http://en.wikipedia.org/wiki/Color_difference . Вы также должны нормализовать его, чтобы оно было в пределах [0, 1]
, т. Е. Максимально возможное расстояние должно быть 1, а минимальное должно быть 0. Сообщите нам в своем ответе, если вы используете другую метрику расстояния.
Тестовые изображения
Вы, конечно, должны опубликовать свои выходные изображения (и даже анимацию растущей змеи, если хотите). Я предлагаю опубликовать множество этих изображений, используя разные низкие допуски (возможно, около 0,005 до 0,03).
Критерии победы
Как уже говорилось, это конкурс популярности. Ответ, получивший наибольшее количество голосов, победит. Ответы, которые обеспечивают наиболее точное и эстетически приятное изображение «змеиной траектории» входных изображений, должны быть поставлены на голосование.
Любой пользователь, который, как установлено, злонамеренно представляет изображения, которые не являются настоящими змеями, будет дисквалифицирован навсегда.
Заметки
- Можно использовать только один путь змеи, и он должен полностью заполнить изображение, не касаясь одного и того же пикселя дважды.
- Змея может начинаться и заканчиваться где угодно на изображении.
- Змея может начинаться как любой цвет.
- Змея должна оставаться в границах изображения. Границы не являются циклическими.
- Змея не может двигаться по диагонали или более чем на один пиксель за раз.
источник
Ответы:
питон
Я генерирую динамический путь, чтобы минимизировать изменения цвета при перемещении змеи. Вот несколько изображений:
допуск = 0,01
Циклические цветовые контуры для вышеуказанных изображений (от синего к красному, становясь зеленее при повторении)
Путь генерируется, начиная с некоторого начального пути, затем добавляя к нему циклы 2х2, пока изображение не будет заполнено. Преимущество этого метода заключается в том, что петли можно добавлять в любом месте пути, поэтому вы не можете нарисовать себя в углу и иметь больше свободы для построения желаемого пути. Я отслеживаю возможные петли, смежные с текущим путем, и сохраняю их в куче, взвешенной по изменению цвета вдоль петли. Затем я выскакиваю из цикла с наименьшим изменением цвета и добавляю его к пути, и повторяю, пока изображение не будет заполнено.
Я фактически отслеживаю только циклы ('DetourBlock' в коде), а затем восстанавливаю путь; это было ошибкой, так как есть некоторые особые случаи для нечетной ширины / высоты, и я потратил несколько часов на отладку метода реконструкции. Ну что ж.
Метрика генерации пути нуждается в настройке, и у меня также есть идея для лучшей окраски, но я подумал, что сначала это получу, так как она работает довольно хорошо. За исключением этого, который кажется лучше в некоторых фиксированных путях:
Вот код Python с извинениями за мои ужасные привычки кодирования:
И еще несколько изображений с очень низким допуском 0,001 :
А также путь великой волны, потому что он аккуратный:
РЕДАКТИРОВАТЬ
Генерирование пути выглядит лучше при минимизации цветового расстояния между средними цветами соседних блоков, а не при минимизации суммы цветовых расстояний между соседними пикселями. Кроме того, оказывается, что вы можете усреднить цвета любых двух совместимых с допусками путей змей и в итоге получить еще один допуск-совместимый путь змей. Таким образом, я пересекаю путь в обоих направлениях и усредняю их, что сглаживает множество артефактов. Зомби Лена и Страшные Руки Моны выглядят намного лучше. Окончательные версии:
Допуск 0,01 :
Допуск 0,001 :
источник
Джава
Моя программа генерирует путь змеи для заданной ширины и высоты, используя алгоритм, аналогичный тому, который генерирует кривую Гильберта.
(маленькая игра: на картинке выше змея начинается в верхнем левом углу. Можете ли вы найти, где он заканчивается? Удачи :)
Вот результаты для различных значений допуска:
Допуск = 0,01
Допуск = 0,05
Допуск = 0,1
Допуск = 0,01
С блоками 4x4 пикселей и видимым путем
Вычисление пути змеи
Путь змеи хранится в массиве целых чисел двойного измерения. Змея всегда входит в сетку в верхнем левом углу. Моя программа может выполнить 4 основных действия по заданному пути змеи:
создайте новый путь змеи для сетки шириной 1 или высотой 1. Путь - это простая линия, которая идет слева направо или вверх вниз, в зависимости от случая.
увеличьте высоту сетки, добавив сверху путь змеи слева направо, а затем отразив сетку (змея всегда должна входить в сетку в верхнем левом углу)
увеличить ширину сетки, добавив слева путь змеи сверху вниз, затем перевернув сетку (змея всегда должна входить в сетку в верхнем левом углу)
удвоить размерность сетки, используя алгоритм «гильбертова стиля» (см. описание ниже)
Используя серию этих атомарных операций, программа может генерировать путь змеи любого заданного размера.
Приведенный ниже код вычисляет (в обратном порядке), какие операции потребуются для получения заданной ширины и высоты. После вычисления действия выполняются одно за другим, пока мы не получим путь змеи ожидаемого размера.
Удвоение размера пути змеи:
Алгоритм, который удваивает размер, работает следующим образом:
Рассмотрим этот узел, который связан с ПРАВО и ВНИЗ. Я хочу удвоить его размер.
Есть 2 способа удвоить его размер и сохранить одинаковые выходы (справа и снизу):
или
Чтобы определить, какой из них выбрать, мне нужно обработать для каждого направления узла значение «смещения», указывающее, сдвинута ли выходная дверь влево / вправо или вверх / вниз. Я следую пути, как змея, и обновляю значение сдвига вдоль пути. Значение смещения однозначно определяет, какой расширенный блок мне нужно использовать для следующего шага.
источник
питон
Вот очень простой алгоритм для начала работы. Он начинается в верхнем левом углу изображения и вращается по часовой стрелке внутрь, делая цвет максимально приближенным к цвету следующего пикселя, оставаясь в пределах допуска.
Запуск больших изображений занимает минуту или две, хотя я уверен, что спиральная логика может быть значительно оптимизирована.
Полученные результаты
Они интересные, но не великолепные. Удивительно, что допуск выше 0,1 дает довольно точные результаты.
Великая волна с допуском 0,03:
Мона Лиза с допуском 0,02:
Лена при допуске 0,03, затем 0,01, затем 0,005, затем 0,003:
Разное с допуском 0,1, затем 0,07, затем 0,04, затем 0,01:
источник
кобра
Заполняет изображение змеей, как:
Это обеспечивает гораздо более быструю настройку цвета, чем просто линии в чередующихся направлениях, но не становится таким блочным, как в версии с шириной 3.
Даже при очень низких допусках края изображения все еще видны (хотя с потерей деталей в меньших разрешениях).
0,01
0,1
0,01
0,01
0,1
0.03
0,005
источник
C #
Змея начинается с верхнего левого пикселя с белым цветом и чередуется слева направо, а затем справа налево вниз по изображению.
Результирующая устойчивость изображения = 0,1
источник