15
Convolutions avec OpenCV et Python 1 er août 2018 Je vais commencer le blog d’aujourd’hui en posant une série de questions qui seront ensuite abordées plus tard dans le tutoriel : Que sont les convolutions d’images ? Que font-ils ? Pourquoi les utilisons-nous ? Comment les appliquons-nous ? Et quel rôle jouent les circonvolutions dans l’apprentissage en profondeur ? Le mot « convolution »sonne comme un terme compliqué, mais ce n’est vrai- ment pas le cas. En fait, si vous avez déjà travaillé avec la vision par ordina- teur, le traitement d’image ou OpenCV auparavant, vous avez déjà appliqué des convolutions, que vous le réalisiez ou non ! Avez-vous déjà appliqué un flou ou un lissage? Oui, c’est une convolution. Et la détection des contours ? Oui, convolution. Avez-vous ouvert Photoshop ou GIMP pour affiner une image? Vous l’avez deviné – convolution. Les convolutions sont l’un des éléments fondamentaux les plus essentiels de la vision par ordinateur et du traitement de l’image. Mais le terme lui-même a tendance à effrayer les gens –en fait, en surface, le mot semble même avoir une connotation négative. Croyez-moi, les circonvolutions sont tout sauf effrayantes. Elles sont en fait assez faciles à comprendre. En réalité, une convolution (image) est simplement une multiplication par éléments de deux matrices suivie d’une somme. 1

Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

  • Upload
    others

  • View
    17

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Convolutions avec OpenCV et Python

1er août 2018

Je vais commencer le blog d’aujourd’hui en posant une série de questions quiseront ensuite abordées plus tard dans le tutoriel :

• Que sont les convolutions d’images ?• Que font-ils ?• Pourquoi les utilisons-nous ?• Comment les appliquons-nous ?• Et quel rôle jouent les circonvolutions dans l’apprentissage en

profondeur ?Le mot « convolution »sonne comme un terme compliqué, mais ce n’est vrai-

ment pas le cas. En fait, si vous avez déjà travaillé avec la vision par ordina-teur, le traitement d’image ou OpenCV auparavant, vous avez déjà appliqué desconvolutions, que vous le réalisiez ou non !

Avez-vous déjà appliqué un flou ou un lissage ? Oui, c’est une convolution.Et la détection des contours ? Oui, convolution.Avez-vous ouvert Photoshop ou GIMP pour affiner une image ? Vous l’avez

deviné – convolution.Les convolutions sont l’un des éléments fondamentaux les plus essentiels de

la vision par ordinateur et du traitement de l’image. Mais le terme lui-même atendance à effrayer les gens –en fait, en surface, le mot semble même avoir uneconnotation négative.

Croyez-moi, les circonvolutions sont tout sauf effrayantes. Elles sont en faitassez faciles à comprendre.

En réalité, une convolution (image) est simplement une multiplication paréléments de deux matrices suivie d’une somme.

1

Page 2: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Sérieusement. C’est tout. Vous venez d’apprendre ce qu’est la convolution :• 1–Prenez deux matrices (qui ont toutes deux les mêmes dimensions).• 2–Multipliez-les, élément par élément (c’est-à-dire, pas le point-produit,

juste une simple multiplication).• 3–Faites la somme des éléments ensemble.Pour en savoir plus sur les convolutions, pourquoi nous les utilisons, com-

ment les appliquer et le rôle global qu’elles jouent dans l’apprentissage enprofondeur + la classification des images, assurez-vous de continuer à lirecet article.

Une note rapide sur les gourous PyImageSearchAvant de commencer, je voudrais juste mentionner que la première moitié

de cet article sur les noyaux et les convolutions est basée sur la leçon « Ker-nels »dans le cours PyImageSearch Gurus.

Bien que la leçon sur les noyaux soit beaucoup plus détaillée que le fait cebillet, je voudrais quand même vous donner un avant-goût de ce que PyImage-Search Gurus –mon magnum opus – sur la vision par ordinateur (a à offrir).

Si vous aimez ce tutoriel, il y a plus de 168 leçons couvrant plus de 2 161pages de contenu sur les bases de l’image, l’apprentissage en profondeur, lareconnaissance automatique des plaques d’immatriculation, la reconnaissancefaciale et bien d’autres choses dans PyImageSearch Gurus.

Pour en savoir plus sur le cours PyImageSearch Gurus (et prenez 10 exemplesde leçons GRATUITES), cliquez simplement sur le bouton ci-dessous :

Convolutions avec OpenCV et PythonPensez-y de cette façon – une image est juste une matrice multidimension-

nelle. Notre image a une largeur (nombre de colonnes) et une hauteur (nombrede lignes), tout comme une matrice.

Mais contrairement aux matrices traditionnelles avec lesquelles vous avezpeut-être travaillé au collège, les images ont aussi une profondeur : le nombre decanaux dans l’image. Pour une image RVB standard, nous avons une profondeurde 3 canaux pour chacun des canaux Rouge, Vert et Bleu, respectivement.

Compte tenu de ces connaissances, nous pouvons considérer une image commeune grande matrice et un noyau ou une matrice convolutive comme une minus-cule matrice utilisée pour le flou, l’accentuation, la détection des contours etd’autres fonctions de traitement d’image.

Essentiellement, ce minuscule noyau se trouve au-dessus de la grande imageet glisse de gauche à droite et de haut en bas, en appliquant une opération ma-thématique (c’est-à-dire une convolution) à chaque coordonnée (x, y) de l’imageoriginale .

Il est normal de définir manuellement les noyaux pour obtenir diverses fonc-tions de traitement d’image. En fait, vous pouvez déjà être familier avec le flou(lissage moyen, lissage gaussien, lissage médian, etc.), la détection des contours(Laplacien, Sobel, Scharr, Prewitt, etc.) et les aiguiser – toutes ces opérationssont des formes de manuelle de noyaux définis qui sont spécifiquement conçuspour exécuter une fonction particulière.

2

Page 3: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Donc, cela soulève la question, est-il un moyen d’apprendre automatique-ment ces types de filtres ? Et même utiliser ces filtres pour la classificationd’image et la détection d’objet ?

Vous pariez qu’il y a.Mais avant d’y arriver, nous devons comprendre un peu plus les noyaux et

les circonvolutions.

KernelsEncore une fois, considérons une image comme une grande matrice et un

noyau comme une minuscule matrice (au moins par rapport à l’image originalede la « grande matrice ») :

Comme le montre la figure ci-dessus, nous faisons glisser le noyau de gaucheà droite et de haut en bas le long de l’image originale.

À chaque coordonnée (x, y) de l’image originale, nous arrêtons et examinonsle voisinage des pixels situés au centre du noyau de l’image. Nous prenons alorsce voisinage de pixels, les convolons avec le noyau, et obtenons une seule valeur

3

Page 4: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

de sortie. Cette valeur de sortie est ensuite stockée dans l’image de sortie aumême point (x, y) que le centre du noyau.

Si cela semble déroutant, pas d’inquiétude, nous allons examiner un exempledans la section « Comprendre les images convolutions »plus loin dans ce blog.

Mais avant de plonger dans un exemple, jetons d’abord un coup d’oeil à ceà quoi ressemble un noyau :

Ci-dessus, nous avons défini un noyau carré de 3 x 3 (des suppositions surce que ce noyau est utilisé ?)

Les noyaux peuvent avoir une taille arbitraire de M x N pixels, à conditionque M et N soient des entiers impairs.

Remarque : La plupart des noyaux que vous verrez habituellement sont enfait des matrices N x N carrées.

Nous utilisons une taille de noyau impaire pour nous assurer qu’il existe unentier (x, y) -coordinate valide au centre de l’image :

4

Page 5: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Sur la gauche, nous avons une matrice de 3 x 3. Le centre de la matrice estévidemment situé à x = 1, y = 1 où le coin supérieur gauche de la matrice estutilisé comme origine et nos coordonnées sont indexées à zéro.

Mais à droite, nous avons une matrice 2 x 2. Le centre de cette matriceserait situé à x = 0,5, y = 0,5. Mais comme nous le savons, sans appliquerl’interpolation, il n’y a pas de localisation de pixel (0.5, 0.5) - nos coordonnéesde pixels doivent être des entiers ! Ce raisonnement est exactement pourquoinous utilisons des tailles de noyaux impairs - pour toujours s’assurer qu’il y aune coordonnée (x, y) valide au centre du noyau.

Comprendre les images convolutionsMaintenant que nous avons discuté des bases des noyaux, parlons d’un terme

mathématique appelé convolution.En traitement d’image, une convolution nécessite trois composants :1. Une image d’entrée.2. Une matrice de noyau que nous allons appliquer à l’image d’entrée.3. Une image de sortie pour stocker la sortie de l’image d’entrée convoluée

avec le noyau.La convolution elle-même est en fait très facile. Tout ce que nous devons

faire est :1. Sélectionnez une coordonnée (x, y) à partir de l’image originale.2. Placez le centre du noyau à cette coordonnée (x, y).3. Prenez la multiplication par éléments de la région d’image d’entrée et du

noyau, puis additionnez les valeurs de ces opérations de multiplication enune seule valeur. La somme de ces multiplications s’appelle la sortie dukernel.

4. Utilisez les mêmes coordonnées (x, y) que celles de l’étape #1, maiscette fois, stockez la sortie du noyau dans le même emplacement (x, y)que l’image de sortie.

5

Page 6: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Ci-dessous vous pouvez trouver un exemple de convolution (désigné mathéma-tiquement par l’opérateur "*") d’une région 3x3 d’une image avec un noyau 3x3utilisé pour flouter :

Donc

Après avoir appliqué cette convolution, nous allons définir le pixel situé à lacoordonnée (i, j) de l’image de sortie O à O_i, j = 126.

C’est tout ce qu’on peut en dire !La convolution est simplement la somme de la multiplication matricielle

élément par élément entre le noyau et le voisinage que le noyau recouvre del’image d’entrée.

Implémentation de convolutions avec OpenCV etPython

C’était amusant de discuter des noyaux et des convolutions - mais passonsmaintenant à un code réel pour vous assurer que vous comprenez commentles noyaux et les convolutions sont implémentés. Ce code source vous aideraégalement à comprendre comment appliquer des convolutions aux images.

Ouvrez un nouveau fichier, nommez-le convolutions.py , et commençons àtravailler :

6

Page 7: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Nous commençons sur les lignes 2-5 en important nos paquets Python re-quis. Vous devriez déjà avoir NumPy et OpenCV installés sur votre système,mais vous ne pouvez pas avoir installé scikit-image 1. Pour installer scikit-image,utilisez pip :

Ensuite, nous pouvons commencer à définir notre méthode de convolvepersonnalisée :

La fonction convolve nécessite deux paramètres : l’ image (en niveaux degris) que nous voulons convoluer avec le kernel .

Étant donné à la fois notre image et notre kernel (que nous supposonsêtre des tableaux NumPy), nous déterminons ensuite les dimensions spatiales(c’est-à-dire, la largeur et la hauteur) de chacune (Lignes 10 et 11).

Avant de continuer, il est important de comprendre que le fait de « faireglisser » 2 une matrice convolutive sur une image, d’appliquer la convolution,puis de stocker la sortie, diminuera en fait les dimensions spatiales de notreimage de sortie.

Pourquoi ?Rappelons que nous « centrons »notre calcul autour du centre (x, y) – co-

ordonnées de l’image d’entrée sur laquelle le noyau est actuellement positionné.Cela implique qu’il n’y a pas de pixels « centraux »pour les pixels qui tombentle long de la bordure de l’image. La diminution de la dimension spatiale est sim-plement un effet secondaire de l’application de convolutions aux images. Parfois,cet effet est souhaitable et d’autres fois non, cela dépend simplement de votreapplication.

Cependant, dans la plupart des cas, nous voulons que notre image de sortieait les mêmes dimensions que notre image d’entrée. Pour ce faire, nous appli-quons un padding 3 (Lignes 16-19). Ici, nous reproduisons simplement les pixelsle long de la bordure de l’image, de sorte que l’image de sortie corresponde auxdimensions de l’image d’entrée.

D’autres méthodes de remplissage existent, y compris le padding zero (rem-

1. http ://scikit-image.org/2. sliding3. rembourrage

7

Page 8: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

plir les bordures avec des zéros — très commun lors de la construction de réseauxconvolutionnels de neurones) et wrap around 4 (où les pixels de frontière sontdéterminés en examinant l’extrémité opposée de l’image). Dans la plupart descas, vous verrez un remplissage 5 répliqué ou nul.

Nous sommes maintenant prêts à appliquer la convolution réelle à notreimage :

Les lignes 24 et 25 bouclent sur notre image , « glissant »le noyau de gaucheà droite et de haut en bas 1 pixel à la fois.

La ligne 29 extrait la région d’intérêt (ROI) de l’ image en utilisant ladécoupe de tableau NumPy. Le roi sera centré autour des coordonnées (x, y)actuelles de l’ image . Le roi aura également la même taille que notre kernel ,ce qui est critique pour l’étape suivante.

La convolution est effectuée sur la ligne 34 en prenant la multiplication paréléments entre le roi et le kernel , suivie de la somme des entrées dans lamatrice.

La valeur de sortie k est ensuite stockée dans le tableau de output auxmêmes coordonnées (x, y) (par rapport à l’image d’entrée).

Nous pouvons maintenant terminer notre méthode convolve :

Lorsque nous travaillons avec des images, nous traitons généralement des va-leurs de pixels comprises dans la plage [0, 255]. Cependant, lors de l’applicationde convolutions, nous pouvons facilement obtenir des valeurs qui se situent endehors de cette plage.

Afin de ramener notre image de output dans la plage [0, 255], nous appli-

4. enrouler autour5. padding

8

Page 9: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

quons la fonction rescale_intensity de scikit-image (ligne 41). Nous convertis-sons également notre image en un type de données entier 8 bits non signé sur laligne 42 (auparavant, l’image de output était un type à virgule flottante afinde gérer les valeurs de pixels en dehors de la plage [0, 255]).

Enfin, l’image de output est renvoyée à la fonction appelante sur la ligne45.

Maintenant que nous avons défini notre fonction de convolve , passons à lapartie pilote du script. Cette section de notre programme va gérer l’analyse desarguments de la ligne de commande, en définissant une série de noyaux que nousallons appliquer à notre image, puis en affichant les résultats de sortie :

Les lignes 48-51 gèrent l’analyse de nos arguments de ligne de commande.Nous n’avons besoin ici que d’un seul argument, –image, qui est le chemin denotre chemin d’entrée.

Nous passons ensuite aux lignes 54 et 55 qui définissent un noyau 7 × 7et un noyau 21 × 21 utilisé pour flouter / lisser une image. Plus le noyau estgrand, plus l’image sera floue. En examinant ce noyau, vous pouvez voir que lasortie de l’application du noyau à une ROI sera simplement la moyenne de larégion d’entrée.

Nous définissons un noyau d’affinage sur les lignes 58 à 61, utilisé pouraméliorer les structures de lignes et d’autres détails d’une image. Expliquerchacun de ces noyaux en détail sort du cadre de ce tutoriel, donc si vous souhaitezen savoir plus sur la construction du noyau, je vous suggère de commencer ici 6

et de jouer avec l’excellent outil de visualisation du noyau sur Setosa.io 7.Définissons quelques noyaux supplémentaires :

6. https ://en.wikipedia.org/wiki/Kernel_(image_processing)7. http ://setosa.io/ev/image-kernels/

9

Page 10: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Les lignes 65-68 définissent un opérateur laplacien 8 qui peut être utilisécomme une forme de détection de contour.

Remarque : Le laplacien est également très utile pour détecter le flou dansles images 9.

Enfin, nous allons définir deux filtres Sobel 10 sur les lignes 71-80. Le pre-mier (Lignes 71-74) est utilisé pour détecter les changements verticaux dans ledégradé de l’image. De même, les lignes 77-80 construisent un filtre utilisé pourdétecter les changements horizontaux dans le gradient.

Étant donné tous ces noyaux, nous les regroupons en un ensemble de tuplesappelé « banque de noyau » :

Enfin, nous sommes prêts à appliquer notre kernelBank à notre image- -input :

8. http ://docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/laplace_operator/laplace_operator.html9. https ://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/

10. https ://en.wikipedia.org/wiki/Sobel_operator

10

Page 11: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Les lignes 95 et 96 chargent notre image du disque et la convertissent enniveaux de gris. Les opérateurs de convolution peuvent certainement être appli-qués à RVB (ou à d’autres images multicanaux), mais par souci de simplicitédans ce billet de blog, nous n’appliquerons nos filtres qu’aux images en niveauxde gris).

Nous commençons à faire une boucle sur notre ensemble de noyaux danskernelBank sur la ligne 99, puis nous appliquons le -kernel actuel à l’imagegray sur la ligne 104 en appelant notre méthode de convolve personnaliséeque nous avons définie plus tôt.

En guise de vérification, nous appelons aussi cv2.filter2D qui applique éga-lement notre kernel à l’image gray . La fonction cv2.filter2D est une versionbeaucoup plus optimisée de notre fonction convolve . La principale raison pourlaquelle j’ai inclus la mise en œuvre de convolve dans ce blog est de vous donnerune meilleure compréhension de la façon dont les circonvolutions fonctionnentsous le capot.

Enfin, les lignes 108-112 affichent les images de sortie sur notre écran.

Exemple de convolutions avec OpenCV et PythonL’image d’exemple d’aujourd’hui provient d’une photo que j’ai prise il y a

quelques semaines dans mon bar préféré de South Norwalk, CT - Cask Repu-blic 11. Dans cette image, vous verrez un verre de ma bière préférée (SmuttynoseFindest Kind IPA) ainsi que trois Pokémon imprimés en 3D dans la boutiqueIndustrial Chimp (malheureusement, maintenant fermée) :

11. http ://caskrepublic.com/

11

Page 12: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Pour exécuter notre script, exécutez simplement la commande suivante :

$python convolutions.py –image 3d_pokemon.png

Vous verrez ensuite les résultats de l’application de notre noyau smallBlurà l’image d’entrée :

Sur la gauche, nous avons notre image originale. Ensuite, au centre, nousavons les résultats de la fonction convolve . Et sur la droite, les résultats decv2.filter2D . Comme les résultats le démontrent, notre sortie correspond àcv2.filter2D , indiquant que notre fonction convolve fonctionne correctement.De plus, notre image originale apparaît maintenant « floue »et « lissée », grâceau noyau de lissage.

Ensuite, appliquons un flou plus important :

12

Page 13: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

180/5000 En comparant la figure 7 et la figure 8, notez comment, lorsquela taille du noyau de calcul de la moyenne augmente, la quantité de flou dansl’image de sortie augmente également.

Nous pouvons également aiguiser notre image :

Calculons les arêtes en utilisant l’opérateur Laplacien :

13

Page 14: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Trouvez les bords verticaux avec l’opérateur Sobel :

Et trouvez des bords horizontaux en utilisant Sobel :

Le rôle des convolutions dans l’apprentissage pro-fond

Comme vous l’avez compris à travers ce billet de blog, nous devons ma-nuellement définir manuellement chacun de nos noyaux pour appliquer diversesopérations telles que le lissage, l’affinage et la détection des contours.

C’est très bien et bien,mais s’il y avait un moyen d’apprendre cesfiltres à la place ? Est-il possible de définir un algorithme d’apprentissageautomatique capable de regarder les images et éventuellement d’apprendre cestypes d’opérateurs ?

En fait, il existe —ces types d’algorithmes sont un sous-type de réseaux neu-ronaux appelés réseaux convolutionnels de neurones (CNN). En appliquant desfiltres convolutifs, des fonctions d’activation non linéaires, de regroupement etde rétropropagation, les CNN peuvent apprendre des filtres capables de détecterles arêtes et les structures de type blob dans les couches inférieures du réseau,puis utiliser les arêtes et les structures comme blocs de construction. détecterdes objets de plus haut niveau (par exemple, des visages, des chats, des chiens,des coupes, etc.) dans les couches les plus profondes du réseau.

14

Page 15: Convolutions avec OpenCV et Python - pagesperso-orange.fr et OpenCV... · 2019. 3. 22. · Exemple de convolutions avec OpenCV et Python L’image d’exemple d’aujourd’hui provient

Comment les CNN font-ils cela ?Je vais vous montrer – mais il faudra attendre encore quelques publications

jusqu’à ce que nous couvrons assez de bases

RésuméDans l’article d’aujourd’hui, nous avons discuté des image kernels et des

convolutions. Si nous considérons une image comme une emphgrande matrice,alors un noyau d’image est juste une minuscule matrice qui se trouve au-dessusde l’image.

Ce noyau glisse ensuite de gauche à droite et de haut en bas, calculant lasomme des multiplications par éléments entre l’image d’entrée et le noyau encours de route - nous appelons cette valeur la sortie du noyau. La kernel outputest ensuite stockée dans une image de sortie au même point (x, y)– que l’imaged’entrée (après prise en compte de tout bourrage (padding) pour s’assurer quel’image de sortie a les mêmes dimensions que l’entrée).

Compte tenu de notre nouvelle connaissance des convolutions, nous avonsdéfini une fonction OpenCV et Python pour appliquer une série de noyaux àune image. Ces opérateurs nous ont permis de brouiller une image, de l’aiguiseret de détecter les bords.

Enfin, nous avons brièvement discuté des rôles que jouent les noyaux / convo-lutions dans le deep learning, en particulier Convolutional Neural Networks 12

, et comment ces filtres peuvent être appris automatiquement au lieu de devoirles définir manuellement en premier

12. les réseaux de neurones convolutionnels

15