Reconnaissance de Forme
Reconnaissance de Forme
La reconnaissance de chiffre à l'aide de l'algorithme des K plus proche voisin est un exemple standard.
Malheureusement pour nous, cela reste un exercice difficile. Nous allons donc nous intéresser à la reconnaissance de forme géométrique.
Dans cet exercice, on va donc chercher à reconnaître des formes géométriques.
Une question de distance
Dans le cours, nous avons vu que les K-plus proche voisins fonctionnent sur la notion de proximité entre différents éléments dans notre système.
Mais lorsque l'on parle d'image et de forme géométrique, quelle peut bien être la distance que l'on sait mesurer et qui nous intéresse.
Question
Sachant que les formes sont déjà isolées, proposez des critères facilement mesurables pour définir une distance.

Présentation de 4 formes simples (un triangle, un carré, un rectangle, un cercle)
Chacune indépendante des autres
Chaque image est un contour noir sur un fond blanc, comme dans l'image ci-contre.
Solution
Élancement et Circularité
On va s'intéresser à deux grandeurs que l'on peut facilement mesurer.
L'élancement : C'est le ratio entre la largeur et la hauteur du rectangle qui encadre au plus proche notre figure.
Par exemple :
Pour un carré, c'est 1, en effet le rectangle englobant le plus petit et le carré lui même et a donc ses cotés égaux
Pour le cercle, c'est 1 aussi, le rectangle englobant est le carré circonscrit
Pour le rectangle, c'est variable mais toujours inférieur à 1, sinon c'est un carré
Pour le triangle, c'est encore plus variable
La circularité : C'est le ratio entre l'aire et le carré du périmètre (multiplié par \(4\pi\), pour normaliser).
Par exemple :
Pour le carré, c'est toujours \(\pi/4\) = 0.78
Pour le cercle, c'est toujours 1
Pour le rectangle, c'est proche de 0.65
Pour le triangle, c'est proche de 0.39
La manipulation d'image
Manipuler des images peut être compliqué et très coûteux en temps de calcul.
C'est pourquoi on vous fourni un binaire qui permet de faire le traitement d'image rapidement et un script python pour l'utiliser.
Créez un dossier et téléchargez ce fichier dedans
Téléchargez ce fichier dans le même dossier et retirez l'extension .out
Le code de ce programme peut être trouver sur la forge
Si lors de l'import de analyse_image.py, vous avez un problème d'exécution, vérifier que vous avez bien les droits d'exécution sur le fichier binaire.
chmod u+x analyse_forme
Des données
Le module analyse_image.py fourni une fonction donnees.
Cette fonction fourni une liste de dictionnaires dont le format est donné ci-après.
{"fichier": "<nom du fichier>",
"forme": "<la forme ou mystere>",
"elancement": <l elancement>,
"circularite": <la circularité>,
}
Les valeurs pour fichier et forme sont des strings, et pour elancement et circularite, des flottants.
Une distance
On va repérer nos images dans un plan 2D, tel que :
L'abscisse est l'élancement
L'ordonnée est la circularité
On utilisera alors la distance euclidienne naturelle dans cet espace.
Question
Implémentez, une fonction distance, telle que :
Entrée :
image1: Un dictionnaire représentant une analyse
image2: Un autre dictionnaire représentant une analyse
Sortie : la distance euclidienne
Indice
On rappelle la formule de la distance euclidienne : \(distance(A, B)=\sqrt{(x_A-x_B)^2+(y_A-y_B)^2}\)
Indice
Il faut importer la fonction sqrt depuis le module math :
from math import sqrt
# Utilisation :sqrt(4) # 2
Indice
Nos valeurs A et B dans la formule s'appliquent de cette façon :
\(x_A \rightarrow\)
image1['elancement']\(x_B \rightarrow\)
image2['elancement']\(y_A \rightarrow\)
image1['circularite']\(y_B \rightarrow\)
image2['circularite']
Question
Implémentez, une fonction plus_proche, telle que :
Entrée :
image: Un dictionnaire représentant une analyse
k: un entier strictement positif, qui est le paramètre de K-PPVassociation: un liste de dictionnaire dont on connait déjà la forme
Sorties : Une liste contenant les
kdictionnaires les plus proches deimage.
On propose l'algorithme suivant :
Stocker, dans une liste
distances, les couples (distance, indice), tels que :distanceest la distance entreimageetassociation[indice]
Cette liste va nous permettre de trouver plus efficacement les
kplus prochesTrier la liste
distances. Comment trier rapidement ?Cela fonctionne car lorsqu'on trie une liste de tuples, le tri va se faire en priorité sur le premier élément du tuple (ici sur la distance). Ingénieux !
Parcourir les
kpremiers éléments de la liste distances et créer la liste deskplus prochesImage
Indice
On souhaite obtenir une liste qui ressemble à cela :
distances = [(0.3, 0), (0.2, 4)]
Cette liste a deux éléments :
Le premier est l'
Imageen indice 0 deassociation, située à distance0.3deselfLe second est l'
Imageen indice 4 deassociation, située à distance0.2deself
Pour y parvenir, il faut :
parcourir toutes les adresses de association (par exemple avec
for i in range(len(association)):) ;calculer la distance
davec la méthodedistance;l'ajouter dans la liste
distancessous la forme(d, i)
Indice
Il suffit de parcourir les indices de 0 à k (exclu) en utilisant la boucle FOR et range(k).
Si on utilise i comme variant de notre boucle for, on peut ensuite récupérer l'indice du voisin avec distances[i][1].
Pourquoi 1 ? Parce-que
distances[i]est un tuple qui contient comme premier élément la distance, et comme deuxième élément l'adresse.
On approche de la fin
Il ne nous reste plus qu'à faire le choix de la bonne forme.
Question
Implémentez, une fonction forme_kppv, telle que :
Entrée :
image: Un dictionnaire représant un analyse d'image
k: un entier strictement positif, qui est le paramètre de K-PPVassociation: un liste de dictionnairedont on connait déjà la forme
Sorties : La forme la plus probable pour
image.
On propose l'algorithme suivant :
Exécuter la fonction
plus_proche, pour obtenir leskplus proches voisinsCréer une liste (
formes) des formes des plus proches voisinsUtiliser
max(formes, key=formes.count), pour trouver la forme la plus probable.
Indice
On peut obtenir la valeur la plus fréquente dans une liste grâce à max(formes, key=formes.count). Pourquoi ?
La fonction
max()renvoie la valeur la plus grande dans une liste (ex :max([2,5,3])renvoie 5).Le paramètre
key=permet de préciser une fonction a utiliser sur chaque élément avant de le comparer aux autres.La fonction
formes.countrenvoie le nombre d’occurrences d'un élément passé en paramètre.Les parenthèses ne sont d'ailleurs pas présentes car on ne veut pas donner à
max()le résultat de la fonction, mais le nom de la fonction qu'il devra utiliser.
Donc la fonction max() regarde le nombre d’occurrences de chaque élément, et pour celui dont cette valeur est la plus élevée, va renvoyer sa valeur.
Question
Évaluez la qualité de votre algorithme.
Pour cela vous pouvez utiliser la fonction mysteres fournis par analyse_image.py qui vous donne accès à une liste d'images dont on ne connait pas la forme.
Indice
On remarquera que la forme n'est pas un si grand mystère et est présente dans le nom du fichier.
Pour les plus rapides
Si vous avez tout terminé, bravo ! Le reste des exercices n'est que du bonus, et n'est pas à connaître. Il s'agit de trois questions bonus :
La première consiste à agrandir notre ensemble de donnée ;
La deuxième consiste à essayer de distinguer plus de forme ;
La troisième consiste à essayer de distinguer des formes manuscrites.
Plus de données
Notre ensemble de données sûres n'est que de 100 images.
Il serait sage d'utiliser plus d'images.
Question
En étudiant le code du script python, trouvez la ligne qui vous permettra d'avoir un dataset plus grand.
Modifiez la ligne de façon à avoir un dataset de 2 000 images.
Plus de forme
Pour l'instant on reconnait les triangles, carrés, cercle et rectangle.
On aimerait en reconnaître plus.
Question
En utilisant la documentation intégré à analyse_forme, générez des ovales.
Indice
Les commandes :
./analyse_forme -h./analyse_forme generate -h
Permettent d'obtenir plus d'information sur le fonctionnement du programme.
Des formes manuscrites
On s’intéresse à reconnaître des images dessinées à la main.
Question
Dessinez à la règle l'équerre et le compas des formes et prenez les en photos et exécutez le programme dessus.
Question
Essayez la même chose mais avec des formes à main levée sur Gimp.