Filtrage d'images en Python

Avez-vous déjà rencontré une image bruyante? Je veux dire une image qui n’était pas aussi nette lors de sa visualisation? Je pense que nous rencontrons très souvent de telles images, en particulier lorsque de nombreuses images sont prises à présent avec nos appareils-photo pour téléphone portable ou nos appareils photo numériques à basse résolution..

Si vous n'aviez que cette image bruyante qui vous dit quelque chose, mais que le problème est qu'elle ne peut pas être visualisée correctement, existe-t-il une solution pour récupérer de ce bruit??

C'est ici qu'intervient le filtrage d'images, et c'est ce que je vais décrire dans ce tutoriel. Commençons!

Filtrage d'image

Le filtrage d'images est un outil couramment utilisé dans le traitement d'images. À la fin de la journée, nous utilisons le filtrage d'images pour supprimer le bruit et toutes les fonctionnalités indésirables d'une image, créant ainsi une version améliorée et améliorée de cette image. Deux types de filtres existent: linéaire et non linéaire. Des exemples de filtres linéaires sont les filtres moyenne et laplacien. Les filtres non linéaires constituent des filtres comme les filtres médian, minimum, maximum et Sobel.

Chacun de ces filtres a un objectif spécifique et est conçu pour éliminer le bruit ou améliorer certains aspects de l'image. Mais comment se fait le filtrage? C'est ce que nous verrons dans la section suivante.

Comment procédons-nous au filtrage d'images??

Pour mener à bien un processus de filtrage d’images, nous avons besoin d’un filtre, aussi appelé un masque. Ce filtre est généralement une fenêtre carrée à deux dimensions, c'est-à-dire une fenêtre de dimensions égales (largeur et hauteur).. 

Le filtre inclura des nombres. Ces chiffres s'appellent les coefficients, et c’est ce qui détermine réellement l’effet du filtre et à quoi ressemblera l’image de sortie. La figure ci-dessous montre un exemple de 3x3 filtre, ayant neuf valeurs (coefficients).

Pour appliquer le filtre, le 3x3 La fenêtre est glissée sur l'image. Ce processus de glissement d'une fenêtre de filtre sur une image s'appelle convolution dans le domaine spatial. La fenêtre sera placée sur chaque pixel (c’est-à-dire que vous la considérez comme une cellule dans une matrice) de l’image, le centre du filtre devant chevaucher ce pixel.. 

Une fois ce chevauchement effectué, les pixels de la sous-image sur lesquels le filtre se trouve sont multipliés par les coefficients correspondants du filtre. Dans ce cas, nous aurons une nouvelle matrice avec de nouvelles valeurs similaires à la taille du filtre (c'est-à-dire. 3x3). Enfin, la valeur de pixel centrale sera remplacée par une nouvelle valeur utilisant une équation mathématique spécifique en fonction du type de filtre utilisé (c'est-à-dire un filtre médian)..

Je sais que le paragraphe ci-dessus est un peu verbeux. Prenons un exemple pour montrer comment un filtre d'image est appliqué en action. Supposons que nous ayons la sous-image suivante où notre filtre se chevauchait (je et j faire référence à l'emplacement des pixels dans la sous-image, et je fait référence à l'image):

La convolution de notre filtre montré dans la première figure avec la sous-image ci-dessus ressemblera à celle montrée ci-dessous, où I_new (i, j) représente le résultat à l'emplacement (i, j).

I_new (i, j) = v1 x I (i-1, j-1) + v2 x I (i-1, j) + v3 x I (i-1, j + 1) + v4 x I (i, j-1) + v5 x I (i, j) + v6 x I (i, j + 1) + v7 x I (i + 1, j-1) + v8 x I (i + 1, j) + v9 x I (i + 1, j + 1) 

Le processus est répété pour chaque pixel de l'image, y compris les pixels situés à la limite de l'image. Mais, comme vous pouvez le deviner, une partie du filtre réside en dehors de l'image lorsque vous le placez au niveau des pixels de la limite. Dans ce cas, nous effectuons rembourrage

Ce processus signifie simplement que nous insérons de nouvelles valeurs de pixel dans la sous-image sous la partie du filtre qui sort de l'image avant le processus de convolution, car cette partie ne contient apparemment aucune valeur de pixel. C'est en dehors de l'image! Ces pixels peuvent être des zéros ou une valeur constante. Il existe d'autres méthodes pour définir les valeurs de remplissage, mais elles sortent du cadre de ce didacticiel..

Je pense que c'est assez théorique pour le moment, alors allons-y et mettons la main à la pâte avec le codage! Dans ce tutoriel, je vais expliquer le filtre médian (c'est-à-dire non linéaire) et le filtre moyen (c'est-à-dire linéaire) et comment nous pouvons les implémenter en Python.. 

Filtre médian

Dans le filtre médian, nous choisissons une fenêtre glissante qui parcourt l’ensemble des pixels de l’image. Ce que nous faisons ici est que nous collectons les valeurs de pixels qui entrent dans le filtre et prenons la médiane de ces valeurs. Le résultat sera assigné au pixel central. 

Dites notre 3x3 Le filtre avait les valeurs suivantes après l'avoir placé sur une sous-image:

Voyons comment calculer la médiane. La médiane, dans son essence, est la milieu numéro d'une liste triée de nombres. Ainsi, pour trouver la médiane pour le filtre ci-dessus, nous trions simplement les nombres du plus bas au plus élevé, et le milieu de ces nombres sera notre valeur médiane. Tri des valeurs dans notre 3x3 La fenêtre nous donnera les informations suivantes:

17 29 43 57 59 63 65 84 98

Pour trouver le nombre médian (médian), nous comptons simplement le nombre de valeurs dont nous disposons, nous ajoutons 1 à ce nombre et nous divisons par 2. Cela nous donnera l'emplacement de la valeur médiane dans la fenêtre, qui est notre valeur médiane. Donc, la valeur médiane sera à l'emplacement 9 + 1/2 = 5, lequel est 59. Cette valeur sera la nouvelle valeur du pixel sous le centre de notre 3x3 la fenêtre.

Ce type de filtre est utilisé pour supprimer le bruit et fonctionne mieux avec des images souffrant de sel et poivre bruit. L'image ci-dessous montre un exemple d'image souffrant d'un tel bruit:

Maintenant, écrivons un script Python qui appliquera le filtre médian à l'image ci-dessus. Pour cet exemple, nous utiliserons la bibliothèque OpenCV. Veuillez cocher Installer OpenCV-Python sous Windows et Installer OpenCV 3.0 et Python 2.7+ sur Ubuntu pour installer OpenCV..

Pour appliquer le filtre médian, nous utilisons simplement OpenCV cv2.medianBlur () une fonction. Notre script peut donc ressembler à ceci:

import cv2 import argparse # crée l'analyseur d'arguments et analyse les arguments ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = 'Chemin d'accès à l'image d'entrée') args = vars (ap.parse_args ()) # lit l'image image = cv2.imread (args ['image']) # applique le filtre médian 3x3 sur l'image processing_image = cv2.medianBlur (image, 3) # affiche l'image cv2. imshow ('Traitement du filtre médian', image_produit) # enregistrer l'image sur le disque cv2.imwrite ('image_processé.png', image traitée) # met en pause l'exécution du script jusqu'à ce qu'une touche du clavier soit enfoncée cv2.waitKey (0)

Notez que j'ai utilisé argparse, comme c'est une bonne pratique d'être flexible ici et d'utiliser la ligne de commande pour transmettre l'image sur laquelle nous voulons appliquer le filtre médian comme argument à notre programme. 

Après avoir passé notre image en argument de ligne de commande, nous lisons cette image en utilisant le cv2.imread () une fonction. Nous appliquons ensuite le filtre médian en utilisant le medianBlur () fonction, en passant notre image et la taille du filtre en tant que paramètres. L'image est affichée en utilisant le cv2.imshow () fonction et est enregistré sur le disque en utilisant cv2.imwrite ().

Le résultat du script ci-dessus est le suivant:

Bien, qu'en pensez-vous? Très belle image agréable et propre sans bruit.

Vous pouvez télécharger le code ci-dessus depuis mon référentiel de filtres médian sur GitHub..

Filtre moyen

Le filtre de moyenne est un exemple de filtre linéaire. Il remplace fondamentalement chaque pixel de l'image de sortie par la valeur moyenne (moyenne) du voisinage. Cela a pour effet de lisser l'image (en réduisant l'ampleur des variations d'intensité entre un pixel et le suivant), en supprimant le bruit de l'image et en éclaircissant l'image..

Ainsi, dans le filtrage moyen, chaque pixel de l'image sera remplacé par la valeur moyenne de ses voisins, y compris le pixel lui-même. le 3x3 Le noyau utilisé pour le filtrage de la moyenne est comme indiqué dans la figure ci-dessous, bien que d'autres tailles de noyau puissent être utilisées (c'est-à-dire 5x5):

Ce que le noyau ci-dessus essaie de nous dire, c’est que nous additionnons tous les éléments du noyau et prenons la moyenne (moyenne) du total..

Un point important à mentionner ici est que tous les éléments du noyau moyen doivent:

  • somme à 1
  • être le même

Prenons un exemple pour clarifier les choses. Disons que nous avons la sous-image suivante:

Lors de l'application du filtre de moyenne, nous ferions ce qui suit:

(7 + 9 + 23 + 76 + 91 + 7 + 64 + 90 + 32) / 9 = 44

Le résultat exact est 44,3, mais j'ai arrondi le résultat à 44. Donc, la nouvelle valeur pour le pixel central est 44 au lieu de 91.

Passons maintenant à la partie codage. Disons que nous avons l'image bruyante suivante:

Ce que nous voulons faire à ce stade est d’appliquer le filtre de moyenne sur l’image ci-dessus et de voir les effets de l’application d’un tel filtre..

Le code pour effectuer cette opération est le suivant:

import cv2 import numpy as np import argparse # crée l'analyseur d'arguments et analyse les arguments ap = argparse.ArgumentParser () ap.add_argument ('- i', '--image', required = True, help = 'Chemin d'accès à l'entrée image ') args = vars (ap.parse_args ()) # lit l'image image = cv2.imread (args [' image ']) # applique le filtre de moyenne 3x3 sur le noyau de l'image = np.ones ((3,3) , np.float32) / 9 transformation_image = cv2.filter2D (image, -1, noyau) # image d'affichage cv2.imshow ('Traitement par filtre moyen', image_processus) # # enregistrer l'image sur le disque cv2.imwrite ('traitement_image.png', ', transformer_image) # met en pause l'exécution du script jusqu'à ce qu'une touche du clavier soit enfoncée cv2.waitKey (0)

Avis du code que nous avons utilisé un 3x3 noyau pour notre filtre moyen. Nous avons également utilisé le filter2D () fonction pour appliquer le filtre moyen. Le premier paramètre de cette fonction est notre image d'entrée, le second est la profondeur souhaitée de l'image de sortie. un peu profond, et le troisième paramètre est notre noyau. Attribution -1 pour le un peu profond paramètre signifie que l'image de sortie aura la même profondeur comme image d'entrée.

Après avoir exécuté le code sur notre image bruyante, voici le résultat obtenu:

Si vous observez l'image de sortie, nous pouvons voir qu'elle est plus lisse que l'image bruyante. Mission accomplie!

Vous pouvez télécharger le code ci-dessus depuis mon référentiel de filtres moyens sur GitHub..

Conclusion

Comme nous l'avons vu dans ce didacticiel, Python nous permet d'effectuer des tâches avancées telles que le filtrage d'images, notamment via sa bibliothèque OpenCV, de manière simple..

De plus, n'hésitez pas à voir ce que nous avons disponible à la vente et à étudier sur le marché, et n'hésitez pas à poser des questions et à fournir vos précieux commentaires en utilisant le flux ci-dessous.