Как определить, является ли цвет зеленым?

Какова формула для определения того, является ли код RGB зеленым? Вот попытка:

public boolean isGreen(Color color){
        return (color.getGreen() > 0.8*(color.getBlue()) && color.getBlue() > color.getRed());
    }

То есть вернуть true, если значение зеленого цвета rgb значительно больше синего, а синего больше красного. Была проведена проверка его точности.

Методы: программа JavaFX генерировала 132 шара каждые 6 секунд, каждый со значением rgba (альфа в данном случае не имеет значения)

(Math.random(), Math.random(), Math.random(), Math.random())

Программа напечатала результат isGreen(randomColor()).

Затем автор подсчитал результаты в одном из четырех квадрантов:

  1. isGreen() возвращает true, но цвет воспринимается не зеленым
  2. isGreen() возвращает true, и цвет воспринимается зеленым.
  3. isGreen() возвращает false, но цвет воспринимается зеленым.
  4. isGreen() возвращает false, и цвет воспринимается не зеленым.

Он удовлетворительно предсказывал, если цвет не был зеленым: 72/99 правильно, или 73%. Этого достаточно; кроме того, для программы более важно, если она ошибочно предсказывает цвет как зеленый, а не неправильно отбрасывает зеленый цвет.

Напротив, он не может предсказать, является ли цвет зеленым. Он правильно предсказал 13/31, или 42%. Это ключевая часть, и она не работает. Неудовлетворительно иметь 58% ложных срабатываний.

Буду признателен за точную формулу!

Вот диаграмма, поясняющая текущие результаты: введите здесь описание изображения


person Cole Henrich    schedule 11.02.2021    source источник
comment
Я бы сказал, что если число g значительно выше, чем r и b, вероятность того, что цвет будет зеленым, выше. Просто мое предположение, я не знаю, верно ли это для большинства случаев.   -  person Sedrick    schedule 12.02.2021
comment
Это больше похоже на проблему статистического обучения. Если вы разделите цвета на те, которые субъективно зеленые и не зеленые, вы можете запустить что-то вроде алгоритма машины опорных векторов (или, возможно, дерево регрессии, хотя я немного не в своей области здесь). Обратите внимание, что это определение действительно субъективно; разные люди будут воспринимать цвета по-разному.   -  person James_D    schedule 12.02.2021
comment
Также обратите внимание, что color.getGreen() > 0.8 * color.getBlue() на самом деле не проверяет, значительно ли «зеленое значение rgb больше, чем синее». Например, если синий равен 0,5, а зеленый — 0,45, это будет верно. Вы хотели умножить зеленый цвет на 0,8?   -  person James_D    schedule 12.02.2021
comment
@James_D Спасибо, да, это только что стало очевидно! В этом была вся проблема.   -  person Cole Henrich    schedule 12.02.2021


Ответы (1)


Вопрос решен!

Это была простая математическая ошибка в методе:

public boolean isGreen(Color color){
        return (color.getGreen() > 0.8*(color.getBlue()) && color.getBlue() > color.getRed());
    }

color.getGreen() > 0.8*(color.getBlue() на самом деле может допустить, что синего будет больше, чем зеленого, и при этом color.getBlue() > color.getRed() может допустить, что красного будет больше, чем зеленого, в результате чего иногда получится фиолетовый.

Правильный способ сделать это

public boolean isGreen(Color color){
        return ((color.getBlue() < 0.8*color.getGreen()) 
        && (color.getRed() < .64 * color.getGreen()));
    }

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

person Cole Henrich    schedule 11.02.2021
comment
Обратите внимание, что rgb, скажем, (0, 0.001, 0.0001), который в основном черный, по этому определению будет зеленым. - person James_D; 12.02.2021