Напишите программу , которая принимает в стандартных полноцветный изображениях и одного 24-битного RGB цвета (три числа от 0 до 255). Измените входное изображение (или выведите новое изображение с такими же размерами), чтобы его средний цвет был точно единственным цветом, который был введен. Вы можете изменить пиксели во входном изображении любым удобным для вас способом, но цель состоит в том, чтобы сделать цветовые изменения настолько визуально незаметными, насколько это возможно .
Средний цвет из RGB изображений действительно набор из трех средних арифметических , по одному для каждого цветового канала. Среднее значение красного является суммой значений красного для всех пикселей изображения, разделенных на общее количество пикселей (область изображения), округленное до ближайшего целого числа. Зеленые и синие средние рассчитываются одинаково.
Этот скрипт Python 2 (с PIL ) может вычислить средний цвет большинства форматов файлов изображений:
from PIL import Image
print 'Enter image file'
im = Image.open(raw_input()).convert('RGB')
pixels = im.load()
avg = [0, 0, 0]
for x in range(im.size[0]):
for y in range(im.size[1]):
for i in range(3):
avg[i] += pixels[x, y][i]
print 'The average color is', tuple(c // (im.size[0] * im.size[1]) for c in avg)
(Есть аналогичные средний цвет программ здесь , но они не обязательно делать точно такой же расчет) .
Основное требование для вашей программы заключается в том, что для любого входного изображения средний соответствующий цвет его выходного сигнала должен точно соответствовать цвету, который был введен, - согласно фрагменту кода Python или некоторому эквивалентному коду. Выходное изображение также должно иметь те же размеры, что и входное изображение.
Таким образом, вы можете технически представить программу, которая просто окрашивает весь входной сигнал указанным средним цветом (потому что этот цвет всегда будет средним), но это конкурс популярности - победит представление с наибольшим количеством голосов , и такая тривиальная представление не принесет вам много голосов. Новые идеи, такие как использование преимуществ в человеческом зрении или уменьшение изображения и рисование цветной рамки вокруг него, (будем надеяться) принесут вам голоса.
Обратите внимание, что определенные комбинации средних цветов и изображений требуют чрезвычайно заметных изменений цвета. Например, если средний цвет для сопоставления был черным (0, 0, 0), любое входное изображение нужно было бы сделать полностью черным, потому что, если бы любые пиксели имели ненулевые значения, они также делали бы среднее ненулевое значение ( исключая ошибки округления). Учитывайте такие ограничения при голосовании.
Тестовые изображения
Некоторые изображения и их стандартные цвета по умолчанию для игры. Нажмите для полного размера.
А. среднее (127, 127, 127)
От fejesjoco «s Изображения со всеми цветами ответ . Нашел оригинал в своем блоге .
Б. средний (62, 71, 73)
Yokohama . Предоставлено Geobits .
C. средний (115, 112, 111)
Токио . Предоставлено Geobits .
D. средний (154, 151, 154)
Е. среднее (105, 103, 102)
Гора Шаста . Предоставлено мной.
F. среднее (75, 91, 110)
Примечания
- Точные форматы ввода и вывода и типы файлов изображений, используемые вашей программой, не имеют большого значения. Просто убедитесь, что понятно, как использовать вашу программу.
- Вероятно, это хорошая идея (но технически не является обязательным требованием), что если изображение уже имеет целевой средний цвет, оно должно выводиться как есть.
- Пожалуйста, опубликуйте тестовые изображения со средним входным цветом (150, 100, 100) или (75, 91, 110), чтобы избиратели могли видеть одни и те же входные данные в разных решениях. (Публиковать больше примеров, чем это хорошо, даже рекомендуется.)
источник
Ответы:
Python 2 + PIL, простое масштабирование цвета
Вот наивный подход, который должен послужить хорошей базой. На каждой итерации мы сравниваем наше текущее среднее с желаемым средним и масштабируем RGB каждого пикселя в соответствии с соответствующим соотношением. Мы должны быть немного осторожны по двум причинам:
Масштабирование 0 все еще приводит к 0, поэтому, прежде чем масштабировать, мы добавим что-то маленькое (здесь
0.01
)Значения RGB находятся в диапазоне от 0 до 255, поэтому мы должны соответствующим образом изменить соотношение, чтобы компенсировать тот факт, что масштабирование ограниченных пикселей ничего не делает.
Изображения сохраняются в формате PNG, потому что при сохранении в формате JPG средние значения цвета портятся.
Образец вывода
(40, 40, 40)
(150, 100, 100)
(75, 91, 110), палитра Звездная ночь
источник
C ++, гамма-коррекция
При этом выполняется регулировка яркости изображения с использованием простой гамма-коррекции, причем значение гаммы определяется отдельно для каждого компонента, чтобы соответствовать целевому среднему значению.
Шаги высокого уровня:
Все изображения ввода / вывода используют файлы PPM в ASCII. Изображения были конвертированы из / в PNG с использованием GIMP. Код был запущен на Mac, преобразование изображений было сделано в Windows.
Код:
Сам код довольно прост. Одна тонкая, но важная деталь заключается в том, что, хотя значения цвета находятся в диапазоне [0, 255], я сопоставляю их с гамма-кривой, как если бы диапазон был [-1, 256]. Это позволяет принудительно усреднить значение до 0 или 255. В противном случае 0 всегда будет оставаться 0, а 255 всегда будет оставаться 255, что никогда не может составлять в среднем 0/255.
Использовать:
.cpp
, напримерforce.cpp
.c++ -o force -O2 force.cpp
../force input.ppm targetR targetG target >output.ppm
.Пример вывода на 40, 40, 40
Обратите внимание, что изображения для всех более крупных выборок включены в формате JPEG, поскольку они превышают предел размера SE в формате PNG. Поскольку JPEG является форматом сжатия с потерями, они могут не совсем соответствовать целевому среднему значению. У меня есть PNG-версия всех файлов, которая точно соответствует.
Пример вывода на 150, 100, 100:
Пример вывода на 75, 91, 110:
источник
Python 2 + PIL
Это повторяет каждый пиксель в случайном порядке и уменьшает расстояние между каждым компонентом цвета пикселя и
255
или0
(в зависимости от того, является ли текущее среднее значение меньшим или большим, чем желаемое среднее значение). Расстояние уменьшается на фиксированный мультипликативный коэффициент. Это повторяется до тех пор, пока не будет получено желаемое среднее значение. Сокращение всегда, по крайней мере1
, если цвет не255
(или0
), чтобы гарантировать, что обработка не останавливается, когда пиксель близок к белому или черному.Образец вывода
(40, 40, 40)
(150, 100, 100)
(75, 91, 110)
источник
Джава
Подход, основанный на ГСЧ. Немного медленно для больших входных изображений.
тесты:
(40,40,40)
(150100100)
(75,91,110)
источник