Erstellen einer farbbasierten Bildsuchmaschine in Ruby
Veröffentlicht: 2022-03-11Man sagt, ein Bild sagt mehr als tausend Worte. Und in vielerlei Hinsicht sind die Wörter in Bildern Farben. Farben sind ein wesentlicher Bestandteil unseres Lebens, und wir können ihre Bedeutung nicht leugnen.
Beim Betrachten eines Bildes haben wir oft versucht, die Farbe auf einem Teil davon zu identifizieren. Wir haben es alle versucht, aber nie im Detail gemacht. Wenn wir gebeten werden, Farben aus einem Bild zu identifizieren, bezeichnen wir sie in der Regel mit bestimmten Farbnamen wie Rot, Blau und Grün. Wenn wir jedoch gebeten werden, die 30 auffälligsten Farben in einem Bild zu extrahieren, kann unser Auge sie nicht so leicht erkennen oder identifizieren. Bei Camalian dreht sich alles darum. Es hilft Ihnen, Farben aus Bildern zu extrahieren und dann mit ihnen zu spielen.
In diesem Artikel werfen wir einen Blick darauf, worum es bei Farbräumen geht, was der Rubin-Edelstein Camalian zu bieten hat und wie er verwendet werden kann, um eine einfache Bildsuchmaschine zu erstellen, die Farben verwendet, um sie zu identifizieren und zu unterscheiden.
Farbraum
Bevor wir beginnen, wollen wir zunächst einige grundlegende Konzepte über Farben verstehen. Bilder, die auf unseren Bildschirmen präsentiert werden, werden durch ein zweidimensionales Array von Pixeln dargestellt. Obwohl Bilddateien auf unterschiedliche Weise codiert werden können, ist die grobe Darstellung nach dem Dekomprimieren und Decodieren der Daten dieselbe. In dieser 2D-Array-basierten Darstellung hat jedes Pixel in einem Farbbild drei Komponenten: Rot, Grün und Blau. Obwohl auf Papier gedruckte Bilder auch eine zweidimensionale Oberfläche aus Punkten sind, sind die Punkte selbst normalerweise eine Mischung aus vier Komponententinten: Cyan, Magenta, Gelb und Schwarz. Diese und einige andere Techniken, die zur Darstellung von Farben verwendet werden, werden als Farbräume bezeichnet. Einige der am häufigsten verwendeten Farbräume sind RGB, CMYK, HSL und HSV. CMYK wird hauptsächlich in der Druckindustrie verwendet, während alle anderen in digitalen Medien verwendet werden.
RGB-Farbraum
Alle physischen elektronischen Medien wie CRT-Bildschirme, LCDs oder Telefone, die Licht übertragen, erzeugen Farben mit drei Komponenten: Rot, Grün, Blau. Das menschliche Auge kann Millionen von Farben erkennen, indem es drei Arten von Farbrezeptoren im Auge stimuliert. Sie können diese Rezeptoren mit R, G und B in Beziehung setzen.
Idealerweise wird jede Farbkomponente in einem Byte gespeichert, dessen Werte zwischen 0 und 255 liegen können.
HSL- und HSV-Farbraum
Die Anordnung des RGB-Farbraums auf einem Würfel ist ziemlich anspruchsvoll. Die Ergebnisse beim Versuch, es auf einem Würfel und/oder einem Farbrad darzustellen, sind schlecht. Beim Arbeiten mit Millionen von Farben kann nicht jeder Farbton richtig auf den RGB-Farbraum ausgerichtet werden.
Um dieses Problem zu lösen, führten Forscher in den 1970er Jahren die Farbräume HSV (Hue, Saturation, Value) und HSL (Hue, Saturation, Lightness) ein. Diese beiden Farbräume können auf einem Farbrad richtig ausgerichtet werden und erleichtern das Erkennen verschiedener Farbtöne darauf.
Rubin-Edelstein für Farben
Bei Camalian dreht sich alles um Farben. Eines der einfachsten Dinge, die Sie mit Camalian tun können, ist, jeden Farbton zu identifizieren, der in einem Bild verwendet wird.
Nehmen wir an, wir haben ein Bild mit 15 verschiedenen Farben.
Das Identifizieren der Farben anhand des Musters ist sicherlich einfacher als das Identifizieren anhand des Bildes selbst. Darüber hinaus ist dies ein einfaches Bild, und echte Fotos sind oft viel vielfältiger, wenn es um ihre Farbpalette geht. Das Extrahieren der Farbwerte aus dem Bild erfordert einige ziemlich knifflige Code-Bits, und hier kommt Camalian ins Spiel. Es erledigt diese kniffligen Dinge für Sie, damit Sie mit Leichtigkeit farbbezogene Informationen aus einem Bild extrahieren können.
Einstieg
Wenn das Extrahieren von Farben mit Camalian einfach ist, ist die Installation damit noch einfacher. Sie können das Ruby-Gem installieren, indem Sie Folgendes ausführen:
gem install camalian
Und um dieses Juwel zu verwenden, können Sie es direkt in Ihrem Ruby-Skript anfordern:
require 'camalian'
Farben extrahieren
Um Farben aus einem Bild zu extrahieren, müssen wir es zuerst in den Speicher laden und Methoden auf das Bildobjekt anwenden:
image = Camalian::load( File.join( File.dirname(__FILE__), 'colormap.png') ) colors = image.prominent_colors(15) puts colors.map(&:to_hex)
Dieses Code-Snippet lädt ein Bild namens „colormap.png“ aus dem Verzeichnis, in dem sich das Skript befindet, und extrahiert daraus die 15 auffälligsten Farben.
Um es auszuführen, speichern Sie die Datei als „color_test1.rb“ und führen Sie sie in der Shell von ruby color_test1.rb
. Es sollte eine Ausgabe ähnlich der folgenden erzeugen:
["#318578", "#41b53f", "#2560a3", "#359169", "#2154b1", "#4dda15", "#1d48bf", "#1530dc", "#296d94", "#193dcd", "#3da94d", "#45c131", "#3da84e", "#2d7986", "#193cce"]
Und es ist so einfach! Wir haben gerade 15 Farben extrahiert, die im obigen Bild verwendet werden. Können Sie sich vorstellen, es mit Loopy-Code zu versuchen, oder schlimmer noch, mit Ihren Augen? Lassen Sie uns die Dinge um eine Stufe höher stellen. Dieses Mal werden wir versuchen, Camalian auf einem Bild mit mehr Details zu verwenden:
Indem wir dasselbe Skript auf diesem Bild ausführen, erhalten wir Folgendes:
[“#210b03”, “#723209”, “#974d09”, “#ae5d08”, “#c77414”, “#d77f15”, “#ffea54”, “#94651f”, “#b66a15”, “#c25f06”, “#fdd94d”, “#d39a39”, “#efa540”, “#fffffe”, “#fff655”]
Der Versuch, das oben erzeugte Array von Farbwerten zu visualisieren, ergibt etwa Folgendes:
Die Palette ist gut, aber es gibt kein bestimmtes Muster in den extrahierten Farben. Lassen Sie uns die Farbwerte nach Ähnlichkeit sortieren und sehen, ob das hilft. Alles, was wir tun müssen, ist, eine weitere Funktion aufzurufen, bevor wir das Array tatsächlich auf die Konsole drucken:

colors = image.prominent_colors(15).sort_similar_colors
Aber was wäre, wenn wir Farben extrahieren wollten, die relativ heller sind? Vielleicht möchten wir Farben, die nur zu 40 % dunkel sind, oder mit anderen Worten einen Helligkeitswert (im HSL-Farbraum) zwischen 0 und 40 haben. Alles, was wir tun müssen, ist:
colors = image.prominent_colors(15).light_colors(0, 40)
Erstellen der Bildsuchmaschine
Nachdem wir nun wissen, wie einfach es ist, mit Camalian mit Farben umzugehen, wollen wir eine einfache Webanwendung erstellen, mit der Sie Bilder hochladen und nach Farbe indizieren können. Der Kürze halber überspringen wir die verschiedenen Details zum Erstellen einer Ruby-Anwendung. Stattdessen werden wir uns auf Besonderheiten konzentrieren, die sich mit Farben und der kamalischen Verwendung befassen.
Was den Umfang dieser Ruby-Anwendung anbelangt, beschränken wir sie auf das Hochladen von Bildern, das Extrahieren von Farben aus dem Bild vor dem Speichern und das Suchen nach hochgeladenen Bildern basierend auf der ausgewählten Farbe und dem Schwellenwert.
Nachfolgend finden Sie ein Modelldiagramm, um die Struktur unserer Anwendung zu erläutern:
Jedes hochgeladene Bild wird durch ein PortfolioItem-Objekt dargestellt. Jedes Farbobjekt stellt einzigartige Farben dar, die durch hochgeladene Bilder entdeckt wurden, und schließlich stellt PortfolioColor die Beziehung zwischen jedem Bild und den darin gefundenen Farben dar.
Die meisten Teile der Anwendung sind ziemlich standardisiert, insbesondere wenn es darum geht, Bild-Uploads zu handhaben, Modellentitäten zu erstellen und sie in der Datenbank zu speichern usw. Falls Sie ein Ruby-Entwickler sind, sollten dies ein Kinderspiel sein. Unten ist die Methode, die verwendet wird, um die Farbe aus dem hochgeladenen Bild zu extrahieren:
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
Dies hilft, indem die Farbpalette extrahiert und in der Datenbank gespeichert wird. Beachten Sie, wie wir nur eine bestimmte Anzahl auffälliger Farben extrahieren (etwas, das der Benutzer beim Hochladen des Bildes definieren kann).
Wenn ein Benutzer ein Bild über das Formular auf der Webbenutzeroberfläche übermittelt, wird das Bild über einen Post-Handler empfangen und ein neues PortfolioItem dafür erstellt. Diese Methode, extract_colors , wird immer dann aufgerufen, wenn ein Portfolioelement in der Datenbank gespeichert wird.
Um die Farbpalette auf Seiten rendern zu können, verwenden wir einen einfachen Helfer:
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
Es erstellt im Wesentlichen ein div mit kleinen quadratischen Spannen , deren Hintergrundfarbe jeweils auf eine der extrahierten markanten Farben eingestellt ist.
Um die Suche zu implementieren, müssen wir schließlich etwas Mathematik und Logik verwenden:
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
Mit der Methode colors_by_hsl können wir alle Color -Entitäten abrufen, die unserer Abfrage entsprechen. Und mit diesen können wir alle hochgeladenen Bilder identifizieren und unsere Suchergebnisseite rendern. Die Abfrage selbst ist ziemlich einfach. Bei gegebener spezifischer Farbe und einem Ähnlichkeitswert wird für jede Farbkomponente ein Wertebereich berechnet.
Und das sind so ziemlich alle harten Teile.
Ausprobieren
Den vollständigen Code finden Sie auf GitHub. Sie können eine Instanz dieser App in Heroku bereitstellen oder sie lokal ausprobieren:
git clone https://github.com/nazarhussain/camalian-sample-app.git cd camalian-sample-app bundle install rake db:migrate rails s
Die endgültige Anwendung sieht in etwa so aus:
Sobald die Anwendung ausgeführt wird, richten Sie Ihren Webbrowser auf http://localhost:3000. Laden Sie mithilfe des Formulars auf dem Bildschirm einige Bilder mit unterschiedlichen Farbpaletten hoch. Verwenden Sie dann das Suchfeld in der oberen rechten Ecke, um Bilder nach Farbe zu suchen. Im Dropdown-Menü „Schwellenwert“ können Sie die Unähnlichkeitstoleranz für den Abgleich der Farben der Bilder festlegen.
Was kommt als nächstes?
Die Demoanwendung, die wir in diesem Artikel erstellt haben, ist ziemlich einfach, aber die Möglichkeiten sind endlos! Einige andere praktische Anwendungen dieser Bibliothek können sein:
- Benutzer daran hindern, dunkle Profilbilder hochzuladen
- Passen Sie das Farbthema der Website an ein vom Benutzer hochgeladenes Bild an
- Validieren Sie bei Designwettbewerben die Einreichungen automatisch anhand der Anforderungen an die Farbpalette
Sie können die Bibliothek auf GitHub weiter erkunden und sich den Quellcode ansehen. Fühlen Sie sich frei, Fehler zu melden, indem Sie Probleme erstellen, oder leisten Sie einen Beitrag, indem Sie Pull-Anfragen senden.