Costruire un motore di ricerca di immagini basato sul colore in Ruby
Pubblicato: 2022-03-11Si dice che un'immagine vale più di mille parole. E per molti versi le parole nelle immagini sono colori. I colori sono parte integrante della nostra vita e non possiamo negare la loro importanza.
Mentre guardiamo un'immagine, abbiamo spesso cercato di identificare il colore su una parte di essa. Tutti abbiamo provato a farlo ma non lo abbiamo mai fatto nei dettagli. Quando ci viene chiesto di identificare i colori da un'immagine, tendiamo a etichettarli usando nomi di colori specifici, come rosso, blu e verde. Tuttavia, se ci viene chiesto di estrarre i 30 colori più importanti in un'immagine, il nostro occhio non può rilevarli o identificarli altrettanto facilmente. Camalian è tutto questo. Ti aiuta a estrarre i colori dalle immagini e poi a giocarci.
In questo articolo, daremo un'occhiata a cosa sono gli spazi colore, cosa ha da offrire la gemma Rubino Camalian e come può essere utilizzata per creare un semplice motore di ricerca di immagini che utilizza i colori per identificarli e distinguerli.
Spazio dei colori
Prima di iniziare, comprendiamo innanzitutto alcuni concetti di base sui colori. Le immagini presentate sui nostri schermi sono rappresentate utilizzando una matrice bidimensionale di pixel. Sebbene i file di immagine possano essere codificati in modi diversi, la rappresentazione grezza dopo la decompressione e la decodifica dei dati è la stessa. In questa rappresentazione basata su array 2D, ogni pixel in un'immagine a colori ha tre componenti: rosso, verde e blu. Sebbene le immagini stampate su carta siano anche una superficie bidimensionale di punti, i punti stessi sono solitamente una miscela di inchiostri a quattro componenti: ciano, magenta, giallo e nero. Queste, tra le altre diverse tecniche utilizzate per rappresentare i colori, sono chiamate spazi colore. Alcuni degli spazi colore più utilizzati sono RGB, CMYK, HSL e HSV. CMYK è utilizzato principalmente nel settore della stampa mentre tutti gli altri sono utilizzati nei media digitali.
Spazio colore RGB
Qualsiasi supporto elettronico fisico come schermi CRT, LCD o telefoni che trasmettono luce producono colore utilizzando tre componenti: rosso, verde, blu. L'occhio umano può rilevare milioni di colori stimolando tre tipi di recettori dei colori nell'occhio. Puoi mettere in relazione quei recettori con R, G e B.
Idealmente, ogni componente del colore è memorizzato in un byte i cui valori possono variare tra 0 e 255.
Spazio colore HSL e HSV
Disporre lo spazio colore RGB su un cubo è piuttosto impegnativo. I risultati del tentativo di rappresentarlo su un cubo e/o sulla ruota dei colori sono scarsi. Mentre si lavora con milioni o colori, ogni sfumatura di colore non può essere allineata correttamente sullo spazio colore RGB.
Per superare questo problema, negli anni '70 i ricercatori hanno introdotto gli spazi colore HSV (Hue, Saturation, Value) e HSL (Hue, Saturation, Lightness). Entrambi questi spazi colore possono essere allineati correttamente su una ruota dei colori e semplificano l'identificazione di varie sfumature di colore su di essa.
Gemma di rubino per i colori
Camalian è tutta una questione di colori. Una delle cose più semplici che puoi fare con Camalian è identificare ogni sfumatura di colore utilizzata in un'immagine.
Diciamo che abbiamo un'immagine con 15 colori distinti.
Identificare i colori dal campione è sicuramente più facile che identificarli dall'immagine stessa. Inoltre, questa è un'immagine semplice e le foto reali catturate sono spesso molto più diverse quando si tratta della loro tavolozza di colori. L'estrazione dei valori di colore dall'immagine richiede alcuni bit di codice piuttosto complicati, ed è qui che entra in gioco Camalian. Fa queste cose complicate per te in modo che tu possa estrarre facilmente le informazioni relative al colore da un'immagine.
Iniziare
Se estrarre i colori con Camalian è facile, installarlo è ancora più facile. Puoi installare la gemma Ruby eseguendo:
gem install camalian
E per usare questa gemma, puoi richiederla direttamente nel tuo script Ruby:
require 'camalian'
Estrazione dei colori
Per estrarre i colori da un'immagine, dobbiamo prima caricarla in memoria e utilizzare i metodi sull'oggetto immagine:
image = Camalian::load( File.join( File.dirname(__FILE__), 'colormap.png') ) colors = image.prominent_colors(15) puts colors.map(&:to_hex)
Questo frammento di codice carica un'immagine denominata "colormap.png" dalla directory in cui risiede lo script ed estrae da essa i 15 colori più importanti.
Per eseguirlo, salva il file come "color_test1.rb" ed eseguilo nella shell da ruby color_test1.rb
. Dovrebbe produrre un output simile al seguente:
["#318578", "#41b53f", "#2560a3", "#359169", "#2154b1", "#4dda15", "#1d48bf", "#1530dc", "#296d94", "#193dcd", "#3da94d", "#45c131", "#3da84e", "#2d7986", "#193cce"]
Ed è così facile! Abbiamo appena estratto 15 colori usati nell'immagine sopra. Riesci a immaginare di provare a farlo usando un codice loopy, o peggio, con i tuoi occhi? Comportiamo le cose di una tacca. Questa volta, proveremo a utilizzare Camalian su un'immagine con maggiori dettagli:
Eseguendo lo stesso script su questa immagine otteniamo quanto segue:
[“#210b03”, “#723209”, “#974d09”, “#ae5d08”, “#c77414”, “#d77f15”, “#ffea54”, “#94651f”, “#b66a15”, “#c25f06”, “#fdd94d”, “#d39a39”, “#efa540”, “#fffffe”, “#fff655”]
Il tentativo di visualizzare l'array di valori di colore prodotti sopra ci dà qualcosa del genere:
La tavolozza è buona, ma non c'è un motivo specifico nei colori estratti. Ordiniamo i valori del colore per somiglianza e vediamo se questo aiuta. Tutto quello che dobbiamo fare è chiamare un'altra funzione prima di stampare effettivamente l'array sulla console:

colors = image.prominent_colors(15).sort_similar_colors
Ma cosa accadrebbe se volessimo estrarre colori relativamente più chiari? Forse vogliamo colori che sono solo il 40% scuri, o in altre parole hanno un valore di luminosità (nello spazio colore HSL) compreso tra 0 e 40. Tutto ciò che dobbiamo fare è:
colors = image.prominent_colors(15).light_colors(0, 40)
Realizzare il motore di ricerca per immagini
Ora che sappiamo quanto sia facile gestire i colori usando Camalian, creiamo una semplice applicazione web che ti permetta di caricare immagini e farle indicizzare per colore. Per brevità, salteremo i vari dettagli coinvolti nella creazione di un'applicazione Ruby. Invece, ci concentreremo sulle specifiche che riguardano i colori e l'uso camaleo.
Per quanto riguarda l'ambito di questa applicazione Ruby, la limiteremo alla gestione dei caricamenti di immagini, all'estrazione dei colori dall'immagine prima di archiviarli e alla ricerca dell'immagine caricata in base al colore e alla soglia scelti.
Di seguito è riportato un diagramma modello per spiegare la struttura della nostra applicazione:
Ogni immagine caricata viene rappresentata utilizzando un oggetto PortfolioItem. Ogni oggetto Color rappresenta i colori unici scoperti attraverso le immagini caricate e infine PortfolioColor rappresenta la relazione tra ogni immagine e i colori che si trovano in essa.
La maggior parte dei bit dell'applicazione sono piuttosto standard, specialmente quando si tratta di gestire i caricamenti di immagini, la creazione di entità di modello e la loro permanenza nel database, ecc. Nel caso in cui tu sia uno sviluppatore Ruby, quelli dovrebbero essere un gioco da ragazzi. Di seguito è riportato il metodo utilizzato per estrarre il colore dall'immagine caricata:
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
Questo aiuta estraendo la tavolozza dei colori e salvandola nel database. Nota come estraiamo solo un numero specifico di colori prominenti (qualcosa che l'utente può definire quando carica l'immagine).
Quando un utente invia un'immagine tramite il modulo nell'interfaccia utente Web, l'immagine viene ricevuta tramite un gestore di post e viene creato un nuovo PortfolioItem per essa. Questo metodo, extract_colors , viene invocato ogni volta che un elemento del parco viene reso persistente nel database.
Per essere in grado di rendere la tavolozza dei colori sulle pagine, utilizziamo un semplice aiuto:
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
Crea essenzialmente un div con piccole campate quadrate, ciascuna con il colore di sfondo impostato su uno dei colori prominenti estratti.
Infine, per implementare la ricerca dobbiamo usare un po' di matematica e logica:
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
Con il metodo colors_by_hsl , possiamo recuperare tutte le entità Color che corrispondono alla nostra query. E, con questi possiamo identificare tutte le immagini caricate e rendere la nostra pagina dei risultati di ricerca. La query stessa è piuttosto semplice. Dato un colore specifico e un valore di somiglianza, viene calcolato un intervallo di valori per ogni componente di colore.
E queste sono praticamente tutte le parti difficili.
Provarlo
Puoi trovare il codice completo su GitHub. Puoi distribuire un'istanza di questa app su Heroku o provarla localmente:
git clone https://github.com/nazarhussain/camalian-sample-app.git cd camalian-sample-app bundle install rake db:migrate rails s
L'applicazione finale è simile a questa:
Una volta che l'applicazione è in esecuzione, punta il tuo browser web su http://localhost:3000. Utilizzando il modulo sullo schermo, carica alcune immagini di tavolozze di colori variabili. Quindi, per cercare le immagini per colore, utilizza il campo di ricerca nell'angolo in alto a destra. L'elenco a discesa della soglia consente di specificare la tolleranza di dissomiglianza per la corrispondenza dei colori delle immagini.
Qual è il prossimo?
L'applicazione demo che abbiamo creato in questo articolo è piuttosto semplice, ma le possibilità sono infinite! Alcuni altri usi pratici di questa libreria possono includere:
- Limitazione agli utenti di caricare immagini del profilo scure
- Adatta il tema del colore del sito ad alcune immagini caricate dall'utente
- Per i concorsi di progettazione, convalida automaticamente gli invii in base ai requisiti della tavolozza dei colori
Puoi esplorare ulteriormente la libreria su GitHub e controllare il suo codice sorgente. Sentiti libero di segnalare bug creando problemi o contribuire inviando richieste pull.