Создание системы поиска изображений на основе цвета на Ruby

Опубликовано: 2022-03-11

Говорят, что картинка стоит тысячи слов. И во многом слова на картинках — это цвета. Цвета являются неотъемлемой частью нашей жизни, и мы не можем отрицать их важность.

Глядя на изображение, мы часто пытались определить цвет его части. Мы все пытались сделать это, но никогда не делали этого в деталях. Когда нас просят идентифицировать цвета на изображении, мы обычно обозначаем их конкретными названиями цветов, такими как красный, синий и зеленый. Однако, если нас попросят выделить 30 наиболее ярких цветов изображения, наш глаз не сможет обнаружить или идентифицировать их так же легко. Camalian все об этом. Это поможет вам извлечь цвета из изображений, а затем поиграть с ними.

Camalian: Палитра цветов Ultiamte для Ruby

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

Цвета Космос

Прежде чем мы начнем, давайте сначала разберемся с некоторыми основными понятиями о цветах. Изображения, представленные на наших экранах, представлены с использованием двумерного массива пикселей. Хотя файлы изображений могут быть закодированы по-разному, грубое представление после распаковки и декодирования данных будет одинаковым. В этом представлении на основе двумерного массива каждый пиксель цветного изображения имеет три компонента: красный, зеленый и синий. Хотя изображения, напечатанные на бумаге, также представляют собой двухмерную поверхность точек, сами точки обычно представляют собой смесь четырех компонентов чернил: голубого, пурпурного, желтого и черного. Эти среди некоторых других различных методов, используемых для представления цветов, называются цветовыми пространствами. Одними из наиболее часто используемых цветовых пространств являются RGB, CMYK, HSL и HSV. CMYK в основном используется в полиграфии, а все остальные используются в цифровых носителях.

Цветовое пространство RGB

Любые физические электронные носители, такие как ЭЛТ-экраны, ЖК-дисплеи или телефоны, передающие свет, воспроизводят цвет, используя три компонента: красный, зеленый и синий. Человеческий глаз может распознавать миллионы цветов, стимулируя три типа цветовых рецепторов в глазу. Вы можете связать эти рецепторы с R, G и B.

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

Цветовое пространство HSL и HSV

Организация цветового пространства RGB на кубе довольно сложна. Попытки изобразить это на кубе или цветовом круге дают плохие результаты. При работе с миллионами цветов каждый оттенок цвета не может быть правильно выровнен в цветовом пространстве RGB.

рубиновый поисковик картинок

Чтобы преодолеть эту проблему, в 1970-х годах исследователи представили цветовые пространства HSV (оттенок, насыщенность, яркость) и HSL (оттенок, насыщенность, яркость). Оба этих цветовых пространства можно правильно выровнять на цветовом круге и упростить определение на нем различных оттенков цвета.

Рубиновый драгоценный камень для цветов

Camalian - это все о цветах. Одна из самых простых вещей, которые вы можете сделать с Camalian, — это определить каждый оттенок цвета, используемый в изображении.

Допустим, у нас есть изображение с 15 различными цветами.

Определить цвета по образцу, безусловно, проще, чем определить их по самому изображению. Более того, это простое изображение, а реальные фотографии часто бывают гораздо более разнообразными, когда дело доходит до их цветовой палитры. Для извлечения значений цвета из изображения требуется несколько довольно сложных фрагментов кода, и именно здесь появляется Camalian. Он делает эти сложные вещи за вас, чтобы вы могли легко извлекать информацию, связанную с цветом, из изображения.

Начиная

Если извлекать цвета с помощью Camalian легко, то установка с ним еще проще. Вы можете установить гем Ruby, выполнив:

 gem install camalian

И чтобы использовать этот драгоценный камень, вы можете запросить его непосредственно в своем Ruby-скрипте:

 require 'camalian'

Извлечение цветов

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

 image = Camalian::load( File.join( File.dirname(__FILE__), 'colormap.png') ) colors = image.prominent_colors(15) puts colors.map(&:to_hex)

Этот фрагмент кода загружает изображение с именем «colormap.png» из каталога, в котором находится скрипт, и извлекает из него 15 наиболее ярких цветов.

Чтобы запустить его, сохраните файл как «color_test1.rb» и запустите его в оболочке с помощью ruby color_test1.rb . Он должен производить вывод, аналогичный следующему:

 ["#318578", "#41b53f", "#2560a3", "#359169", "#2154b1", "#4dda15", "#1d48bf", "#1530dc", "#296d94", "#193dcd", "#3da94d", "#45c131", "#3da84e", "#2d7986", "#193cce"]

И это так просто! Мы только что извлекли 15 цветов, используемых на изображении выше. Можете ли вы представить себе попытку сделать это с помощью зацикленного кода или, что еще хуже, глазами? Давайте наберем вещи на ступеньку выше. На этот раз мы попробуем использовать Camalian на изображении с более подробной информацией:

Запустив тот же скрипт на этом изображении, мы получим следующее:

 [“#210b03”, “#723209”, “#974d09”, “#ae5d08”, “#c77414”, “#d77f15”, “#ffea54”, “#94651f”, “#b66a15”, “#c25f06”, “#fdd94d”, “#d39a39”, “#efa540”, “#fffffe”, “#fff655”]

Попытка визуализировать массив значений цвета, полученный выше, дает нам что-то вроде этого:

Палитра хорошая, но какой-то определенной закономерности в извлекаемых цветах нет. Давайте отсортируем значения цвета по сходству и посмотрим, поможет ли это. Все, что нам нужно сделать, это вызвать еще одну функцию, прежде чем на самом деле вывести массив на консоль:

 colors = image.prominent_colors(15).sort_similar_colors 

Но что, если мы хотим извлечь цвета, которые относительно светлее? Возможно, нам нужны цвета, которые темнее всего на 40%, или, другими словами, имеют значение яркости (в цветовом пространстве HSL) от 0 до 40. Все, что нам нужно сделать, это:

 colors = image.prominent_colors(15).light_colors(0, 40) 

Создание системы поиска изображений

Теперь, когда мы знаем, как легко работать с цветами с помощью Camalian, давайте создадим простое веб-приложение, позволяющее загружать изображения и индексировать их по цвету. Для краткости мы пропустим различные детали, связанные с созданием приложения Ruby. Вместо этого мы сосредоточимся на особенностях, связанных с цветами и использованием Camalian.

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

Ниже приведена схема модели, объясняющая структуру нашего приложения:

Каждое загруженное изображение представлено с помощью объекта PortfolioItem. Каждый объект Color представляет уникальные цвета, обнаруженные с помощью загруженных изображений, и, наконец, PortfolioColor представляет связь между каждым изображением и найденными в нем цветами.

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

 after_save :extract_colors private def extract_colors image = Camalian::load(self.image.path) colors = image.prominent_colors(self.color_count.to_i).sort_similar_colors colors.each do |color| unless c = Color.where(r: color.r, g: color.g, b: color.b).first c = Color.create(r: color.r, g: color.g, b: color.b, h: color.h, s: color.s, l: color.l) end self.colors << c end end

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

Когда пользователь отправляет изображение через форму в веб-интерфейсе, изображение принимается через обработчик сообщений, и для него создается новый PortfolioItem . Этот метод, extract_colors , вызывается всякий раз, когда элемент портфолио сохраняется в базе данных.

Чтобы иметь возможность отображать цветовую палитру на страницах, мы используем простой помощник:

 module PortfolioItemsHelper def print_color_palette(colors) color_string = '' colors.each do |c| color_string += content_tag :span, ' ', style: "display: block; float: left; width: 35px; height: 35px; background: #{c.to_hex}" end content_tag :div, color_string.html_safe, style: "display: inline-block;" end end

По сути, он создает div с небольшими квадратными интервалами , каждый из которых имеет цвет фона, установленный в один из извлеченных основных цветов.

Наконец, чтобы реализовать поиск, мы должны использовать немного математики и логики:

 class PortfolioSearchForm include ActiveModel::Model attr_accessor :color, :similarity validates_presence_of :color, :similarity def color_object @color_object ||= Camalian::Color.new(self.color) end def color_range(color, level) (color_object.send(color) - level)..(color_object.send(color) + level) end def colors_by_rgb level = self.similarity.to_i * 255 / 100.0 Color.where(r: color_range(:r, level), g: color_range(:g, level), b: color_range(:b, level)) end def colors_by_hsl level = self.similarity.to_i Color.where(h: color_range(:h, (self.similarity.to_i * 30 / 100.0) ), s: color_range(:s, level), l: color_range(:l, level)) end end

С помощью метода colors_by_hsl мы можем получить все объекты Color , соответствующие нашему запросу. И с их помощью мы можем идентифицировать все загруженные изображения и отображать нашу страницу результатов поиска. Сам запрос довольно прост. Учитывая определенный цвет и значение подобия, диапазон значений вычисляется для каждого цветового компонента.

И это почти все сложные моменты.

Пробуем

Вы можете найти полный код на GitHub. Вы можете развернуть экземпляр этого приложения на Heroku или попробовать его локально:

 git clone https://github.com/nazarhussain/camalian-sample-app.git cd camalian-sample-app bundle install rake db:migrate rails s

Окончательное приложение выглядит примерно так:

После запуска приложения укажите в веб-браузере адрес http://localhost:3000. Используя форму на экране, загрузите несколько изображений разных цветовых палитр. Затем для поиска изображений по цвету используйте поле поиска в правом верхнем углу. Раскрывающийся список порогов позволяет указать допуск несхожести для соответствия цветов изображений.

Что дальше?

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

  • Запрет пользователям загружать темные изображения профиля
  • Адаптировать цветовую тему сайта к какой-либо картинке, загруженной пользователем
  • Для конкурсов дизайна автоматически проверяйте представленные материалы на соответствие требованиям цветовой палитры.

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