Traitement d’images pour la d√©tection de tag Aruco ūüĆĪ avec OpenCV en Python : 1/4

Généralités

L’objectif de ce cours est de r√©soudre le probl√®me de d√©tection de tag Aruco embarqu√© sur un Raspberry Pi. √Ä travers ce cours nous verrons trois notions : le traitement d’image (classique et par IA) et la mani√®re dont nous pouvons l’utiliser (OpenCV), les tag Aruco ainsi que le principe des API.

Diapositives du cours

Présentation du cours et prérequis

  1. Mardi 15 f√©vrier : Pr√©sentation du cours, introduction au traitement d’image
  2. Mardi 15 mars : Introduction √† OpenCV ūüíĽ
  3. Mardi 22 mars : D√©tection de tag Aruco ūüíĽ
  4. Mardi 29 mars : Embarquement sur Raspberry Pi et API ūüíĽ

Les cours 2, 3 et 4 n√©cessitent d’avoir un environnement Python 3.x install√©. Les cours 3 et 4 seront plus simple sous Linux.

Programme du cours

  1. Présentation du cours (30 minutes)
  2. Traitement d’images classique (45 minutes)
  3. Traitement d’images par intelligence artificielle (45 minutes)

Am√©liorer l’aspect visuel de vos images

Le traitement d’images d√©signe l’ensemble des techniques permettant de modifier une image, souvent dans le but de l’am√©liorer. Par exemple, il est possible de la rendre plus lumineuse ou plus nette. Cette discipline se situe √† la crois√©e des math√©matiques appliqu√©es et de l’informatique, c’est pourquoi nous nous int√©resserons d√©sormais √† la d√©finition d’une image dans ces deux domaines.

Repr√©sentation d’une image

Qu’est qu’une image ? Cette question simple admet en r√©alit√© plusieurs r√©ponses, plus ou moins techniques selon le domaine √©tudi√©. Commen√ßons par donner la r√©ponse qui vient naturellement √† la majorit√© d’entre nous : une image est une repr√©sentation visuelle de quelque chose ou de quelqu’un.

Lena, l’exemple canonique du traitement d’images

L’image vue comme une fonction math√©matique

En math√©matiques, une image est une fonction. Cette fonction quantifie l’intensit√© lumineuse de n’importe quel point dans l’image. Dans une image en noir et blanc, l’intensit√© est le niveau de gris : plus un point est sombre, plus son niveau de gris est fiable.

Dans le cas d’une image en couleurs, l’intensit√© d’un point d√©signe sa couleur. Celle-ci peut √™tre per√ßue comme un m√©lange de trois couleurs primaires (rouge, vert, bleu). Ainsi, une image ne correspond non plus √† une seule fonction, mais √† trois : nous associons √† chaque point son intensit√© de rouge, de vert et de bleu. Ces trois valeurs sont stock√©es dans un vecteur colonne de taille trois, de sorte que l’image puisse √™tre repr√©sent√©e comme une fonction vectorielle.

En traitement d’image, il n’est pas possible de se contenter de d√©finir une image comme “quelque chose que l’on voit et qui repr√©sente une information”. En effet, comme nous allons le voir, la modification d’une image fait intervenir des op√©rations math√©matiques. Celles-ci sont formul√©es de mani√®re beaucoup plus intelligible et pr√©cise si l’on consid√®re l’objet auquel elles s’appliquent.

L’image num√©rique

Le traitement d’images fait intervenir des outils non seulement issus des math√©matiques appliqu√©es, mais aussi de l’informatique. La d√©finition math√©matique d’une image ne convient pas √† un ordinateur : des restrictions doivent √™tre impos√©es sur les ensembles de d√©finition et d’arriv√©e de la fonction.

Dans notre d√©finition math√©matique, l’abscisse, l’ordonn√©e et l’intensit√© d’un point donn√© de l’image peuvent prendre n’importe quelle valeur r√©elle. C’est pourquoi nous parlons de mod√®le continu ou d’image analogique.

Une image en informatique est ainsi une discr√©tisation (ou num√©risation) de notre mod√®le continu : nous l’appelons image num√©rique. Cette discr√©tisation se fait √† la fois sur l’ensemble de d√©finition de la fonction image (√©chantillonnage) et sur son ensemble d’arriv√©e (quantification)

Une image num√©rique est une image √©chantillonn√©e et quantifi√©e. La d√©finition formelle d’une image num√©rique en noir et blanc est donc la suivante

\(I : \{0,1,…,w-1\} \times \{0,1,…,h-1\} \rightarrow \{0,1,…,255\}\)

L’ordinateur traite une image comme une matrice d’entiers de taille \(h \times w\) contenant les niveaux de gris de ses pixels.

Notons que si cette repr√©sentation est la plus courante pour afficher une image, la lire ou l’√©crire dans un fichier, nous travaillerons g√©n√©ralement sur des images sans quantification et nous n’appliquerons la quantification qu’√† la fin.

Premiers traitements d’images

Nous abordons ici les techniques de traitement d’images bas√©es sur la modification d’histogrammes. Ces m√©thodes font partie de la classe des traitements dits ponctuels : la valeur de chaque pixel est corrig√©e, et ce, ind√©pendamment des autres pixels.

Manipulation d’histogrammes

L’histogramme d’une image num√©rique est une courbe statistique repr√©sentant la r√©partition de ses pixels selon leur intensit√©. Pour une image en noir et blanc, il indique en abscisse le niveau de gris (entier entre 0 et 255) et en ordonn√©e, le nombre de pixels ayant cette valeur.

Lorsque l’histogramme est normalis√©, il indique en ordonn√©e la probabilit√© \(p_i\) de trouver un pixel de niveau de gris \(i\) dans l’image. L’intensit√© d’un pixel est alors vue comme une variable al√©atoire discr√®te. Un histogramme cumul√© normalis√© calcule le pourcentage de pixels ayant une valeur inf√©rieure √† un niveau de gris donn√©.

import cv2
import matplotlib.pyplot as plt
# load simba image
simba = cv2.imread('data/simba.png', cv2.IMREAD_GRAYSCALE)
# compute hist of simba.png
hist = cv2.calcHist([simba], [0], None, [256], [0, 256])
f, plot = plt.subplots(1, 2)
plot[0].imshow(simba, cmap='gray')
plot[1].plot(hist)
plt.show()
L’image et son histogramme

Il s’agit d’un outil tr√®s important en traitement d’images, car sa modification permet d’ajuster la dynamique des niveaux de gris ou des couleurs dans une image afin de la rendre plus agr√©able visuellement. Grossi√®rement, √† gauche se situent les pixels noirs et √† droite les pixels blancs.

Une premi√®re application consiste √† corriger la luminosit√© ou exposition, de l’image. Analysons la forme des histogrammes pour des images dont l’exposition est mauvaise

Vous pouvez constater que pour l’image trop sombre, ou sous-expos√©e, la majorit√© des pixels se situent dans la partie gauche de l’histogramme, vers les valeurs de niveaux de gris faibles.

En revanche, l’histogramme associ√© √† l’image dont l’exposition est relativement bonne pr√©sente une r√©partition des pixels sur tout l’intervalle. Ainsi pour corriger les d√©fauts li√©s √† l’exposition d’une image, il suffit d’√©tirer son histogramme.

Cette transformation se fait simplement √† l’aide de la r√®gle de trois : la valeur de chaque pixel est remplac√©e par le r√©sultat de la formule ci-dessous.

\(I'(x,y) = \frac{255 \times (I(x,y) – I_{min})}{I_{max}-I_{min}}\)

La deuxi√®me application courante concerne l’am√©lioration du contraste de l’image.

Le contraste caract√©rise la r√©partition de lumi√®re dans une image : plus une image est contrast√©e, plus la diff√©rence de luminosit√© entre ses zones claires et sombres est importante. En g√©n√©ral, une image peu contrast√©e est terne, tandis qu’une image trop contrast√©e est visuellement “agressive”. Dans les deux cas, l’image manque de clart√© car certains de ses d√©tails seront peu, voir pas du tout, visibles.

L’√©galisation d’histogrammes est une technique simple permettant de r√©ajuster le contraste d’une image et ainsi de lui redonner du peps ou de l’adoucir. Pour comprendre de mani√®re intuitive le fonctionnement de ce traitement, √©tudions l’allure de l’histogramme pour des images peu ou trop contrast√©es.

Notre image avec peu de contraste et son histogramme
Notre image avec trop de contraste et son histogramme

Comme nous pouvons le constater, les pixels des images dont le contraste est mauvais se r√©partissent dans tout l’intervalle disponible, donc un √©tirement d’histogramme n’am√©liora rien, mais pas de mani√®re √©quitable.

L’objectif est donc d’harmoniser la distribution des niveaux de gris de l’image, de sorte que chaque niveau de l’histogramme contienne id√©alement le m√™me nombre de pixels. Concr√®tement, nous essyons d’aplatir au maximum l’histogramme original.

Pour cela nous calculons d’abord l’histogramme cumul√© normalis√© de l’image, puis nous ajustons la valeurs de chaque pixel en utilisant la formule math√©matique suivante :

\(I'(x,y) = 255 \times \sum \limits_{i=0}^{I(x,y)} p_i\)

o√Ļ \(p_i\) d√©signe la probabilit√© qu’un pixel de l’image initiale soit d’intensit√© \(i\).

L’√©galisation d’histogramme se fait avec la fonction cv2.equalizeHist du module OpenCV en python.

√Člimination du bruit

La qualit√© d’une photo peut √©galement √™tre d√©grad√©e par du bruit num√©rique, c’est-√†-dire par l’apparition al√©atoire de grains superflus. Il s’agit d’un ph√©nom√®ne courant en photographie num√©rique, d√Ľ √† un mauvais r√©glage de la sensibilit√© des capteurs de l’appareil photo, ou √† une limitation de leurs capacit√©s.

Le bruit peut être vu comme une image constituée de pixels dont les intensités ont été déterminées de manière aléatoire.

Une image √©tant d√©finie soit comme une fonction, soit comme une matrice, nous pouvons appliquer des op√©rations math√©matiques usuelles, comme l’addition. Ainsi, nous parlons de bruit additif lorsque l’image bruit√©e est la somme de l’image originale et du bruit.

Un exemple très classique du bruit additif est le bruit gaussien, pour lequel les intensités sont choisies aléatoirement selon une loi normale.

Filtrer une image

Le filtrage constitue un volet important en traitement d’images, et un de ses objectifs principaux est de nettoyer l’image en √©liminant le plus de bruit possible. Dans ce chapitre, nous allons nous int√©resser davantage √† cette classe de m√©thodes, et en particulier √† la notion de filtre lin√©aire

Les filtres linéaires

Il existe diff√©rentes techniques de filtrage selon le type de bruit √† att√©nuer. Le lissage par moyennage utilise un filtre lin√©aire et fait partie, en ce sens, de la classe de filtrage la plus simple.

En traitement d’images, et m√™me plus g√©n√©ralement en traitement du signal, un filtre lin√©aire est un syst√®me qui transforme une image en utilisant un op√©rateur lin√©aire. Il s’agit g√©n√©ralement d’un traitement local.

Une propri√©t√© importante d’un filtre lin√©aire est l’invariance par translation : la modification d’un pixel d√©pend de son voisinage, et non de sa position dans l’image.

Le lissage par moyennage utilise bien un filtre lin√©aire, appel√© filtre moyenneur. En effet, l’op√©ration appliqu√©e √† l’image initiale de repr√©sentation matricielle X pour obtenir l’image d√©bruit√©e Y est compos√©e d’additions et d’une division.

L’op√©rateur de convolution

Un filtre lin√©aire remplace la valeur de chaque pixel en entr√©e par une combinaison lin√©aire des intensit√©s de ses pixels voisins. L’op√©rateur permettant d‚Äôeffectuer cette transformation est appel√© produit de convolution. C’est pourquoi l’application d’un filtre lin√©aire est √©galement connue sous le terme de filtrage par convolution

En notant \(\ast\) l’op√©rateur de convolution, la relation math√©matique entre l’image initiale X et l’image filtr√©e Y pour tout type de filtre lin√©aire s’√©crit \(Y=H\ast X \).  Cela revient √† modifier la valeur de chaque pixel de la mani√®re suivante :

\(Y_{ij} = \sum \limits_{u=_k}^k \sum \limits_{v = -k}^k H_{u,v} X_{i-u, j-v}\)

\(H\) est le noyau de convolution : il s’agit d’une matrice carr√©e de taille impaire qui cract√©rise le filtre lin√©aire appliqu√©.

Pour les bords de l’image, nous appliquons une convolution partielle avec les pixels voisins disponibles. Dans tous les cas, il est pr√©f√©rable de ne pas r√©duire la taille de l’image.

D√©tecter et d√©crire efficacement les zones d’int√©r√™ts dans une image

Si vous tapez “Tour Eiffel” dans votre moteur de recherche d’images pr√©f√©r√©, vous constaterez que les r√©sultats repr√©sentent la m√™me sc√®ne, mais de mani√®res diff√©rentes. Beaucoup d’√©l√©ments peuvent varier d’une photo √† une autre :

  • La prise de vue (r√©sultat d’une transformation affine ou d’une projection)
  • L’orientation (r√©sultat d’une rotation)
  • L’√©chelle (r√©sultat d’un zoom)
  • Les propri√©t√©s photom√©triques : la luminosit√© et/ou le contraste (variations dues aux moments diff√©rents de la journ√©e, m√©t√©o, flash…)
  • Occlusion : une partie de l’image est cach√©e
  • Background clutter : une partie de l’image se confond avec les √©l√©ments en arri√®re-plan

Notion de point d’int√©r√™ts

Dans la premi√®re partie de ce cours, nous avions √©tudi√© diff√©rentes techniques permettant de transformer une image en une autre. Parmi elles, il y avait les transformations g√©om√©triques, qui modifient la position des pixels, et les manipulations d’histogrammes, qui corrigent la luminosit√© et le contraste.

Deux images d’une m√™me classe, c’est-√†-dire qui repr√©sentent la m√™me chose, sont donc li√©es par une transformation. Cependant, la caract√©risation pr√©cise de cette transformation nous est inconnue.

Comment d√©terminer la transformation qui permet de passer d’une image √† une autre ? 

Il s’agit en fait d’un probl√®me classique en vision par ordinateur, appel√© image matching. Les applications sont nombreuses : parmi elles, la cr√©ation de panoramas, la d√©tection d’images similaires √† une autre (visual search), ou encore la reconnaissance d’objets dans une image (object recognition).

Au lieu de chercher √† d√©terminer l’√©quation math√©matique pr√©cise de la transformation comme dans la partie pr√©c√©dente, la strat√©gie consiste √† trouver les √©l√©ments communs aux deux images. La probl√©matique est alors reformul√©e ainsi :

Quels sont les √©l√©ments caract√©ristiques de l’image 1 ? Les retrouve-t-on dans l’image 2 ?  

Cette t√Ęche est plus ou moins triviale pour notre cerveau, mais difficile pour un ordinateur : celui-ci doit parvenir √† d√©crire la particularit√© d’une classe d’images, et ce, en d√©pit de toutes les variations possibles list√©es plus haut.

Le template matching avec les filtres

Dans la partie pr√©c√©dente, nous avons d√©couvert les filtres comme des outils capables de r√©duire le bruit dans une image. En fait, les filtres sont √©galement souvent utilis√©s pour retrouver des motifs particuliers dans une image. Ces motifs sont repr√©sent√©s par de petites images, appel√©es templates. La t√Ęche de template matching a pour but de retrouver des templates dans une image.

Le template matching r√©alis√© avec des filtres utilise l’op√©rateur de corr√©lation crois√©e (cross-correlation), not√© \(\otimes\) . Cet op√©rateur transforme l’image de repr√©sentation matricielle X en une nouvelle image Y de la fa√ßon suivante :

\(Y_{ij} = \sum \limits_{u = -k}^k \sum \limits_{v = -k}^k H_{u,v} X_{i+u, j+v}\)

Dans ce contexte, H est une petite image repr√©sentant le template √† retrouver. Concr√®tement, cette op√©ration revient √† faire glisser H sur l’image X, √† multiplier les pixels qui se superposent et √† sommer ces produits.

Ainsi, le template matching consiste √† calculer la corr√©lation crois√©e entre une image  X et un filtre dont le noyau H repr√©sente un template que l’on souhaite retrouver dans X.

La nouvelle image Y, appel√©e carte de corr√©lation, nous indique o√Ļ le template a √©t√© d√©tect√© : plus une r√©gion est claire (d’intensit√©s √©lev√©es), plus elle ressemble au template recherch√©.

Les features, ou zones d’int√©r√™t d’une image

En vision par ordinateur, le terme de (local) features d√©signe des zones int√©ressantes de l’image num√©rique. Ces zones peuvent correspondre √† des contours, des points ou des r√©gions d’int√©r√™t. A chaque feature d√©tect√©e est associ√© un vecteur, appel√© descripteur (feature descriptor ou feature vector), qui, comme son nom l’indique, d√©crit la zone concern√©e.

La r√©solution du probl√®me d’image matching se fait alors en deux √©tapes :

  1. D√©tecter et d√©crire les features dans chaque image
  2. Trouver les paires de features qui se correspondent dans les deux images (features matching)
Exemple d’image matching. Les features sont rep√©r√©es par les ronds.

L’algorithme d’image matching √©tudie des images caract√©ris√©es par leurs features, donc la qualit√© des r√©sultats d√©pend (entre autres) de la pertinence des features d√©tect√©es. En ce sens, la premi√®re √©tape est fondamentale et ne doit en aucun cas √™tre n√©glig√©e. 

Un mauvais choix de features peut entra√ģner plusieurs difficult√©s dans l’√©tape de matching features :

  • Probl√®me 1 : deux images n’ont pas les m√™mes features alors qu’elles repr√©sentent la m√™me chose de mani√®res diff√©rentes
  • Probl√®me 2 : ces deux images pr√©sentent les m√™mes features, mais trouver les paires qui se correspondent est tr√®s difficile

Ces deux probl√®mes rendent le matching impossible et doivent donc √™tre anticip√©s d√®s la premi√®re √©tape, lors de la d√©tection et la description de features. Cela nous am√®ne √† la question suivante : quelles features  faut-il s√©lectionner ?

  1. R√©p√©table : une feature doit se retrouver dans les images repr√©sentant la m√™me sc√®ne malgr√© les diff√©rences g√©om√©triques et photom√©triques. Une feature doit donc pr√©senter des propri√©t√©s d’invariance √† ces transformations.
  2. Distinctive : une feature  doit √™tre suffisamment unique et non ambigu√ę au sein d’une image pour faciliter le matching. Ce sont les informations contenues dans son descripteur qui doit mettre en valeur sa particularit√©.  
  3. Locale : une feature doit correspondre √† une zone suffisamment petite, et elle est d√©crite selon son voisinage uniquement. Cela permet d’√©viter les difficult√©s de matching dues aux ph√©nom√®nes d’occlusion et de background clutter.

En r√©sum√©, une bonne feature doit √™tre suffisamment unique pour pouvoir diff√©rencier deux classes d’images diff√©rentes, et suffisamment g√©n√©rique pour pouvoir reconna√ģtre facilement les images d’une m√™me classe malgr√© la diversit√© des repr√©sentations.

D√©tection des coins et des bords d’une images

Dans ce chapitre, nous expliquerons deux m√©thodes couramment utilis√©es pour d√©tecter des features classiques : le filtre de Canny pour les bords, puis le d√©tecteur de Harris-Stephens pour les coins. Pour cela, nous devons dans un premier temps √©tudier la notion de gradient d’une image.

La détection des bords avec le filtre Canny

Les bords ou contours (edges en anglais) fournissent beaucoup d’information √† propos d’une image : ils d√©limitent les objets pr√©sents dans la sc√®ne repr√©sent√©e, les ombres ou encore les diff√©rentes textures.

Un moyen pour d√©tecter les bords serait de segmenter l’image en objets, mais il s’agit d’un probl√®me difficile. Le filtre de Canny d√©velopp√© en 1986 est une solution plus simple, qui repose sur l’√©tude du gradient.

Les bords se situent dans les r√©gions de l’image qui pr√©sentent de forts changements. En effet, les contours des objets correspondent √† des changements de profondeur (on passe d’un objet √† un autre situ√© en arri√®re-plan), et les ombres et diff√©rentes textures √† des changements d’illumination.

Math√©matiquement, la d√©tection des bords revient donc √† chercher les points de l’image o√Ļ la fonction d’intensit√© II varie brusquement. Or, nous savons qu’une amplitude du gradient √©lev√©e indique un fort changement d’intensit√©. Le but est de chercher les maxima locaux de \(||\nabla I||\).

La méthode de détection des bords par le filtre de Canny comporte quatre étapes :

Etape 1. Réduction du bruit

Le bruit de l’image peut nous induire en erreur : les pixels aux valeurs aberrantes provoquent des forts changements d’intensit√© alors qu’ils n’appartiennent √† aucun contour.

L’image doit donc √™tre d√©bruit√©e au pr√©alable avec un filtre adapt√©. Comme √©tudi√© dans la premi√®re partie du cours, on utilisera un filtre gaussien pour √©liminer le bruit additif, et un filtre m√©dian pour le “poivre et sel” (tr√®s rare).

Etape 2. Calcul du gradient de l’image

Le gradient de l’image d√©bruit√©e est approxim√© par filtrage de convolution, le plus souvent avec les masques de Sobel.

Nous calculons ensuite l’amplitude et la direction du gradient en tout point de l’image

Les bords sont repérés par les points de forte amplitude.

Etape 3. Suppression des non-maxima

Les bords trouv√©s √† l’√©tape pr√©c√©dente sont trop √©pais. Pour les rendre plus pr√©cis, nous ne s√©lectionnons que les points pour lesquels l’amplitude du gradient est localement maximale dans sa direction.

Pour cela, on quantifie őė et on trouve les deux voisins de chaque pixel en suivant la direction de son gradient. 

Quantification de l'angle de la direction du gradient
Quantification de l’angle de la direction du gradient

Le pixel courant est retenu que si son amplitude est plus grande que celles de ses deux voisins.

Etape 4. Seuillage

Parmi les points s√©lectionn√©s dans l’√©tape pr√©c√©dente, nous ne retenons finalement que ceux dont l’amplitude du gradient est sup√©rieure √† un certain seuil.

Il est difficile de choisir la valeur d’un “bon” seuil. C’est pourquoi on privil√©gie le seuillage par hyst√©r√©sis, qui utilise deux seuils, not√©s \(s_{bas}\) et \(s_{haut}\)

Ce d√©tecteur est facile √† mettre en oeuvre, mais pr√©sente deux limitations majeures :

  • Le choix des param√®tres (variance du filtre gaussien et les deux seuils). Ils ont un impact tr√®s important sur le temps de calcul et la qualit√© des r√©sultats, mais il n’existe pas de m√©thode automatique pour d√©terminer les meilleures valeurs pour chaque image…
  • Les bords d√©tect√©s sont des points et pas des courbes, et il est difficile de “cha√ģner” les points.

La localisation des coins avec le d√©tecteur de Harris-Stephens

Les coins (corners en anglais) sont d’autres features riches en informations. Ils se situent dans les r√©gions o√Ļ l’intensit√© varie fortement dans au moins deux directions :

Exemple de coin. On voit bien que l'intensité varie brutalement dans plusieurs directions (vers le haut et vers la gauche)
Exemple de coin. On voit bien que l’intensit√© varie brutalement dans plusieurs directions (vers le haut et vers la gauche)

Le d√©tecteur de Harris-Stephens, d√©velopp√© en 1988, est une technique tr√®s populaire permettant de rep√©rer les coins dans une image. Il est bas√© sur le d√©tecteur de Moravec, qui exploite le gradient. 

Le d√©tecteur de Moravec permet de d√©terminer les changements d’intensit√© autour d’un pixel donn√©.

L’id√©e est de consid√©rer un voisinage centr√© en ce pixel de le d√©caler l√©g√®rement dans plusieurs directions, puis de calculer pour chaque d√©placement la variation d’intensit√©. Cela se traduit math√©matiquement par la fonction suivante :

\(E_{m,n}(u,v) = \sum\limits_{(x,y) \in W_{m,n}} [I(x+u, y+v) – I(x,y)]^2\)

Nous appliquons cette fonction dans les trois situations principales ci-dessous :

Détecteur de Moravec
Détecteur de Moravec

Situation 1 : la zone contient un coin, l’intensit√© change brusquement dans plusieurs directions, donc la fonction E prend de fortes valeurs dans ces directions

Situation 2 : la zone contient un contour, l’intensit√© change brusquement si on se d√©place horizontalement et tr√®s peu verticalement. Ainsi, E prend de fortes valeurs si on d√©place perpendiculairement au contour, et des faibles pour des d√©placements le long du contour. 

Situation 3 : pas de changement d’intensit√© : la r√©gion est uniforme. E prend alors de faibles valeurs dans toutes les directions 

Le pixel \((m,n)\) correspond √† un coin si la plus petite variation d’intensit√© autour de lui est maximale par rapport √† celle des autres pixels.

Le d√©tecteur de Harris-Stephens est une am√©lioration du d√©tecteur de Moravec. Il apporte trois modifications majeures : 

  1. La fenêtre carrée \(W_{m,n}\) centrée en \((m,n)\) est remplacée par une fenêtre gaussienne.
  2. \(I(x+u, y+v)\) est approximé par un développement de Taylor au voisinage de \((x,y)\)
  3. Les coins sont détectés selon un nouveau critère : les valeurs propres $\latex \lambda_1$ et $\latex \lambda_2$ de $M$
Détection des coins en fonction des valeurs propres
Détection des coins en fonction des valeurs propres

Trouver les valeurs propres de M peut √™tre fastidieux. Une alternative consiste alors √† analyser les valeurs de l’op√©rateur R :  \(R = det(M) – k.trace(M)^2\) avec \(k\) une constante choisie entre 0.04 et 0.06

Détection des coins en fonction de la valeur de R
Détection des coins en fonction de la valeur de R

La d√©tection des coins avec le d√©tecteur de Harris-Stephens se fait donc en quatre √©tapes :

Etape 1. Calcul de la matrice pour chaque pixel. Les d√©riv√©es partielles sont approxim√©es en filtrant l’image par convolution avec les masques de Sobel

Etape 2. Calcul de R pour chaque pixel

Etape 3. Seuillage de ROn s√©lectionne les pixels pour lesquels \(R>s\) , o√Ļ s est un seuil √† choisir

Etape 4. Suppression des non-maxima de R. Les coins correspondent aux maxima locaux de R : pour les trouver, on applique aux pixels s√©lectionn√©s la m√©thode d√©crite dans l’√©tape 3 du filtre de Canny

Utiliser les points d’int√©r√™ts pour classifier une image

La classification d’images est un probl√®me fondamental en vision par ordinateur, qui a de nombreuses applications concr√®tes. Le but est de construire un syst√®me capable d’assigner correctement une cat√©gorie √† n’importe quelle image en entr√©e. Un tel syst√®me exploite des algorithmes de Machine Learning issus de l’apprentissage supervis√©.  

La méthode de résolution

Le probl√®me de classification d’images est pos√© formellement de la mani√®re suivante :

  • Il y a K classes d’images possibles. L’ensemble \({0,1,…,K‚ąí1}\) d√©finit les labels des diff√©rentes classes (exemple : 0 = “oiseau” et 1 = “chien”)
  • Nous avons une collection de N images en entr√©e : \({X_i}_{i \in {1,…,N}}\)
  • Les classes des N images sont connues √† l’avance : chaque image Xi est √©tiquet√©e par \(y_i \in {0,1,…,K‚ąí1}\)
  • Le but est de classifier correctement une nouvelle image, dont on ne conna√ģt pas la classe : on veut trouver la bonne √©tiquette y‚Ä≤ de X‚Ä≤

Le schéma ci-dessous illustre la méthode utilisée pour résoudre ce problème :

Les trois étapes d'un algorithme de classification d'images
Les trois √©tapes d’un algorithme de classification d’images

Cr√©ation des bag-of-features

Comme son nom l’indique, un bag-of-features repr√©sente une image par un “sac” dans lequel on a mis ses features en vrac. Math√©matiquement, c’est un vecteur cr√©√© en deux temps : d’abord, on cr√©e les visual words”, puis on construit un histogramme. 

Cr√©ation des visual words

Le bag-of-words caract√©rise un document textuel par les mots qu’il a utilis√©s. Ici, les images sont caract√©ris√©es par les features trouv√©es lors de l’√©tape 1. 

N√©anmoins, s’il est possible de retrouver plusieurs mots strictement identiques dans deux documents, ce n’est pas le cas pour les images et les features. En effet, le crit√®re de r√©p√©tabilit√© nous dit qu’une feature peut se retrouver dans plusieurs images, mais les features sont toutes diff√©rentes lorsqu’on les compare pixel par pixel. Cela s’explique par les variations g√©om√©triques, photom√©triques, ou m√™mes dues aux apparences diff√©rentes d’un objet d’une classe (exemple : il y a plusieurs types d’oiseaux).

Ainsi, on obtient beaucoup de features, mais certaines repr√©sentent un m√™me √©l√©ment de fa√ßons diff√©rentes. Ces √©l√©ments qui se d√©clinent en plusieurs versions sont appel√©es des visual words. par analogie avec les donn√©es textuelles : les textes sont caract√©ris√©s par des mots, et les images par des mots visuels. 

Exemple de visual words. Chaque ligne représente plusieurs features représentatives d'un visual word (exemple : première ligne = aile d'avion)
Exemple de visual words. Chaque ligne repr√©sente plusieurs features repr√©sentatives d’un visual word (exemple : premi√®re ligne = aile d’avion)

Pour cr√©er le “dictionnaire” de visual words, il suffit d’appliquer un algorithme de clustering aux descripteurs de features construits √† l’√©tape 1, comme le k-means. Les visual words correspondent alors aux centres des clusters trouv√©s.

Création des visual words par clustering des descripteurs
Création des visual words par clustering des descripteurs
Construction de l’histogramme

Il reste √† d√©crire les images en fonction de ces visual words. Pour chaque image, on cr√©e un histogramme qui indique la fr√©quence d’apparition de chaque visual word dans l’image :

Une image et son histogramme indiquant la fréquence d'apparition de chaque visual word
Une image et son histogramme indiquant la fr√©quence d’apparition de chaque visual word

Finalement, le bag-of-features d’une image est le vecteur dans lequel on a stock√© les valeurs de l’histogramme et qu’on a normalis√© (en divisant par la norme euclidienne). 

Classification supervisée

C’est la derni√®re √©tape de notre m√©thode de r√©solution : l’objectif est d’apprendre les r√®gles de d√©cision permettant d’assigner correctement une repr√©sentation bag-of-features √† une classe. Cela signifie qu’on va entra√ģner un algorithme d’apprentissage supervis√© sur les bag-of-features construits √† l’√©tape 2. 

  1. plus proches voisins (k-NN)
  2. Régression logistique
  3. SVM (2 classes)
  4. SVM (multi-classes)
  5. SVM à noyau

Classifier des images √† l’aide de r√©seaux de neurones convolutifs

Dans la partie pr√©c√©dente, nous avons √©tudi√© la notion de features en vision et les m√©thodes traditionnellement utilis√©es pour faire de la classification d’images. Celles-ci consistent √† extraire les features de chaque image du jeu de donn√©es, puis √† entra√ģner un classifieur sur ces features

Ces techniques d’apprentissage supervis√© peuvent fournir de tr√®s bons r√©sultats et leur performance d√©pend fortement de la qualit√© des features pr√©alablement trouv√©e. Il existe plusieurs m√©thodes d’extraction et de description de features. L’algorithme SIFT est tr√®s populaire, puisqu’il parvient √† d√©tecter et √† d√©crire efficacement des features pertinentes.

En pratique, l’erreur de classification n’est jamais nulle. Les r√©sultats peuvent alors √™tre am√©lior√©s en cr√©ant de nouvelles m√©thodes d’extraction de features, plus adapt√©es aux images √©tudi√©es, ou en utilisant un “meilleur” classifieur. 

Mais en 2012, une r√©volution se produit : lors de la comp√©tition annuelle de vision par ordinateur ILSVRC, un nouvel algorithme de Deep Learning explose les records ! Il s’agit d’un r√©seau de neurones convolutif appel√© AlexNet. 

D√©finition d’un r√©seau de neurones convolutif

Les r√©seaux de neurones convolutifs ont une m√©thodologie similaire √† celle des m√©thodes traditionnelles d’apprentissage supervis√© : ils re√ßoivent des images en entr√©e, d√©tectent les features de chacune d’entre elles, puis entra√ģnent un classifieur dessus.

Cependant, les features sont apprises automatiquement ! Les CNN r√©alisent eux-m√™mes tout le boulot fastidieux d’extraction et description de features : lors de la phase d’entra√ģnement, l’erreur de classification est minimis√©e afin d’optimiser les param√®tres du classifieur ET les features ! De plus, l’architecture sp√©cifique du r√©seau permet d’extraire des features de diff√©rentes complexit√©s, des plus simples au plus sophistiqu√©es.  L’extraction et la hi√©rarchisation automatiques des features, qui s’adaptent au probl√®me donn√©, constituent une des forces des r√©seaux de neurones convolutifs : plus besoin d’impl√©menter un algorithme d’extraction “√† la main”, comme SIFT ou Harris-Stephens. 

Contrairement aux techniques d’apprentissage supervis√©, les r√©seaux de neurones convolutifs apprennent les features de chaque image. C’est l√† que r√©side leur force : les r√©seaux font tout le boulot d’extraction de features automatiquement, contrairement aux techniques d’apprentissage  

Aujourd’hui, les r√©seaux de neurones convolutifs, aussi appel√©s CNN ou ConvNet pour Convolutional Neural Network, sont toujours les mod√®les les plus performants pour la classification d’images. Cette partie leur est donc naturellement consacr√©e.

Rappel sur les r√©seaux de neurones

Pour bien comprendre les r√©seaux de neurones convolutifs, il est important de conna√ģtre les bases des r√©seaux de neurones

Les principaux √©l√©ments √† retenir sont les suivants :

  • Un r√©seau de neurones est un syst√®me compos√© de neurones, g√©n√©ralement r√©partis en plusieurs couches connect√©es entre elles
  • Un tel syst√®me s’utilise pour r√©soudre divers probl√®mes statistiques, mais nous nous int√©ressons ici qu’au probl√®me de classification (tr√®s courant). Dans ce cas, le r√©seau calcule √† partir de l’entr√©e un score (ou probabilit√©) pour chaque classe. La classe attribu√©e √† l’objet en entr√©e correspond √† celle de score le plus √©lev√© 
  • Chaque couche re√ßoit en entr√©e des donn√©es et les renvoie transform√©es. Pour cela, elle calcule une combinaison lin√©aire puis applique √©ventuellement une fonction non-lin√©aire, appel√©e fonction d’activation. Les coefficients de la combinaison lin√©aire d√©finissent les param√®tres (ou poids) de la couche
  • Un r√©seau de neurones est construit en empilant les couches : la sortie d’une couche correspond √† l’entr√©e de la suivante.
  • Cet empilement de couches d√©finit la sortie finale du r√©seau comme le r√©sultat d’une fonction diff√©rentiable de l’entr√©e
  • La derni√®re couche calcule les probabilit√©s finales en utilisant pour fonction d’activation la fonction logistique (classification binaire) ou la fonction softmax (classification multi-classes)
  • Une fonction de perte (loss function) est associ√©e √† la couche finale pour calculer l’erreur de classification. Il s’agit en g√©n√©ral de l’entropie crois√©e
  • Les valeurs des poids des couches sont apprises par r√©tropropagation du gradient : on calcule progressivement (pour chaque couche, en partant de la fin du r√©seau) les param√®tres qui minimisent la fonction de perte r√©gularis√©e. L’optimisation se fait avec une descente du gradient stochastique

Les réseaux de neurones convolutifs

Quelle est la différence entre un réseau de neurones et un réseau de neurones convolutif ?

Les r√©seaux de neurones convolutifs d√©signent une sous-cat√©gorie de r√©seaux de neurones : ils pr√©sentent donc toutes les caract√©ristiques list√©es ci-dessus. Cependant, les CNN sont sp√©cialement con√ßus pour traiter des images en entr√©e. Leur architecture est alors plus sp√©cifique : elle est compos√©e de deux blocs principaux.

Le premier bloc fait la particularit√© de ce type de r√©seaux de neurones, puisqu’il fonctionne comme un extracteur de features. Pour cela, il effectue du template matching en appliquant des op√©rations de filtrage par convolution. La premi√®re couche filtre l’image avec plusieurs noyaux de convolution, et renvoie des “feature maps”, qui sont ensuite normalis√©es (avec une fonction d’activation) et/ou redimensionn√©es.

Ce proc√©d√© peut √™tre r√©it√©r√© plusieurs fois : on filtre les features maps obtenues avec de nouveaux noyaux, ce qui nous donne de nouvelles features maps √† normaliser et redimensionner, et qu’on peut filtrer √† nouveau, et ainsi de suite. Finalement, les valeurs des derni√®res feature maps sont concat√©n√©es dans un vecteur. Ce vecteur d√©finit la sortie du premier bloc, et l’entr√©e du second.

Le second bloc n’est pas caract√©ristique d’un CNN : il se retrouve en fait √† la fin de tous les r√©seaux de neurones utilis√©s pour la classification. Les valeurs du vecteur en entr√©e sont transform√©es (avec plusieurs combinaisons lin√©aires et fonctions d’activation) pour renvoyer un nouveau vecteur en sortie. Ce dernier vecteur contient autant d’√©l√©ments qu’il y a de classes : l’√©l√©ment ii repr√©sente la probabilit√© que l’image appartienne √† la classe ii. Chaque √©l√©ment est donc compris entre 0 et 1, et la somme de tous vaut 1. Ces probabilit√©s sont calcul√©es par la derni√®re couche de ce bloc (et donc du r√©seau), qui utilise une fonction logistique (classification binaire) ou une fonction softmax (classification multi-classe) comme fonction d’activation.

Comme pour les r√©seaux de neurones ordinaires, les param√®tres des couches sont d√©termin√©s par r√©tropropagation du gradient : l’entropie crois√©e est minimis√©e lors de la phase d’entra√ģnement. Mais dans le cas des CNN, ces param√®tres d√©signent en particulier les features des images.

Les diff√©rents types de couches d’un CNN sont expliqu√©es dans le chapitre suivant.

D√©couvrir les diff√©rentes couches d’un CNN

Il existe quatre types de couches pour un r√©seau de neurones convolutif : la couche de convolution, la couche de pooling, la couche de correction ReLU et la couche fully-connected. Dans ce chapitre, je vais vous expliquer le fonctionnement de ces diff√©rentes couches.

La couche de convolution

La couche de convolution est la composante cl√© des r√©seaux de neurones convolutifs, et constitue toujours au moins leur premi√®re couche.

Son but est de rep√©rer la pr√©sence d’un ensemble de features dans les images re√ßues en entr√©e. Pour cela, on r√©alise un filtrage par convolution : le principe est de faire “glisser” une fen√™tre repr√©sentant la feature sur l’image, et de calculer le produit de convolution entre la feature et chaque portion de l’image balay√©e. Une feature est alors vue comme un filtre : les deux termes sont √©quivalents dans ce contexte. 

Cette technique est tr√®s proche de celle √©tudi√©e dans la partie pr√©c√©dente pour faire du template matching : ici, c’est le produit convolution qui est calcul√©, et non la corr√©lation crois√©e.

La couche de convolution re√ßoit donc en entr√©e plusieurs images, et calcule la convolution de chacune d’entre elles avec chaque filtre. Les filtres correspondent exactement aux features que l’on souhaite retrouver dans les images. 

On obtient pour chaque paire (image, filtre) une carte d’activation, ou feature map, qui nous indique o√Ļ se situent les features dans l’image : plus la valeur est √©lev√©e, plus l’endroit correspondant dans l’image ressemble √† la feature

 Comment choisir les features ?

Contrairement aux m√©thodes traditionnelles, les features ne sont pas pr√©-d√©finies selon un formalisme particulier (par exemple SIFT), mais apprises par le r√©seau lors la phase d’entra√ģnement ! Les noyaux des filtres d√©signent les poids de la couche de convolution. Ils sont initialis√©s puis mis √† jour par r√©tropropagation du gradient

C’est l√† toute la force des r√©seaux de neurones convolutifs : ceux-ci sont capables de d√©terminer tout seul les √©l√©ments discriminants d’une image, en s’adaptant au probl√®me pos√©. Par exemple, si la question est de distinguer les chats des chiens, les features automatiquement d√©finies peuvent d√©crire la forme des oreilles ou des pattes.  

La couche de pooling

Ce type de couche est souvent plac√© entre deux couches de convolution : elle re√ßoit en entr√©e plusieurs feature maps, et applique √† chacune d’entre elles l’op√©ration de pooling

L’op√©ration de pooling consiste √† r√©duire la taille des images, tout en pr√©servant leurs caract√©ristiques importantes.

Pour cela, on d√©coupe l’image en cellules r√©guli√®res, puis on garde au sein de chaque cellule la valeur maximale. En pratique, on utilise souvent des cellules carr√©es de petite taille pour ne pas perdre trop d’informations. Les choix les plus communs sont des cellules adjacentes de taille 2 √ó√ó 2 pixels qui ne se chevauchent pas, ou des cellules de taille 3 √ó√ó 3 pixels, distantes les unes des autres d’un pas de 2 pixels (qui se chevauchent donc).

On obtient en sortie le m√™me nombre de feature maps qu’en entr√©e, mais celles-ci sont bien plus petites.

La couche de pooling permet de r√©duire le nombre de param√®tres et de calculs dans le r√©seau. On am√©liore ainsi l’efficacit√© du r√©seau et on √©vite le sur-apprentissage.

Les valeurs maximales sont rep√©r√©es de mani√®re moins exacte dans les feature maps obtenues apr√®s pooling que dans celles re√ßues en entr√©e ‚Äď c’est en fait un grand avantage ! En effet, lorsqu’on veut reconna√ģtre un chien par exemple, ses oreilles n’ont pas besoin d’√™tre localis√©es le plus pr√©cis√©ment possible : savoir qu’elles se situent √† peu pr√®s √† c√īt√© de la t√™te suffit !

Ainsi, la couche de pooling rend le r√©seau moins sensible √† la position des features : le fait qu’une feature se situe un peu plus en haut ou en bas, ou m√™me qu’elle ait une orientation l√©g√®rement diff√©rente ne devrait pas provoquer un changement radical dans la classification de l’image.

La couche de correction ReLU

ReLU (Rectified Linear Units) d√©signe la fonction r√©elle non-lin√©aire d√©finie par ReLU(x)=max(0,x)ReLU(x)=max(0,x).

Allure de la fonction ReLU
Allure de la fonction ReLU

La couche de correction ReLU remplace donc toutes les valeurs n√©gatives re√ßues en entr√©es par des z√©ros. Elle joue le r√īle de fonction d’activation.

La couche fully-connected

La couche fully-connected constitue toujours la derni√®re couche d’un r√©seau de neurones, convolutif ou non ‚Äď elle n’est donc pas caract√©ristique d’un CNN. 

Ce type de couche re√ßoit un vecteur en entr√©e et produit un nouveau vecteur en sortie. Pour cela, elle applique une combinaison lin√©aire puis √©ventuellement une fonction d’activation aux valeurs re√ßues en entr√©e.

La derni√®re couche fully-connected permet de classifier l’image en entr√©e du r√©seau : elle renvoie un vecteur de taille NN, o√Ļ NN est le nombre de classes dans notre probl√®me de classification d’images. Chaque √©l√©ment du vecteur indique la probabilit√© pour l’image en entr√©e d’appartenir √† une classe. 

Par exemple, si le probl√®me consiste √† distinguer les chats des chiens, le vecteur final sera de taille 2 : le premier √©l√©ment (respectivement, le deuxi√®me) donne la probabilit√© d’appartenir √† la classe “chat” (respectivement “chien”). Ainsi, le vecteur [0.90.1][0.90.1] signifie que l’image a 90% de chances de repr√©senter un chat. 

Chaque valeur du tableau en entr√©e “vote” en faveur d’une classe. Les votes n’ont pas tous la m√™me importance : la couche leur accorde des poids qui d√©pendent de l’√©l√©ment du tableau et de la classe.

Pour calculer les probabilit√©s, la couche fully-connected multiplie donc chaque √©l√©ment en entr√©e par un poids, fait la somme, puis applique une fonction d’activation (logistique si N=2N=2, softmax si N>2N>2) :

Ce traitement revient √† multiplier le vecteur en entr√©e par la matrice contenant les poids. Le fait que chaque valeur en entr√©e soit connect√©e avec toutes les valeurs en sortie explique le terme fully-connected.

Comment connait-on la valeur de ces poids ?

Le r√©seau de neurones convolutif apprend les valeurs des poids de la m√™me mani√®re qu’il apprend les filtres de la couche de convolution : lors de phase d’entra√ģnement, par r√©tropropagation du gradient.

La couche fully-connected d√©termine le lien entre la position des features dans l’image et une classe. En effet, le tableau en entr√©e √©tant le r√©sultat de la couche pr√©c√©dente, il correspond √† une carte d’activation pour une feature donn√©e : les valeurs √©lev√©es indiquent la localisation (plus ou moins pr√©cise selon le pooling) de cette feature dans l’image. Si la localisation d’une feature √† un certain endroit de l’image est caract√©ristique d’une certaine classe, alors on accorde un poids important √† la valeur correspondante dans le tableau.

Construire son premier CNN

Licence Attribution Share Alike 4.0 International (CC BY-SA 4.0)
Cours original : OpenClassRoom

Permanent link to this article: https://www.eirlab.net/2022/02/12/traitement-dimage-pour-la-detection-de-tag-aruco-%f0%9f%8c%b1-avec-opencv-en-python-1-4/