Comments 17
Странно что в примерах сравниваются настройки simple и sqrt с усреднением цветов в lab. Lab для этого не подходит, лучше бы показали сравнение настоящим линейным усреднением.
Цель у всех этих рамок создать environment, как бы свет идущий с вне поля чёткого зрения, но из той же среды.
По этому усредняться цвет должен так же как это произошло бы в реальном оптическом эксперименте, то есть линейно.
Lab же пытались сделать идеально соответствующим человеческим ощущениям от цвета. Он не линеен, не могу точно сказать за эволюцию, но наверное он лучше подходит для классификации объектов и устранении влияния освещения, и это совсем противоположная задача.
Так, например, сравним гамму: у линейного света — 1, у SRGB ≈ 2.2, у Lab — 3. И в первом примере, где смешиваются черный и белый, это видно: у Lab получается даже более тёмный цвет, чем у SRGB. Далее, при смешивании синего и жёлтого у Lab получается розовый.
Есть разница между "средним цветом" и "цветом, встречающимся наиболее часто" — так же, как и между медианой, средним и модой: https://www.purplemath.com/modules/meanmode.htm
В вашем алгоритме используется среднее значение. Но, как и написано в указанной мною статье, среднее значение может даже и не появляться в выборке:
data = [ 13, 13, 13, 13, 14, 14, 16, 18, 21 ]
mean(data) = 15
mode(data) = 13
Поэтому у вас на примерах небо темнее полоски на фоне, а на картинке с листиками фоном вообще болотный цвет.
Я понимаю, для разных задач — разные решения, и в некоторых случаях подобное решение может быть оправдано затратами времени. Но тем не более, может стоит попробовать и немного другой подход?
Вот несколько интересных идей:
1. Минимальное расстояние (сумма расстояний) по цвету до каждого пиксела картинки. Высчитываем цветовое расстояние (например, как квадратный корень из суммы квадратов H, S, L) для пиксела, суммируем его, минимизируем, получаем «самый близкий ко всем». Для разноцветья — серый, для фотографий с общим цветом (например, синеватых) — усреднённо синеватый.
2. Минимизируем расстояние в пятимерном пространстве, где три кординаты — HSL, а ещё две — расстояние на картинке. Таким образом, чем дальше пиксел от рамочки, тем меньше он влияет на её цвет.
Можно придумать кучу вариантов. Уход в градиентики и прочие «нарисовать рамочку» уже не так интересно.
На хабре есть статья про premultiplied alpha — https://habr.com/post/328386/
Поскольку это производные от изображения данные, их можно рассчитать заранее (Каким-нибудь ImageMagick, например) и передавать уже готовые рядом с картинкой. Онлайн-рассчёт это хорошо, но пользователи устройств с питанием от аккумулятора, возможно, будут недовольны раходом батареи :(
Средний цвет в JavaScript