Разделите изображение экрана на сетку из r-многих прямоугольников в n на m «сетке», каждый из которых имеет ширину (общая ширина / n) и высоту (общая высота / м).
1a. Присвойте вес громким областям экрана, таким как область слева от центра.
1b. Для каждого прямоугольника назначьте пиксели в пространство ( цвет , частота )
Для каждого прямоугольника R, распределение частоты f_R и вес W_R:
2a. Определите i -й цвет схемы (например, i = 1 <-> цвет фона) путем сканирования «верхней частоты», «второй частоты» ( то есть f_R [] я,:]) для каждого блока.
2b. Для каждого i , поместите его в таблицу результатов ( color_i , оценка ), где оценка = f_R [ i , "частота" ] * W_R
2в. Лучшим бомбардиром для каждого i будет i -й цвет схемы.
Теоретически, если у вас много "синий на белом" или "красный на черном", вы должны получить белый основной, синий вторичный или черный основной, например, красный вторичный.
Для вашего цвета текста, либо основывайте его непосредственно на расчете по цвету фона, либо выбирайте вторичный цвет, и, если V-разница HSV слишком мала, основывайте цвет на цвете вычисленной схемы, но увеличивайте V значение.
псевдокод:
float[][] weights =
{ { 1.0, 3.0, 5.0, 5.0, 3.0, 1.0, 1.0, 1.0, 1.0 },
{ 2.0, 6.0, 7.0, 7.0, 6.0, 2.0, 3.0, 3.0, 2.0 },
{ 2.0, 8.0, 9.0, 9.0, 7.0, 3.0, 6.0, 6.0, 3.0 },
{ 2.0, 8.0, 9.0, 9.0, 7.0, 2.0, 3.0, 3.0, 2.0 },
{ 2.0, 7.0, 9.0, 9.0, 7.0, 2.0, 1.0, 1.0, 1.0 },
{ 2.0, 6.0, 7.0, 7.0, 6.0, 2.0, 3.0, 3.0, 1.0 },
{ 1.0, 3.0, 5.0, 5.0, 3.0, 2.0, 6.0, 6.0, 2.0 },
{ 1.0, 1.0, 2.0, 2.0, 1.0, 2.0, 6.0, 6.0, 2.0 },
{ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 3.0, 3.0, 1.0 } };
// Leave the following implementations to the imagination:
void DivideImageIntoRegions( Image originalImage, out Image[][] regions );
void GetNthMostCommonColorInRegion( Image region, int n, out Color color );
TKey FindMaximum<TKey, TValue>( Map<TKey, TValue> map );
// The method:
Color[] GetPrimaryScheme( Image image, int ncolors, int M = 9, int N = 9 )
{
Color[] scheme = new Color[ncolors];
Image[][] regions = new Image[M][N];
DivideImageIntoRegions( image, regions );
for( int i = 0; i < ncolors; i++ )
{
Map<Color, float> colorScores = new Map<Color, float>();
for( int m = 0; m < M; m++ )
for( int n = 0; n < N; n++ )
{
Color theColor;
GetNthMostCommonColorInRegion( region, i, theColor );
if( colorScores[theColor] == null )
{ colorScores[theColor] = 0; }
colorScores[theColor] += weights[m][n];
}
scheme[i] = FindMaximum( colorScores );
}
return scheme;
}
Глядя на вышесказанное, становится ясно, что если есть область с небольшой изменчивостью, она будет иметь тот же самый второй по распространенности цвет, что и наиболее распространенный цвет. Чтобы настроить, второй самый распространенный цвет в таком случае может быть нулевым, против которого можно защититься:
if( theColor != null )
continue;
if( colorScores[theColor] == null )
{ colorScores[theColor] = 0; }
colorScores[theColor] += weights[m][n];
}