Fesor
@Fesor
Full-stack developer (Symfony, Angular)

Получение цвета региона?

Есть небольшой кусок картинки, примерно 50*50 пикселей. В нем некий градиент одного цвета (скажем, желтый, а точнее его различные оттенки. Этот регион является центром некого трехмерного объекта, отсюда градации оттенков)

Существует задача получить цвет объекта в виде строки. Ну тобиш для 255;0;0 должно выдать что это красный.

Оттенков не так много, приблизительно 10 основных (красный, синий, ..., розовый, оранжевый)


В виду небольших сроков задача была решена мною на скорую руку. Из изображения было взято среднее значение цвета (по каждому из каналов) и затем подбирается наиболее близкое значение для заданных «эталонов». Так как объект глянцевый, имеют место блики (как правило белые, или же цвета источника света), что вносит существенную погрешность при определении среднего значения. Думал решить эту проблему отсевом значений, находящихся очень далеко от среднего. Тут уже мозг начал отказывать.


При определении цвета по массиву эталонов так же имеет место существенная погрешность, но тут видно только эксперементальным методом надо подбирать эталоны.


Сама же функция для определения цвета выглядит так:
private string GetColorName(Bgr color)
        {
            string[] names = {
                                "Red",
                                "Blue",
                                "Green",
                                "Black",
                                "Orange",
                                "Yelow",
                                "Pink",
                                "White Or Transparent",
                            };

            Bgr[] colors = {
                               new Bgr(0, 0, 255),
                               new Bgr(255, 0, 0),
                               new Bgr(0, 255, 0),
                               new Bgr(0, 0, 0),
                               new Bgr(55, 160, 245),
                               new Bgr(55, 235, 245),
                               new Bgr(170, 190, 255),
                               new Bgr(255, 205, 175),
                           };

            double minDistance = 0;
            int colorIndex = 0;

            for (int i = 0; i < 8; i++)
            {
                double distance = Math.Pow(color.Red - colors[i].Red, 2) +
                                  Math.Pow(color.Blue - colors[i].Blue, 2) +
                                  Math.Pow(color.Green - colors[i].Green, 2);
                if (i == 0)
                {
                    minDistance = distance;
                    colorIndex = i;
                }
                if (distance < minDistance)
                {
                    colorIndex = i;
                    minDistance = distance;
                }
            }

            return names[colorIndex];


        }



Собственно интересует, есть ли готовые реализации для получение среднего значения превалирующей группы оттенков. Так же интересует более эффективный/точный способ градации цветов, хотя тут я уже и не надеюсь.
  • Вопрос задан
  • 3172 просмотра
Пригласить эксперта
Ответы на вопрос 2
Akson87
@Akson87
Попробуйте рассматривать Вашу задачу как задачу кластеризации. Т.е. есть кучка точек в 3хмерном пространстве, соответствующем RGB и надо найти наибольший кластер, скорее всего он окажется вытянутым весьма, можно его вписать в эллипс и центр эллипса будет нужным цветом.
Еще если известны свойства 3д модели, можно подумать о том, что это поверхность, у нее есть нормали, прикрутить некую модель освещения и попробовать восстановить истинный цвет объекта. Но это так… что в голову приходит первым.
Ответ написан
Комментировать
Eternalko
@Eternalko
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
Wanted. Санкт-Петербург
До 120 000 ₽
Wanted. Санкт-Петербург
от 80 000 до 150 000 ₽
от 60 000 до 120 000 ₽
22 нояб. 2024, в 22:26
3500 руб./за проект
22 нояб. 2024, в 21:47
3000 руб./за проект
22 нояб. 2024, в 21:44
50000 руб./за проект