RICM4 - Accès à l'Information Multimédia - PROJET - Réalisation d'un système de recherche d'images fixes

Vous trouverez les supports de cours à l'adresse : http://mrim.imag.fr/HMUL8R6B/COURS.
Vous trouverez quelques examens des années précédentes à l'adresse : http://mrim.imag.fr/HMUL8R6B/EXAMENS (notez que le programme du cours a pu changer pour les plus anciens).

1. But

Le but de ce projet est de réaliser un système de recherche dans une base d'image à partir d'une image requête. Les images sont recherchées dans la base selon la similarité de leurs distributions de couleur ou de mots visuels avec celles de l'image. Le distribution de couleurs sera représentée par un histogramme tridimensionnel de couleurs. Le distribution de mots visuels représentée par un histogramme de descripteurs locaux de type SIFT.

Bien que ce ne soit pas obligatoire, le système pourra fonctionnera sur le web (par la CGI). Une alternative plus simple est de seulement générer une page web puis de l'afficher avec un navigateur. Dans tous les cas, il faut pouvoir afficher l'image requête et une liste des images les plus proches au sens de la couleur et/ou des descripteurs SIFT.

2. Données fournies

Les images que allez utiliser sont issues du projet VOC 2010 sur la classification automatique d'images (pour information, vous n'avez pas besoin d'étudier ce site).

Vous travaillerez sur la sous collection de test : (test, 9637 images). Le répertoire test contient:

  • Une liste d'images : list.txt ;
  • Une liste correspondante d'URLs permettant de les visualiser dans une page web : urls.txt .

3. Programmes fournis

Vous pourrez utiliser les éléments de code : cgiu.h/cgiu.c, utilitaire pour la CGI, et proc.h/proc.c qui contient d'autres fonctions utiles pour la réalisation du projet. Un programme testproc.c vous permet de tester quelques fonctions de ce module et vous montre comment les utiliser. Il se compile avec :

cc cgiu.c proc.c testproc.c -o testproc

(tout n'est pas utile pour ces TPs).

Si vous voulez faire une interface par CGI, vous pouvez partir du formulaire et du programme suivants : form_post4.html et post4.c. Pour plus d'informations à propos de CGI, voir html-cgi.pdf et langageC.pdf.

Vous pouvez regarder le TP2 de l'ancien cours RICM4-RIM pour des informations relatives au placement du formulaire HTML et du programme CGI, ainsi qu'au lien entre les deux avec le serveur HTTP de goedel.

Nous vous fournissons aussi un module pour charger en mémoire des images au format JPEG : rdjpeg.h/rdjpeg.c et un programme exemple qui charge une image en mémoire et affiche les plans rouge, vert et bleu du premier bloc 8×8 ce cette image : read_image.c. Il se compile avec :

cc rdjpeg.c read_image.c -o read_image

Un executable Linux djpeg est fourni pour le cas où il ne serait pas disponible sur votre système. S'il ne fonctionne pas, vous pouvez l'installer sur ubuntu avec la commande :

sudo apt-get install libjpeg-progs

Ça installe tout ce qui concerne le JPEG, y compris djpeg qui doit alors se retrouver dans /usr/bin .

4. Implémentation

4.1. Première partie: recherche par la distribution de couleurs.

Il y a deux programmes à écrire (ou un seul avec deux options).

  • Le premier s'exécute une seule fois (hors ligne). Il construit un index qui est un fichier contenant les histogrammes de toutes les images de la collection dans laquelle on effectue la recherche.
  • Le second s'exécute pour chaque requête (en ligne). Il calcule la distance Euclidienne entre l'histogramme de l'image requête et les histogrammes précalculés de toutes les images de la collections. Il trie enfin les images de la collection en fonction de ces distances et affiche les 10 plus proches par ordre de distance croissante.

Étapes :

  • Calculer un histogramme tridimensionnel de couleurs sur une image. Les composantes RGB seront chacune décomposées en 4 intervalles égaux. L'histogramme sera normalisé (somme des valeurs égale à 1).
  • Calculer les histogrammes de couleurs pour toutes les images de la collection. Stocker le résultat dans un fichier binaire.
  • Calculer les distances entre l'histogramme de l'image requête et les histogrammes de couleurs pour toutes les images.
  • Trier les images de la collection en fonction de leur distance à l'image requête et afficher les 10 plus proches.

Tri :

  • Pour le tri, il faut conserver la relation entre la distance calculée et la référence de l'image correspondante. On utilise pour cela un tableau de structures contenant le numéro de l'image et la distance correspondante. Voir proc.h (structure KEY).
  • On peut utiliser la fonction C standard qsort() (voir le man) pour trier le tableau de structures. Utiliser la fonction keyCompare() de proc.c.

Affichage des résultats :

  • Sans passer pa un CGI, il est possible de visualiser les résultats de la recherche dans une page HTML. Il suffit pour cela d'encapsuler les URL des images avec des balises <IMG SRC=“…”> et de rediriger la sortie du programme vers un fichier out.html qu'il n'y a plus qu'à charger dans un navigateur.

4.2. Deuxième partie: recherche par mots visuels.

4.2.1. Calcul de SIFTs locaux (programme ou résultats fournis)

Il existe des approches qui permettent d'extraire des carcatéristiques visuelles, basées sur des informations localisées autour d'un point d'une image. Ces approches proposent également des manières de déterminer autour de quel point travailler et également à quelle distance autour du point effectuer l'extraction de caractéristique.

L'approche SIFT (pour Scale Invariant Feature Transform) et une approche qui donne de très bons résultats. Il existe quelques programmes qui réalisent cette extraction, comme par exemple colorDescriptor de Koen van de Sande (vous pouvez regarder cela en dehors du TP). Comme ce programme est assez lent (quelques secondes par image…). Nous vous proposons d'utiliser les fichiers générés par ce programme comme source pour votre travail.

L'exécutable Linux 64-bits de colorDescriptor est disponible dans http://mrim.imag.fr/HMUL8R6B/PROJET/colorDescriptor.<br> L'exécutable MacOS de colorDescriptor est disponible dans http://mrim.imag.fr/HMUL8R6B/PROJET/colorDescriptor-mac.<br>

Pour obtenir le fichier sift correspondant à ceux déjà extraits, il faut utiliser la commande :

colorDescriptor --descriptor sift sample.jpg --output sample.sift

Une difficulté de ces approches est qu'il n'y a pas un nombre prédéfini de caractéristiques extraites pour chaque image (à l'inverse de ce qui se passe pour les histogrammes de couleurs vous avez calculés). Il faut alors avoir recours à une étape de clustering (point suivant).

Le programme de Koen van de Sande génère une liste de caractéristiques à 128 dimensions, selon le format suivant :

KOEN1
128
< entier : nb de caractéristiques extraites >
(< ligne de caractéristiques >)*

avec une ligne de caractéristiques telle que :

<CIRCLE <entier> <entier> <réel> <entier> <réel>>;entier (entier)*;

Par exemple :

<CIRCLE 159 154 1.78381 0 0.000296159>; 0 0 31 20 8 0 0 0 0 2 13 13 2 0 10 10 0 4 22 2 0 7 32 4 0 2 18 3 1 4 12 0 7 0 0 6 16 0 0 3 99 7 0 1 2 1 59 140 22 4 0 0 0 100 140 69 0 0 0 0 0 44 140 11 11 4 0 6 16 0 0 0 140 140 19 0 1 0 6 33 56 114 140 15 1 35 75 22 0 8 140 16 1 15 116 9 0 1 0 4 14 0 0 0 10 62 28 1 1 0 0 0 1 39 140 7 0 0 0 0 8 3 140 7 0 0 5 18;

qui veut dire que dans la région de centre (159,154) une caractéristique à été extraite à une échelle 1,78381 avec une orientation de 0 et un degré de visibilité de 0.000296159.

Afin de pouvoir utiliser ces caractéristiques pour le clustering, il faut les mettre en forme, c'est-à-dire éliminer les informations autres que les caractéristiques elles-mêmes. Pour cela, on élimine les entêtes (les 3 premières lignes d'un fichier généré par colorDescriptor), on enlève aussi la partie “tag” des lignes de caractéristiques, sans oublier d'enlever les “;”. TRES IMPORTANT : une ligne ne doit pas se terminer par un espace (le retour charriot doit être juste après la dernière dimension).

Il vous est donc demandé de créer, pour chaque fichier sift de l'ensemble test fourni en /home/Public/quenotg/HMUL8R6B/PROJET/test/sift/, les fichiers nettoyés en ne gardant qu'une ligne sur 150. Il vous est demandé d’éviter de générer toutes les lignes pour des raisons de place occupée sur disque.

Le problème avec le compte quenotg à l'UFR a été réglé et les données sont maintenant accessibles comme elles le devraient, il faut par contre utiliser un chemin différent : /home/Public/quenotg/HMUL8R6B/PROJET.

Ensuite, vous aller concaténer tous ces fichiers (rappelons que ces fichiers ne contiennent qu'une ligne de caractéristiques toutes les 150 par exemple) afin de créer un fichier samples.txt qui n'a pas trop d'échantillons (plus le nombre d'échantillons est grand, plus le clustering va nécessiter de la mémoire et plus le traitement sera long, jusqu'à… plusieurs jours, et des dizaines de GB…). C'est ce fichier qui va être utiliser pour le clustering.

4.2.2. Calcul de sacs ds SIFT - Clustering

L'objectif du fichier samples.txt est de générer des regroupements (clusters) on en fixe a priori le nombre. Pour cela, nous allons utiliser le logiciel R

R est un environnement gratuit pour des calculs statistique. Il permet en particulier de réaliser du clustering automatique.

Nous vous fournissons ici les instructions R qui permettent de réaliser un clustering de type Kmoyennes (Kmeans en anglais). Pour cela, vous devez récupérer le code kmeans_clustering.R, et de l'utiliser de la manière suivante :

R --slave --no-save --no-restore --no-environ --args ./samples.txt 256 ./centers256.txt 10 < kmeans_clustering.R

Cet appel indique que l'on utilise R en mode non interactif, avec pour arguments : le fichier samples.txt, le nombre de clusters attendu (ici 256), le fichier qui va stocker les centroïdes des clusters, et enfin le nombre d'itérations pour le clustering (ici 10).

Le résultat de cet appel est donc la génération des centroïdes de chaque cluster. Cette étape est longue et peut prendre 10 minutes pour s'éxécuter, évitez donc de le lancer plusieurs fois. Il faut ensuite passer en revue chaque caractéristique visuelle extraite pour lui assigner son cluster, c'est l'objectif de l'étape suivante : le mapping.

NOTE : R n'est pas installé sur toutes les machines de l'ufr. Il est installé sur mandelbrot, vous devez donc vous connecter sur mandelbrot pour l'utiliser..

4.2.3. Calcul de sacs ds SIFT - Mapping

Le mapping consiste à déterminer, pour chaque caractéristique visuelle extraite, le cluster qui lui correspond (dont le centroide est le plus proche.

Pour cela, nous allons encore faire appel à R, avec le code qui vous est fourni en 1nn.R. Le nom 1nn vient du fait que l'on trouve, pour une caractéristique le plus proche voisin, c'est-à-dire le “One Nearest Neighbour” (1nn). Ce code appelle R et lui demande, pour chaque élément d'une liste de caractéristriques, de renvoyer l'identifiant du cluster auquel il est rattaché. NOTE : le numéro de cluster commence à 1.

Un utilisation type de ce code est :

R --slave --no-save --no-restore --no-environ --args centers256.txt 256 all_for_R_demo_30 res1nn.txt < 1nn.R

qui indique que R attend le fichier de centroïdes (généré précédemment), qu'il travaille sur 256 dimensions (clusters), qu'il doit s'appliquer sur un fichier appelé ici all_for_R_demo_30 et mettre de résultat dans le fichier res1nn.txt. Bien entendu, les noms de fichiers sont indicatifs.

Pour un fichier de caractéristiques composé de 3 lignes:

0 0 1 0 0 0 0 0 0 0 0 1 13 1 0 0 1 0 0 0 41 8 3 4 6 8 1 6 74 1 0 0 1 28 29 12 2 3 2 0 8 9 48 34 40 14 4 4 8 2 2 3 172 94 74 19 65 29 4 16 172 109 9 14 0 9 11 8 7 35 31 2 26 11 23 16 11 32 41 49 23 3 2 9 169 64 18 30 38 0 0 1 172 172 132 73 1 14 33 9 2 6 9 2 6 13 49 17 0 5 13 11 9 10 15 13 33 24 7 7 0 0 5 7 27 77 107 20
2 0 0 0 2 0 0 2 14 3 1 0 0 0 3 26 14 17 29 28 10 0 0 4 0 0 3 20 17 0 0 0 57 1 0 4 5 0 0 21 119 18 10 6 20 43 40 119 21 35 119 119 96 65 12 13 0 0 23 83 35 2 0 0 70 21 0 1 14 15 4 3 119 119 106 21 32 30 11 27 16 38 62 43 119 119 39 6 1 0 1 3 8 108 23 1 6 9 1 4 36 23 5 0 14 59 70 2 0 1 1 0 119 119 41 11 6 41 25 12 25 20 17 52 83 119 26 9
9 22 23 10 0 0 0 0 21 23 24 20 2 0 0 0 5 7 12 46 28 1 1 0 0 0 0 2 10 4 9 16 60 61 99 87 27 0 0 10 115 115 115 115 9 0 0 6 58 43 92 115 52 8 29 21 17 9 2 30 45 36 84 83 44 27 14 81 38 1 1 7 85 51 31 81 26 0 0 11 73 115 31 71 17 0 3 8 28 111 25 56 78 25 10 7 2 1 0 6 12 6 115 90 0 3 22 34 20 3 19 71 0 8 43 17 14 1 0 78 0 12 51 32 43 12 3 49 0

Le résultat généré est de la forme :

189
101
146

Qui indique que la première caractéristique est assignée au cluster numéro 189, la seconde au cluster 101 et la troisième au cluster 146.

Vous devez donc, à partir du fichier de caratéristiques de chaque image de test, générer le fichier de mapping et le stocker.

Pour simplifier votre problème, nous vous fournissons le code (shell script) qui permet de génerer les fichiers de mapping en process_1nn_sift.sh. Ce code suppose que :

  • vous avez dans le répertoire le fichier 1nn.R,
  • que vous avez une hiérarchie sift/test/1nn à partir du répertoire courant,
  • et que le fichier de centres s'appelle centers256.txt .

Vous pouvez changer cela en éditant ce fichier.

Le fichier résultat est une liste des numéros des centres de cluster les plus proches. Il y en a un par image. Il faut ensuite faire un histogramme par image de ces numéros de centres, ces numéros étant les catégories.

Ensuite, tout se passe comme avec les histogrammes de couleur.

4.3. Troisième partie: recherche combinée.

La recherche combinée s'effectue en fusionnant les valeurs des distances selon la couleur et selon les mots visuels. La fusion peut être effectuée soit par une moyenne, éventuellement pondérée, soit par un opérateur maximum entre les deux distances. Avant le moyennage ou l'application de l'opérateur maximum, il convient de normaliser les distances par modalité (couleur ou texture). La normalisation peut se faire au niveau des descripteurs avant le calcul de la distance en divisant tous les descripteurs (requête et images de la base) par la norme moyenne des descripteurs des images de la base.

5. Évaluation du projet

Vous devrez faire un compte rendu et fournir les codes sources de vos programmes et les différents scripts que vous utilisez pour les lancer. Vous enverrez le compte-rendu et les sources (pas les fichiers de données) dans une archive zip ou tgz pour le 21 avril au plus tard (Georges.Quenot@imag.fr). Vous montrerez ce qui tourne lors de la séance du 7 avril.

Le compte rendu doit comprendre une très courte introduction expliquant quel est le problème que votre système traite, l'organisation logicielle globale de votre système, comment vous avez implémenté les différents éléments (vous pouvez en choisir un en particulier que vous détaillez), et des exemples de résultats obtenus illustrant les capacités du système et en montrant des cas où il fonctionne de manière satisfaisante et d'autre où il fonctionne moins bien. Ne reproduisez pas le sujet et n'incluez pas le code et les scripts dans le compte rendu, à l'exception éventuelle d'extraits courts.

ancien.txt · Last modified: 2018/03/16 06:18 by quenot
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki