Construire un moteur de recherche d'images basé sur la couleur dans Ruby

Publié: 2022-03-11

On dit qu'une image vaut mille mots. Et à bien des égards, les mots dans les images sont des couleurs. Les couleurs font partie intégrante de notre vie et nous ne pouvons nier leur importance.

En regardant une image, nous avons souvent essayé d'identifier la couleur d'une partie de celle-ci. Nous avons tous essayé de le faire mais nous ne l'avons jamais fait dans les détails. Lorsqu'on nous demande d'identifier les couleurs d'une image, nous avons tendance à les étiqueter en utilisant des noms de couleurs spécifiques, tels que le rouge, le bleu et le vert. Cependant, si on nous demande d'extraire les 30 couleurs les plus importantes d'une image, notre œil ne peut pas les détecter ou les identifier aussi facilement. Camalian est tout à propos de cela. Il vous aide à extraire les couleurs des images, puis à jouer avec elles.

Camalian : sélecteur de couleurs ultime pour Ruby

Dans cet article, nous allons jeter un coup d'œil à ce que sont les espaces colorimétriques, ce que le joyau Ruby Camalian a à offrir et comment il peut être utilisé pour créer un moteur de recherche d'images simple qui utilise les couleurs pour les identifier et les distinguer.

Espace des couleurs

Avant de commencer, comprenons d'abord quelques concepts de base sur les couleurs. Les images présentées sur nos écrans sont représentées à l'aide d'un tableau bidimensionnel de pixels. Bien que les fichiers image puissent être encodés de différentes manières, la représentation brute après décompression et décodage des données est la même. Dans cette représentation basée sur un tableau 2D, chaque pixel d'une image couleur a trois composants : rouge, vert et bleu. Bien que les images imprimées sur un papier soient également une surface bidimensionnelle de points, les points eux-mêmes sont généralement un mélange de quatre encres : cyan, magenta, jaune et noir. Parmi certaines autres techniques différentes, celles-ci sont utilisées pour représenter les couleurs et sont appelées espaces colorimétriques. Certains des espaces colorimétriques les plus couramment utilisés sont RVB, CMJN, HSL et HSV. CMJN est principalement utilisé dans l'industrie de l'impression tandis que tous les autres sont utilisés dans les médias numériques.

Espace colorimétrique RVB

Tous les supports électroniques physiques tels que les écrans CRT, les écrans LCD ou les téléphones qui transmettent la lumière produisent des couleurs à l'aide de trois composants : rouge, vert et bleu. L'œil humain peut détecter des millions de couleurs en stimulant trois types de récepteurs de couleurs dans l'œil. Vous pouvez relier ces récepteurs à R, G et B.

Idéalement, chaque composante de couleur est stockée dans un octet dont les valeurs peuvent être comprises entre 0 et 255.

Espace colorimétrique HSL et HSV

Organiser l'espace colorimétrique RVB sur un cube est plutôt difficile. Les résultats d'essayer de le représenter sur un cube et / ou une roue de couleur sont médiocres. Lorsque vous travaillez avec des millions de couleurs, chaque teinte de couleur ne peut pas être alignée correctement sur l'espace colorimétrique RVB.

moteur de recherche d'images rubis

Pour surmonter ce problème, dans les années 1970, les chercheurs ont introduit les espaces colorimétriques HSV (Teinte, Saturation, Valeur) et HSL (Teinte, Saturation, Luminosité). Ces deux espaces colorimétriques peuvent être correctement alignés sur une roue chromatique et faciliter l'identification des différentes teintes de couleur sur celle-ci.

Gemme rubis pour les couleurs

Camalian est tout au sujet des couleurs. L'une des choses les plus simples que vous puissiez faire avec Camalian est d'identifier chaque teinte de couleur utilisée dans une image.

Disons que nous avons une image avec 15 couleurs distinctes.

Identifier les couleurs à partir de l'échantillon est certainement plus facile que de les identifier à partir de l'image elle-même. De plus, il s'agit d'une image simple et les vraies photos capturées sont souvent beaucoup plus diversifiées en ce qui concerne leur palette de couleurs. L'extraction des valeurs de couleur de l'image nécessite des morceaux de code assez délicats, et c'est là que Camalian entre en jeu. Il fait ces choses délicates pour vous afin que vous puissiez extraire facilement les informations relatives à la couleur d'une image.

Commencer

Si extraire des couleurs avec Camalian est facile, installer avec lui l'est encore plus. Vous pouvez installer le gem Ruby en exécutant :

 gem install camalian

Et pour utiliser cette gemme, vous pouvez l'exiger directement dans votre script Ruby :

 require 'camalian'

Extraction des couleurs

Pour extraire les couleurs d'une image, nous devons d'abord la charger en mémoire et utiliser des méthodes sur l'objet image :

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

Cet extrait de code charge une image nommée "colormap.png" à partir du répertoire où réside le script et en extrait les 15 couleurs les plus importantes.

Pour l'exécuter, enregistrez le fichier sous "color_test1.rb" et exécutez-le en shell par ruby color_test1.rb . Il devrait produire une sortie semblable à celle-ci :

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

Et c'est aussi simple que ça ! Nous venons d'extraire 15 couleurs utilisées dans l'image ci-dessus. Pouvez-vous imaginer essayer de le faire en utilisant du code en boucle, ou pire, avec vos yeux ? Composons les choses d'un cran. Cette fois, nous allons essayer d'utiliser Camalian sur une image avec plus de détails :

En exécutant le même script sur cette image, nous obtenons ce qui suit :

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

Essayer de visualiser le tableau de valeurs de couleurs produit ci-dessus nous donne quelque chose comme ceci :

La palette est bonne, mais il n'y a pas de motif spécifique dans les couleurs extraites. Trions les valeurs de couleur par similarité et voyons si cela aide. Tout ce que nous avons à faire est d'appeler une fonction supplémentaire avant d'afficher réellement le tableau sur la console :

 colors = image.prominent_colors(15).sort_similar_colors 

Et si on voulait extraire des couleurs relativement plus claires ? Peut-être voulons-nous des couleurs qui ne sont qu'à 40% sombres, ou en d'autres termes ont une valeur de luminosité (dans l'espace colorimétrique HSL) comprise entre 0 et 40. Tout ce que nous devons faire est:

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

Création du moteur de recherche d'images

Maintenant que nous savons à quel point il est facile de gérer les couleurs avec Camalian, construisons une application Web simple qui vous permet de télécharger des images et de les indexer par couleur. Par souci de concision, nous allons ignorer les différents détails impliqués dans la construction d'une application Ruby. Au lieu de cela, nous nous concentrerons sur les spécificités qui traitent des couleurs et de l'utilisation de Camalian.

En ce qui concerne la portée de cette application Ruby, nous la limiterons à la gestion des téléchargements d'images, à l'extraction des couleurs de l'image avant de les stocker et à la recherche d'images téléchargées en fonction de la couleur et du seuil choisis.

Vous trouverez ci-dessous un schéma modèle pour expliquer la structure de notre application :

Chaque image téléchargée est représentée à l'aide d'un objet PortfolioItem. Chaque objet Color représente des couleurs uniques découvertes à travers des images téléchargées, et enfin PortfolioColor représente la relation entre chaque image et les couleurs qui s'y trouvent.

La plupart des éléments de l'application sont assez standard, en particulier lorsqu'il s'agit de gérer les téléchargements d'images, de créer des entités de modèle et de les conserver dans la base de données, etc. Si vous êtes un développeur Ruby, cela ne devrait pas poser de problème. Vous trouverez ci-dessous la méthode utilisée pour extraire la couleur de l'image téléchargée :

 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

Cela aide en extrayant la palette de couleurs et en l'enregistrant dans la base de données. Remarquez comment nous extrayons uniquement un nombre spécifique de couleurs proéminentes (quelque chose que l'utilisateur peut définir lors du téléchargement de l'image).

Lorsqu'un utilisateur soumet une image via le formulaire sur l'interface utilisateur Web, l'image est reçue via un gestionnaire de publication et un nouveau PortfolioItem est créé pour elle. Cette méthode, extract_colors , est invoquée chaque fois qu'un élément du portefeuille est conservé dans la base de données.

Pour pouvoir restituer la palette de couleurs sur les pages, nous utilisons une simple aide :

 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

Il crée essentiellement un div avec de petites étendues carrées, chacune avec sa couleur d'arrière-plan définie sur l'une des couleurs proéminentes extraites.

Enfin, pour implémenter la recherche, nous devons utiliser des mathématiques et de la logique :

 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

Avec la méthode colors_by_hsl , nous pouvons récupérer toutes les entités Color qui correspondent à notre requête. Et, avec ceux-ci, nous pouvons identifier toutes les images téléchargées et afficher notre page de résultats de recherche. La requête elle-même est assez simple. Étant donné une couleur spécifique et une valeur de similarité, une plage de valeurs est calculée pour chaque composante de couleur.

Et c'est à peu près toutes les parties difficiles.

Essayer

Vous pouvez trouver le code complet sur GitHub. Vous pouvez déployer une instance de cette application sur Heroku ou l'essayer localement :

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

L'application finale ressemble à ceci :

Une fois l'application en cours d'exécution, pointez votre navigateur Web sur http://localhost:3000. À l'aide du formulaire à l'écran, téléchargez quelques images de différentes palettes de couleurs. Ensuite, pour rechercher des images par couleur, utilisez le champ de recherche dans le coin supérieur droit. La liste déroulante des seuils vous permet de spécifier la tolérance de dissemblance pour faire correspondre les couleurs des images.

Et après?

L'application de démonstration que nous avons construite dans cet article est plutôt simple, mais les possibilités sont infinies ! Certaines autres utilisations pratiques de cette bibliothèque peuvent inclure :

  • Empêcher les utilisateurs de télécharger des images de profil sombres
  • Adapter le thème de couleur du site à une image téléchargée par l'utilisateur
  • Pour les concours de design, validez automatiquement les soumissions par rapport aux exigences de la palette de couleurs

Vous pouvez explorer davantage la bibliothèque sur GitHub et consulter son code source. N'hésitez pas à signaler des bogues en créant des problèmes ou à contribuer en envoyant des demandes d'extraction.