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

Я думаю, что если размер пустого класса равен нулю, это означает, что он не существует. Чтобы он (класс) существовал, он должен иметь не менее 1 байт, так как этот байт является адресом памяти / ссылки.

23
задан Mike 4 December 2009 в 13:55
поделиться

7 ответов

Рассмотрите цвет как вектор в трехмерном пространстве, затем вы можете легко вычислить разницу, используя трехмерные пифагоры:

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

Обратите внимание, что во многих языках программирования, основанных на C-синтаксисе (например, C #), ^ означает не «возвести в степень», а скорее «двоичный исключающее или ".

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

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

^ не означает «возвести в степень», а скорее «двоичное исключающее ИЛИ».

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

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

^ не означает «возвести в степень», а скорее «двоичное исключающее ИЛИ».

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

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

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

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

69
ответ дан 28 November 2019 в 17:57
поделиться

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

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
ответ дан 28 November 2019 в 17:57
поделиться

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

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

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

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

3
ответ дан 28 November 2019 в 17:57
поделиться

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

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, поскольку вы не указали базу данных). Обратите внимание, что для этого по-прежнему потребуется сканирование таблицы, поскольку порядок по содержит вызов функции.

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

2
ответ дан 28 November 2019 в 17:57
поделиться

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

difference = sqrt((red1 - red2)^2 + (green1 - green2)^2 + (blue1 - blue2)^2)
1
ответ дан 28 November 2019 в 17:57
поделиться

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

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

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

Поскольку корень строго увеличивается, вы можете искать максимум из квадрат вместо этого. То, как вы выразите это в SQL, будет зависеть от того, какую СУБД вы используете.

1
ответ дан 28 November 2019 в 17:57
поделиться

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

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

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

0
ответ дан 28 November 2019 в 17:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: