Алгоритм последовательной доставки цветов с максимальной контрастностью - PullRequest
0 голосов
/ 26 октября 2019

Мне нужно создать цвета, чтобы использовать их для выделения типов контента. В одном документе может быть несколько десятков цветовых оттенков.

Мой пример использования - я хочу сообщить ученым о том, как данные были извлечены из входного документа. Подсказки с цветовой кодировкой фона (с описательными) будут использоваться для выделения импортированных блоков. Вот фиктивный входной файл: raw input file

А вот фиктивная версия того, как он будет выглядеть после выделения, чтобы указать, какие поля были импортированы. Всплывающая подсказка о каждом выделенном блоке даст дополнительную информацию об инструменте, который его распознал, плюс значение (с единицами измерения), которое было передано в базу данных: marked up input file

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

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

Для каждого последующего цвета алгоритм должен будет искать наибольшую «незанятую» дугу на цветовом колесе и генерироватьцвет в средней его точке.

Похоже ли это на любую существующую стратегию генерации цвета?

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

(Моя целевая среда - Python, но это просто детали реализации)

Ответы [ 2 ]

1 голос
/ 28 октября 2019

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

Простой и удивительно хороший показатель для использования - среднее значениекрасный :

formula

formula

formula

formula

formula

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

Вот пример реализации в python:

import numpy as np
from itertools import combinations
from scipy.optimize import minimize, Bounds

BLACK_AND_WHITE = np.array((0.0, 0.0, 0.0, 255.0, 255.0, 255.0))

мы рассматриваем три последовательных числа в массиве как представляющие цвет, заданные двумя такими триплетами, и используя расстояние, как определеновыше, наша функция расстояния -

def distance(c1, c2):
    r = (c1[0] + c2[0]) / 2.0
    coeffs = np.array(((2.0 + r/256), 4, (2.0 + (255 - r)/256.0)))
    diff = c1 - c2
    return np.sqrt(np.sum(coeffs * diff ** 2))

Мы хотим максимизировать минимальное расстояние между всеми парами цветов, что аналогично минимизации отрицательного минимального расстояния. Чтобы получить пары, мы используем combinations(..., 2), который делает именно это, и чтобы сделать итерацию по триплетам, мы изменяем массив цветов так, чтобы каждая строка содержала цвет:

def cost_function(x):
    colors = np.concatenate((BLACK_AND_WHITE, x)).reshape(-1, 3)
    return -min(mean_red_distance(color_pairs[0], color_pairs[1]) for color_pairs in combinations(colors, 2))

Теперь пришло времясворачивая нашу функцию стоимости, цвета могут варьироваться от 0 до 255:

def get_new_colors_after_adding(existing_colors):
    if len(existing_colors):
        guess = np.mod(existing_colors.reshape(-1, 3)[0] + np.array((100, 100, 100)), 256)
    else:
        guess = np.array((0, 255, 255))
    guess = np.concatenate((guess, existing_colors))
    # let all colors range between 0 and 255
    result = minimize(cost_function, guess, bounds=Bounds(0, 255))
    if not result.success:
        raise ValueError('Failed adding new color')
    return result.x

И, наконец, мы добавляем 10 цветов на каждом шаге и печатаем получившиеся триплеты:

if __name__ == '__main__':
    # start with no colors
    existing_colors = np.empty(0, dtype=np.int32)
    # example of consequently adding colors.
    for i in range(10):
        existing_colors = get_new_colors_after_adding(existing_colors)
        print(np.round(existing_colors.reshape(-1, 3)).astype(np.int))
0 голосов
/ 28 октября 2019

Ааа, я подумал об альтернативной стратегии для этой проблемы.

Вместо создания цветов на лету, цветовое кодирование может быть отложено до конца процесса.

Как только мы узнаем, сколько цветов требуется, мы можем сгенерировать такое количество перестановок, равномерно распределенных по оттенкам в цветовом спектре HSB / HSV. Я думаю, это обеспечило бы наибольшую контрастность.

...