Как определить количество цветов в изображении, как это делает Google? - PullRequest
0 голосов
/ 02 мая 2019

Я искал это в течение долгого времени, и я хочу знать, есть ли у кого-нибудь из вас какой-либо ресурс или знание какого-то алгоритма, который может сделать изображение и вернуть процент наиболее значимых цветов вобраз.Но не любого цвета, я хочу, чтобы проценты соответствовали предопределенной постоянной палитре из 12 цветов (то же самое, что вы используете для поиска изображений в Google для сортировки).

Однако созданный мной скрипт работает в том смысле,что он получает цвета, которые являются НАСТОЯЩИМ, но не обязательно наиболее значительными.

Sample image

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

Пример: красный = 1%, желтый = 3% и черный = 96% (не точные значения, но точные).

Проблема заключается в том, что, хотя их количество не самое большое,они явно являются ОСНОВНЫМИ цветами на изображении относительно того, как их видит человеческий глаз.Есть ли алгоритм для этого или техника?Спасибо за чтение.

1 Ответ

0 голосов
/ 02 мая 2019

Допустим, ваше изображение имеет разрешение WxH.

Вы говорите, что у вас есть палитра из 12 цветов.

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

  • Глобальный счетчик Счетчик допустимых цветов в изображении;
  • массив частот с длиной, равной размеру палитры;
  • массив цветов, представляющих палитру .

Возможный алгоритм может быть:

for(int i = 0; i < W; i++){
    for(int j = 0; j < H; j++){
        Color dif = new Color(255, 255, 255, 1);
        Color currDif;
        int minIndex = -1;
        for(int k = 0; k < palette.length; k++){
            currDif = palette[k] - image[i][j];
            if(dif > currDif){
                dif = currDif;
                minIndex = k;
            }
        }
        if( CloseEnough(dif, palette[minIndex]) ){
            frequency[minIndex]++;
            counter++;
        }
    }
}

Затем, чтобы проверить проценты, можно просто:

for(int i = 0; i < 12; i++){
    print("Color i appears (Palette[i] / counter) %");
}  

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

Функции CloseEnough и < по вашему выбору, но они могут работать следующим образом:

bool CloseEnough(Color c1, Color c2){
    return abs(c1.r - c2.r) < 30 && abs(c1.g - c2.g) < 30 && abs(c1.b - c2.b) < 30;
    //note that 30 can be quite small
    //this value can be modified based on testing and result quality
}

//the closer to black a color is, the smaller it will be
bool < (Color c1, Color c2){
    return (c1.r + c1.g + c1.b) < (c2.r + c2.b + c2.g);
}

Возможно, есть лучшие решенияТ, но надеюсь, что это поможет.

...