Палитра Android не выбирает преобладающие цвета

У меня есть следующие изображения:

введите здесь описание изображения введите здесь описание изображения введите здесь описание изображения

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

 public static int getPredominantColorFromPokemon(String pokemonId, Context context) {
    int pokemonImage = PokemonUtils.getPokemonSugimoriImageById(pokemonId, context);
    if (pokemonImage == 0) {
        return Color.WHITE;
    }
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), pokemonImage);
    Palette palette = Palette.from(bitmap).generate();
    int colorPalette1 = palette.getLightVibrantColor(Color.WHITE);
    int colorPalette2 = colorPalette1 == -1 ? palette.getVibrantColor(Color.WHITE) : colorPalette1;//Fallback
    int colorPalette3 = colorPalette2 == -1 ? palette.getLightMutedColor(Color.WHITE) : colorPalette2; //Fallback
    int colorPalette4 = colorPalette3 == -1 ? palette.getDominantColor(Color.WHITE) : colorPalette3;//Fallback
    return colorPalette4;
}

Цвета результата этих 3 изображений следующие:

Однако это не то, что я ищу, мой желаемый результат будет таким:

введите здесь описание изображения

Результаты первого и второго изображения в порядке, фон зеленый, потому что преобладает зеленый цвет, но в случае с третьим изображением (Венузавр) это не так, потому что результат имеет розовый/фиолетовый цвет, и я хочу, чтобы Палитра для обнаружения зеленого вместо этого. Как я могу изменить свой метод, чтобы определить ПРЕИМУЩЕСТВЕННЫЕ цвета?


person Nexussim Lements    schedule 28.07.2020    source источник
comment
Я думаю, что в этой ситуации розовый является доминирующим цветом, так как тело имеет 2 оттенка зеленого. Поэтому я считаю, что на изображении больше розовых пикселей, чем любого другого цвета.   -  person Razvan S.    schedule 28.07.2020


Ответы (1)


Цвета очень субъективны, и не всегда можно однозначно решить, какой цвет является доминирующим. Ключевыми факторами являются люминофор и гистограмма. Очевидно, реализация Google считает, что розовый цвет важнее синего. Это даже понятно, поскольку красный/оранжевый/желтый – это сигнальные цвета, которые воспринимаются человеческим глазом более важными (независимо от их количества на изображении).

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

Короче говоря: если вы хотите использовать Palette API, вам придется иметь дело с результатом, который он вам дает.

Но поскольку Palette API предлагает несколько извлеченных цветов, вы можете сравнить их оттенок с гистограммой изображения и соответственно выбрать свой любимый цвет палитры.

Вот пример того, как преобразовать цвет из RGB в HSV и обратно.

  • H = оттенок = основной тип цвета, с которым вы имеете дело (красный, зеленый, оранжевый и т. д.)
  • S = Насыщенность (Насколько интенсивен оттенок. Насыщенный красный или светло-красный)
  • V = Значение (Насколько яркий оттенок. От полностью темного до полностью яркого)
int color = Color.rgb(206, 43, 55);

int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
System.out.println(red + ", " + green + ", " + blue);
//prints: 206, 43, 55 (as expected)

float[] hsv = new float[3];
Color.RGBToHSV(red, green, blue, hsv);

float hue = hsv[0];
float sat = hsv[1];
float val = hsv[2];

int outputColor = Color.HSVToColor(hsv);
red = Color.red(outputColor);
green = Color.green(outputColor);
blue = Color.blue(outputColor);
System.out.println(red + ", " + green + ", " + blue);

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

Это то, где вы не найдете 1 идеального решения. Вместо этого вам, возможно, придется найти компромисс между поддерживаемым кодом, скоростью и требованиями приложения.

Удачи!

person muetzenflo    schedule 28.07.2020
comment
Не могли бы вы привести пример сравнения Hue с Historgram, пожалуйста? - person Nexussim Lements; 28.07.2020
comment
Я отредактировал свой ответ и добавил немного больше информации. - person muetzenflo; 28.07.2020