Одним из довольно хороших решений является переключение с цветового пространства RGB на одно из цветовых пространств Y, такое как YUV, YCrCb или любое из них. Во всех случаях канал Y представляет яркость, а два других канала вместе представляют цвет относительно яркости. Вы, вероятно, хотите уменьшить яркость, возможно, с учетом того, что все цвета ниже определенной темноты должны быть исключены, поэтому получение Y отдельно - это первый полезный шаг сам по себе.
Преобразование из RGB в YUV достигается с помощью простой линейной комбинации. Прямо из Википедии и тысячи других источников:
y = 0.299*r + 0.587*g + 0.114*b;
u = -0.14713*r - 0.28886*g + 0.436*b;
v = 0.615*r - 0.51499*g - 0.10001*b;
Предполагая, что вы держите r, g и b в диапазоне [0, 1], ваш первый тест может быть:
if(y < 0.05)
{
// this colour is very dark, so it's considered to be as
// far as we allow from any colour we're interested in
}
Чтобы решить, насколько близок ваш цвет, скажем, к зеленому, определите компоненты u и v зеленого, которые вас интересуют, в пропорции от y:
r = b = 0;
g = 0;
y = 0.299*r + 0.587*g + 0.114*b = 0.587;
u = -0.14713*r - 0.28886*g + 0.436*b = -0.28886;
v = 0.615*r - 0.51499*g - 0.10001*b = -0.51499;
proportionOfU = u / y = -2.0479;
proportionOfV = v / y = -0.8773;
Впоследствии отработайте и сравните пропорции U и V для входящих цветов и сравните (например, с 2d планарным расстоянием) с теми, которые вы вычислили для цвета, с которым вы сравниваете. Более близкие значения более похожи. То, как вы масштабируете и используете этот показатель, зависит от вашего приложения.
Обратите внимание, что по мере приближения y к 0 вычисленные пропорции становятся все менее точными из-за ограниченного диапазона входных данных и не определены, когда y равно 0. Концептуально это происходит потому, что все цвета выглядят одинаково, когда нет света их. Проверка того, что y выше хотя бы определенного минимального значения, является прагматичным способом решения этой проблемы. Это также означает, что вы не получите ощутимых результатов, если попытаетесь сказать «насколько черный этот рисунок?», Хотя опять-таки из-за неоднозначности между поверхностью, которая не отражает свет, и поверхностью, которая не ' на него не падает свет.