Определите, какой цвет (красный, синий, зеленый или другой) будет видимым для данной комбинации значений RGB? - PullRequest
3 голосов
/ 22 января 2020

Так что в основном мне нужен метод, в котором я могу передавать значения красного, зеленого и синего, и метод должен возвращать, приведет ли эта комбинация значений RGB к явно Red-i sh цвету Green-i sh цвет или синий-я sh цвет. И если комбинация не приводит ни к одному из этих трех цветов, она должна вернуть false.

Я пытался сделать это, используя условные выражения, пробовал несколько вариантов, но ничего не было точным.

Например, я пытался:

if (B > 100 && B > G / 2 && B > R / 2)
{
    blueCount++;
}
else if (G > 100 && G > G / 2 && G > B / 2)
{
    greenCount++;
}
else if (R > 100 && R > G / 2 && R > B / 2)
{
    redCount++;
}

// R , G , B contains 0-255 values 

Ответы [ 3 ]

3 голосов
/ 22 января 2020

Если вы определяете «будучи цветом-я sh» как:

  • значение цвета выше 100
  • значение цвета по крайней мере дважды как 2 других значения
    • ваш текущий код заявляет " как минимум половина из 2 других значений ", но это не может работать, потому что если у вас есть " R: 199 G: 101 B: 102", вы могли бы сказать, что это green-i sh, потому что G выше 100 и больше, чем половина 199 и половина 102 (когда это очевидно red-i sh)

, тогда ваш код выглядит почти хорошо (просто замените / на *).

Я бы просто использовал enum для результата:

enum Ish
{
    Other, // 0 so this would be false if you convert it to bool
    Red,   // 1
    Green, // 2
    Blue   // 3
}
if (R>100 && R>G*2 && R>B*2)
    return Ish.Red;
if (G>100 && G>R*2 && G>B*2) // you had G>G/2 here /!\
    return Ish.Green;
if (B>100 && B>G*2 && B>R*2)
    return Ish.Blue;
return Ish.Other;

Я использовал 2 дважды, но я думаю, что вы можете использовать другие значения, пока оно >1 ( Вы не можете сказать, что синий цвет является доминирующим , если, например, B <= R)

Это будут значения redi sh, возможные для R = 100 (левое изображение с коэффициентом 2, правое изображение с фактором 1):

Red-ish 100 fact 2 Red-ish 100 fact 1* 10 47 *

И это для R = 200 (левое изображение с фактором 2, правое изображение с фактором 1):

Red-ish 200 fact 2 Red-ish 200 fact 1

Поэтому вы, вероятно, можете использовать коэффициент от 1 до 2

. Для R = 200 вы можете видеть цвета red-i sh в зависимости от коэффициента ниже:

Red-ish 200 multifactor

3 голосов
/ 22 января 2020

Я предлагаю использовать другое цветовое пространство : HSV или HSL вместо RGB.

Теперь, чтобы объявить color являющимся greeni sh Вы должны проверить

  1. Если color имеет H (Hue) в некотором диапазоне (Green оттенок доминирует поверх других цветов)
  2. Если color имеет S (Saturation) выше некоторого порога , чтобы не быть слишком бесцветным (серый sh)
  3. Если color имеет V или L (Value или Luminocity) выше некоторого порога , чтобы не быть слишком темным (блэки sh)

https://vignette.wikia.nocookie.net/psychology/images/e/e0/HSV_cylinder.png/revision/latest?cb=20071105130143

2 голосов
/ 22 января 2020

Не пытайтесь изо всех сил найти совершенно точный ответ на этот вопрос. В конце концов, нет такой вещи, как идеально определенная линия между red-i sh и не red-i sh.

. Способ, которым я хотел бы подойти к этому: во-первых, проверьте, что цвет не слишком серый / черный. Это может быть сделано с использованием суммы трех компонентов (имейте в виду, что полный черный цвет равен 0; 0; 0 для RGB, оттенки серого обычно равны 55; 55; 55). Например, вы можете считать слишком темным любой цвет, составляющие которого составляют менее 300. Поиграйте немного с любым инструментом выбора RGB, чтобы найти порог, который вам нравится больше всего.

РЕДАКТИРОВАТЬ: из комментария ниже я вижу сумма трех компонентов не будет работать, например, 255; 0; 0 будет считаться слишком серым. Таким образом, вы должны использовать максимальное значение из трех компонентов. Например, 20; 0; 0 все равно будет довольно темным, но 100; 0; 0 не так уж много. Спасибо @rafalon за указание на это.

Затем вам нужно проверить, что этот цвет близок к «чистому» цвету, то есть красному, зеленому или синему. Чтобы сделать это, вам нужно сравнить наиболее заметный компонент с двумя другими. Вы должны сравнить этот самый высокий компонент с двумя другими, индивидуально. Это связано с тем, что цвет, такой как 255; 0; 255, вообще не равен sh, тогда как 255; 128; 128 можно считать таковым. Таким образом, комбинация двух менее заметных компонентов не сработает.

Вы можете считать цвет красным-i sh, если зеленый и синий имеют значение ниже некоторого процента красного. Возьмем для примера этот процент 50%. Затем вам нужно убедиться, что зеленый меньше 0,5 * красного, а синий меньше 0,5 * красного. Опять же, вам следует немного поиграть с цветами RGB, чтобы найти процент, который, по вашему мнению, подходит.

TL; DR: для цвета с компонентами r, g и b этот цвет будет "чистым" цветом если:

  1. Макс. (r, g, b)> tooDarkValue

  2. r> somePercentage * Макс. (r, g, b) И g > somePercentage * Max (r, g, b) И b> somePercentage * Max (r, g, b)

Обратите внимание, что второе условие всегда будет истинным для Max (r, g , б), (любое число больше, чем процент от самого себя), поэтому нет необходимости оценивать, какой компонент является самым высоким, а затем иметь 3 различных условия

...