Есть небольшой кусок картинки, примерно 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];
}
Собственно интересует, есть ли готовые реализации для получение среднего значения превалирующей группы оттенков. Так же интересует более эффективный/точный способ градации цветов, хотя тут я уже и не надеюсь.