A la découverte de la recherche visuelle

Par Moodstocks

A la découverte de la recherche visuelle header image 2

Fuzz factor, Ruby et RMagick

6 mars 2009 · 2 commentaires

Les férus du traitement d’image ont certainement déjà été confrontés au problème suivant : comment remplacer la couleur de fond d’une image par une autre, ou comment déterminer si 2 pixels ont des couleurs similaires ? Ce problème, en apparence simpliste, peut s’avérer plus délicat si les images à traiter comprennent des fonds dont la couleur n’est pas exactement uniforme mais possèdent de légères variations.

La stratégie à retenir consiste alors à être tolérant. Je m’explique. Tout développeur un tant soit peu sérieux n’aurait pas idée dans un code scientifique de comparer deux nombres flottants de manière exacte, i.e :

double x, double y;
// x resulte d'un calcul ... y resulte d'un autre calcul
if (x == y) { // mauvais
// ...
}

Dans un tel contexte, l’emploi d’une tolérance est de rigueur pour s’affranchir du bruit numérique, i.e. :

double eps = 1.e-12;
if (fabs(x - y) < eps) { // bon
// ...
}

Il est en est de même en traitement d’image : c’est ce que l’on appelle un fuzz factor.

Les adeptes du logiciel libre utilisent très certainement ImageMagick, et les amoureux de Ruby l’interface RMagick. La documentation du fuzz factor manque un peu de clarté à mon goût.

Pour faire simple, dans l’espace de couleur le plus basique qui soit - RGB - une couleur est un point dans l’espace, i.e. un triplet (x = red, y = green, z = blue). Dans un système 8 bits - dit Q8 - les valeurs sur chaque axe s’échelonnent de 0 à 255. Ainsi le blanc correspond à (255, 255, 255) et le noir (0, 0, 0).

Mesurer la similarité entre 2 couleurs revient donc à mesurer la distance entre 2 points. Ainsi 2 couleurs seront déclarées similaires si leur distance est inférieure ou égale à un seuil donné : il s’agit du fuzz factor.

Dans ImageMagick, 2 pixels p1 et p2 sont similaires au fuzz factor près si :
Fuzz Factor - Matching Similar Colors

Grâce au facteur 3, le fuzz factor s’échelonne de 0 à 255 - ou 0 à 100 %. Ainsi :

  • un fuzz factor de 255 - ou 100 % - revient à dire que le blanc et le noir sont similaires.
  • un fuzz factor de 255 / racine(3) - ou 57,7 % - revient à dire que le bleu (0, 0, 255) et le noir sont similaires.

Il est à noter que la fonction fcmp de RMagick permet d’appliquer facilement cette distance.

Passons à la pratique sur une image simple : la buddy icon de Flickr.com.


require 'rubygems'
require 'RMagick'
include Magick

# Etapes
# ---
# 1. Lecture de l'image
# 2. Lecture de la couleur au coin haut gauche
# 3. Remplacement de la couleur de fond par du rouge
# 4. Enregistrement des sorties

img = Image::read("http://blog.moodstocks.com/wp-content/uploads/2009/03/buddy.jpg").first
img.format = "JPG"

ref = img.pixel_color(0, 0)

out = File.new("buddy-out.jpg", "w"); out.binmode
img.fuzz = "2%" # => le fuzz factor
out.write(img.opaque(ref.to_color, 'red').to_blob); out.close

Sans fuzz factor le résultat comporte du bruit :

Avec 2 % de fuzz factor le résultat est parfait :

Catégorie(s) : Traitement d'images

2 réponses pour le moment ↓

Laisser un commentaire