Подтвердить что ты не робот

Учитывая значение RGB, какой был бы лучший способ найти ближайшее соответствие в базе данных?

У меня есть значение rgb, и если он не существует в таблице цветов в моей базе данных, мне нужно найти ближайший цвет. Я думал сравнить все значения и найти разницу (в красном, зеленом и синем), а затем взять среднее значение. Наименьшее среднее отклонение должно быть самым близким цветом. Мне кажется, что должен быть лучший способ. Любые идеи?

4b9b3361

Ответ 1

Рассмотрим цвет как вектор в трехмерном пространстве, тогда вы можете легко вычислить разницу с помощью 3d pythagoras:

d = sqrt((r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2)

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

Например, используя типичный взвешенный подход:

d = sqrt(((r2-r1)*0.3)^2 + ((g2-g1)*0.59)^2 + ((b2-b1)*0.11)^2)

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

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

d =   ((r2-r1)*0.30)^2
    + ((g2-g1)*0.59)^2
    + ((b2-b1)*0.11)^2

Обратите внимание, что во многих языках программирования на основе синтаксиса (например, С#) ^ не означает "повышение до степени", а скорее "двоичное исключение" или "

Итак, если это был С#, вы бы использовали Math.Pow для вычисления этой части или просто расширения и выполнения умножения.

Добавлено. Судя по странице Разница цветов в Википедии, существуют различные стандарты, которые пытаются обрабатывать различия восприятия, Например, тот, который называется CIE94, использует другую формулу в цветовой модели L*C*h, которая выглядит так, как будто она стоит посмотреть, но она зависит от того, насколько точна вы хотите.

Ответ 2

Следующее делает именно то, что вы описываете:

select (abs(my_R - t.r) + abs(my_G - t.g) + abs(my_B - t.b)) / 3 as difference, t.*
from RGBtable t
order by difference desc;

Однако вы можете получить лучшие результаты с чем-то, что было нелинейным. В подходе "взять средние", если цвет цели (25, 25, 25), цвет (45, 25, 25) будет ближе, чем (35, 35, 35). Тем не менее, я уверен, второй будет выглядеть по-другому, так как он также будет серым.

Несколько идей приходят вам на ум: вы можете попытаться возвести в квадрат различия до того, как вы их усредняете. Или вы можете сделать что-то сложное с поиском цвета с самым близким соотношением между разными значениями. Поиск ближайших отношений приблизит вас к правильному оттенку, но не учитывает насыщенность (если я правильно помню условия...)

Ответ 3

Евклидово расстояние difference = sqrt(sqr(red1 - red2) + sqr(green1 - green2) + sqr(blue1 - blue2)) - это стандартный способ, чтобы определить сходство двух цветов.

Однако, если у вас есть ваши цвета в простом списке, то для поиска ближайшего цвета требуется вычислить расстояние от нового цвета с каждым цветом в списке. Это операция O (n).

sqrt() - дорогостоящая операция, и если вы просто сравниваете два расстояния, вы можете просто опустить sqrt().

Если у вас очень большая палитра цветов, возможно, быстрее организовать цвета в kd tree (или один из альтернативы), чтобы уменьшить количество различий, требующих вычислений.

Ответ 4

Пусть база данных сделает это за вас:

select top 1
  c.r,
  c.b,
  c.g
from
  color c
order by
  (square(c.r - @r) + square(c.g - @g) + square(c.b - @b))

Где @r, @g и @b - значения r, g, b цвета, который вы ищете (синтаксис параметра SQL Server, поскольку вы не указали базу данных). Обратите внимание, что это все равно придется выполнять сканирование таблицы, так как order by имеет в нем вызов функции.

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

Ответ 5

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

difference = sqrt((red1 - red2)^2 + (green1 - green2)^2 + (blue1 - blue2)^2)

Ответ 6

На один шаг лучше среднего ближайший квадратный корень:

((delta red)^2 + (delta green)^2 + (delta blue)^2)^0.5

Это минимизирует расстояние в трехмерном цветовом пространстве.

Так как корень строго возрастает, вы можете искать максимум квадрата. Как вы выражаете это в SQL, зависит от того, какие RDBMS вы используете.

Ответ 7

Рассчитайте как среднее, так и расстояние следующим образом:

(r + g + b) / 3 = average
(r - average) + (g - average) + (b - average) = distance

Это должно дать вам хорошее представление о ближайшем значении.