Получить используемые названия цветов из изображения - PullRequest
4 голосов
/ 05 апреля 2010

Я хотел бы проверить, какие цвета присутствуют на изображении. Это будет храниться в базе данных и использоваться для формы поиска. (красный = 1, зеленый = 1, синий = 0, желтый = 1, черный = 1, белый = 1 и т. д.)

img = Magick::Image.read('phosto-file.jpg').first
img = img.quantize(10
h = img.color_histogram
pp h
{red=12815, green=18494, blue=15439, opacity=0=>13007,
 red=44662, green=47670, blue=51967, opacity=0=>18254,
 red=17608, green=43331, blue=48321, opacity=0=>11597,
 red=21105, green=25865, blue=39467, opacity=0=>10604,
 red=15125, green=36629, blue=22824, opacity=0=>10223,
 red=52102, green=42405, blue=10063, opacity=0=>12928,
 red=39043, green=28726, blue=40855, opacity=0=>7728,
 red=10410, green=8880, blue=7826, opacity=0=>13795,
 red=25484, green=25337, blue=24235, opacity=0=>7351,
 red=44485, green=12617, blue=11169, opacity=0=>14513}

Как мне преобразовать 10 значений в названия цветов? красный, зеленый, NOMATCH, желтый, черный, белый и т. д. Нужно только приблизительное название цвета - не LimeGreen, а зеленый и т. д.

С уважением. Асбьорн Морелл

Ответы [ 3 ]

1 голос
/ 06 апреля 2010

Если бы вы могли представить все цвета, которые вы ищете, в том же числовом формате, который возвращает ImageMagick.Затем вы можете сравнить значения RGB, чтобы определить, к какому из них оно ближе всего.

Так, например, если у вас есть значение гистограммы (при условии 255 значений для каждого цвета, YMMV) * ​​1003 *

{ red => 10, green => 255, blue => 10 }

Тогда вы можете сравнить его с каждым из

{
  red   => {red => 255, green => 0, blue => 0},
  green => {red => 0, green => 255, blue => 0},
  blue  => {red => 0, green => 0, blue => 255}
}

Таким образом, если вы сложите разницу между всеми элементами, вы получите

{
  red   => 510,
  green =>  20,
  blue  => 510,
}

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

ОБНОВЛЕНИЕ: добавлено решениев рубине


def compare_color(color_val)
  colors = {
    :red    => [255,0,0],
    :green  => [0,255,0],
    :blue   => [0,0,255]
  }

  difference = {}

  def compare_array(a1,a2)
    total = 0
    a1.each_index do |x|
      total += (a1[x]-a2[x]).abs
    end
    total
  end

  colors.each do |color,hex|
    difference[color] = compare_array(color_val,hex)
  end

  closest = difference.sort{|a,b| a[1]  b[1]}.first                                                                       [closest,difference]
end

p compare_color([10,255,10])
# [[:green, 20], {:red=>510, :green=>20, :blue=>510}]
1 голос
/ 04 октября 2010

Вы можете найти этот пост в моем блоге интересным. Это объясняет, как именно решить вашу проблему. Я также выпустил ColorNamer gem , который дает вам ближайший названный цвет из значения RGB или HTML-хэша. Вы также можете использовать любой Цвет объект

1 голос
/ 05 апреля 2010

Простым способом было бы иметь список значений RGB и соответствующих им имен, и вы бы выбрали наиболее близкий соответствующий цвет (с некоторым допустимым пределом погрешности). Только для основных цветов, даже очень простая сумма различий в каждом из каналов RGB может дать работоспособные результаты, хотя я подозреваю, что у вас не останется названий цветов, если данные выглядят так. Вы можете найти список имен цветов в сети, возможно, сокращение одного такого списка может помочь. (Обратите внимание, что для цветов обычно требуется диапазон 0,2555, поэтому вам придется конвертировать данные в более широкий диапазон.)

Несколько более продвинутый способ - преобразовать значения RGB в оттенки, насыщенность и яркость и использовать их для генерации имен, например, «темно-красный», когда оттенок красный, насыщенность достаточно высокая, чтобы не быть серым, а яркость низкая (но недостаточно низкая, чтобы быть черным).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...