Construirea unui motor de căutare de imagini bazat pe culoare în Ruby
Publicat: 2022-03-11Se spune că o imagine valorează cât o mie de cuvinte. Și în multe privințe, cuvintele din imagini sunt culori. Culorile sunt o parte integrantă a vieții noastre și nu le putem nega importanța.
În timp ce privim o imagine, am încercat adesea să identificăm culoarea unei părți a acesteia. Cu toții am încercat să o facem, dar nu am făcut-o niciodată în detalii. Când li se cere să identifice culorile dintr-o imagine, avem tendința de a le eticheta folosind nume de culori specifice, cum ar fi roșu, albastru și verde. Cu toate acestea, dacă ni se cere să extragem cele 30 de culori cele mai proeminente dintr-o imagine, ochiul nostru nu le poate detecta sau identifica la fel de ușor. Camalian este totul despre asta. Vă ajută să extrageți culorile din imagini și apoi să vă jucați cu ele.
În acest articol, vom arunca o privire asupra spațiilor de culoare, ce are de oferit bijuteria Ruby Camalian și cum poate fi folosită pentru a realiza un simplu motor de căutare a imaginilor care folosește culori pentru a le identifica și a le distinge.
Spațiul de culori
Înainte de a începe, să înțelegem mai întâi câteva concepte de bază despre culori. Imaginile prezentate pe ecranele noastre sunt reprezentate folosind o matrice bidimensională de pixeli. Deși fișierele de imagine pot fi codificate în moduri diferite, reprezentarea brută după decomprimarea și decodificarea datelor este aceeași. În această reprezentare bazată pe matrice 2D, fiecare pixel dintr-o imagine color are trei componente: roșu, verde și albastru. Deși imaginile imprimate pe hârtie sunt, de asemenea, o suprafață bidimensională de puncte, punctele în sine sunt de obicei un amestec de cerneluri cu patru componente: cyan, magenta, galben și negru. Acestea, printre alte tehnici diferite, sunt folosite pentru a reprezenta culorile, se numesc spații de culoare. Unele dintre cele mai populare spații de culoare sunt RGB, CMYK, HSL și HSV. CMYK este folosit mai ales în industria tipăririi, în timp ce toate celelalte sunt folosite în mediile digitale.
Spațiu de culoare RGB
Orice suport electronic fizic, cum ar fi ecranele CRT, LCD-urile sau telefoanele care transmit lumină, produc culoare folosind trei componente: roșu, verde, albastru. Ochiul uman poate detecta milioane de culori prin stimularea a trei tipuri de receptori de culoare din ochi. Puteți lega acei receptori la R, G și B.
În mod ideal, fiecare componentă de culoare este stocată într-un octet ale cărui valori pot varia între 0 și 255.
Spațiu de culoare HSL și HSV
Aranjarea spațiului de culoare RGB pe un cub este destul de dificilă. Rezultatele încercării de a-l reprezenta pe un cub sau pe o roată de culori sunt slabe. În timp ce lucrați cu milioane sau culori, fiecare nuanță de culoare nu poate fi aliniată corect în spațiul de culoare RGB.
Pentru a depăși această problemă, în anii 1970, cercetătorii au introdus spațiile de culoare HSV (Hue, Saturation, Value) și HSL (Hue, Saturation, Lightness). Ambele spații de culoare pot fi aliniate corect pe o roată de culoare și facilitează identificarea diferitelor nuanțe de culoare pe aceasta.
Bijuterie de rubin pentru culori
Camalian este totul despre culori. Unul dintre cele mai simple lucruri pe care le puteți face cu Camalian este să identificați fiecare nuanță de culoare folosită într-o imagine.
Să presupunem că avem o imagine cu 15 culori distincte.
Identificarea culorilor din eșantion este cu siguranță mai ușoară decât identificarea lor din imagine în sine. În plus, aceasta este o imagine simplă, iar fotografiile reale capturate sunt adesea mult mai diverse când vine vorba de paleta lor de culori. Extragerea valorilor de culoare din imagine necesită niște fragmente de cod destul de complicate și aici intervine Camalian. Face aceste lucruri complicate pentru tine, astfel încât să poți extrage cu ușurință informații legate de culoare dintr-o imagine.
Noțiuni de bază
Dacă extragerea culorilor cu Camalian este ușoară, instalarea cu acesta este și mai ușoară. Puteți instala bijuteria Ruby executând:
gem install camalian
Și pentru a utiliza această bijuterie, o puteți solicita direct în scriptul dvs. Ruby:
require 'camalian'
Extragerea culorilor
Pentru a extrage culori dintr-o imagine, trebuie mai întâi să o încărcăm în memorie și să folosim metode pe obiectul imagine:
image = Camalian::load( File.join( File.dirname(__FILE__), 'colormap.png') ) colors = image.prominent_colors(15) puts colors.map(&:to_hex)
Acest fragment de cod încarcă o imagine numită „colormap.png” din directorul în care se află scriptul și extrage cele mai proeminente 15 culori din acesta.
Pentru a-l rula, salvați fișierul ca „color_test1.rb” și rulați-l în shell de ruby color_test1.rb
. Ar trebui să producă rezultate similare cu următoarele:
["#318578", "#41b53f", "#2560a3", "#359169", "#2154b1", "#4dda15", "#1d48bf", "#1530dc", "#296d94", "#193dcd", "#3da94d", "#45c131", "#3da84e", "#2d7986", "#193cce"]
Și este atât de ușor! Tocmai am extras 15 culori folosite în imaginea de mai sus. Vă puteți imagina că încercați să o faceți folosind codul loopy sau, mai rău, cu ochii? Să rezolvăm lucrurile cu o crestătură. De data aceasta, vom încerca să folosim Camalian pe o imagine cu mai multe detalii:
Rulând același script pe această imagine obținem următoarele:
[“#210b03”, “#723209”, “#974d09”, “#ae5d08”, “#c77414”, “#d77f15”, “#ffea54”, “#94651f”, “#b66a15”, “#c25f06”, “#fdd94d”, “#d39a39”, “#efa540”, “#fffffe”, “#fff655”]
Încercarea de a vizualiza matricea de valori de culoare produse mai sus ne oferă ceva de genul acesta:
Paleta este bună, dar nu există un model specific în culorile extrase. Să sortăm valorile culorilor după asemănare și să vedem dacă asta ajută. Tot ce trebuie să facem este să apelăm încă o funcție înainte de a imprima efectiv matricea pe consolă:

colors = image.prominent_colors(15).sort_similar_colors
Dar dacă am vrea să extragem culori care sunt relativ mai deschise? Poate că vrem culori care sunt doar 40% întunecate sau, cu alte cuvinte, au o valoare a luminii (în spațiul de culoare HSL) între 0 și 40. Tot ce trebuie să facem este:
colors = image.prominent_colors(15).light_colors(0, 40)
Realizarea motorului de căutare a imaginilor
Acum că știm cât de ușor este să te ocupi de culori folosind Camalian, haideți să construim o aplicație web simplă care vă permite să încărcați imagini și să le indexați după culoare. Pentru concizie, vom sări peste diferitele detalii implicate în construirea unei aplicații Ruby. În schimb, ne vom concentra pe specificul care se referă la culori și la utilizarea Camalian.
În ceea ce privește domeniul de aplicare al acestei aplicații Ruby, o vom limita la gestionarea încărcărilor de imagini, extragerea culorilor din imagine înainte de a le stoca și căutarea imaginii încărcate pe baza culorii și a pragului alese.
Mai jos este o diagramă model pentru a explica structura aplicației noastre:
Fiecare imagine încărcată este reprezentată folosind un obiect PortfolioItem. Fiecare obiect Color reprezintă culori unice descoperite prin imaginile încărcate, iar în final PortfolioColor reprezintă relația dintre fiecare imagine și culorile găsite în ea.
Cele mai multe părți ale aplicației sunt destul de standard, mai ales când vine vorba de gestionarea încărcărilor de imagini, crearea de entități model și păstrarea lor în baza de date etc. În cazul în care sunteți un dezvoltator Ruby, acestea ar trebui să fie deloc pe cap. Mai jos este metoda folosită pentru a extrage culoarea din imaginea încărcată:
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
Acest lucru ajută prin extragerea paletei de culori și salvarea în baza de date. Observați cum extragem doar un anumit număr de culori proeminente (ceva pe care utilizatorul îl poate defini atunci când încarcă imaginea).
Când un utilizator trimite o imagine prin formularul de pe interfața de utilizare web, imaginea este primită printr-un handler de postare și este creat un nou PortfolioItem pentru aceasta. Această metodă, extract_colors , este invocată ori de câte ori un articol din portofoliu este persistat în baza de date.
Pentru a putea reda paleta de culori pe pagini, folosim un ajutor simplu:
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
În esență, creează un div cu intervale pătrate mici , fiecare cu culoarea de fundal setată la una dintre culorile proeminente extrase.
În cele din urmă, pentru a implementa căutarea, trebuie să folosim ceva matematică și logică:
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
Cu metoda colors_by_hsl , putem prelua toate entitățile Color care se potrivesc cu interogarea noastră. Și, cu acestea, putem identifica toate imaginile încărcate și reda pagina noastră cu rezultatele căutării. Interogarea în sine este destul de simplă. Având în vedere o anumită culoare și o valoare de similaritate, se calculează un interval de valori pentru fiecare componentă de culoare.
Și acestea sunt aproape toate părțile grele.
Încercând
Puteți găsi codul complet pe GitHub. Puteți să implementați o instanță a acestei aplicații în Heroku sau să o încercați local:
git clone https://github.com/nazarhussain/camalian-sample-app.git cd camalian-sample-app bundle install rake db:migrate rails s
Aplicația finală arată cam așa:
Odată ce aplicația rulează, îndreptați browserul web către http://localhost:3000. Folosind formularul de pe ecran, încărcați câteva imagini cu palete de culori diferite. Apoi, pentru a căuta imagini după culoare, utilizați câmpul de căutare din colțul din dreapta sus. Lista derulantă pentru prag vă permite să specificați toleranța de diferență pentru potrivirea culorilor imaginilor.
Ce urmeaza?
Aplicația demo pe care am construit-o în acest articol este destul de simplă, dar posibilitățile sunt nesfârșite! Alte utilizări practice ale acestei biblioteci pot include:
- Limitarea utilizatorilor de a încărca imagini de profil întunecate
- Adaptați tema de culoare a site-ului la o imagine încărcată de utilizator
- Pentru competițiile de design, validați automat trimiterile în funcție de cerințele paletei de culori
Puteți explora în continuare biblioteca pe GitHub și puteți verifica codul sursă al acesteia. Simțiți-vă liber să raportați erori creând probleme sau să contribuiți trimițând solicitări de extragere.