Python >> Tutoriel Python >  >> Python

Scikit-image, une bibliothèque de traitement d'images basée sur Python

Dans ce didacticiel, nous allons apprendre le traitement d'images à l'aide de scikit-image en Python.

Des mises à jour de statut idiotes à la documentation de haut niveau, les images sont devenues une partie intégrante des données numériques. D'où la nécessité de traiter l'image. Améliorer l'image, la compresser, extraire des données et les analyser, le traitement d'image est utilisé dans divers domaines tels que l'intelligence artificielle, la criminalistique des données, l'infographie, la recherche médicale et bien d'autres.

En raison de sa popularité croissante et de la disponibilité de nombreuses bibliothèques faciles à utiliser, Python est un excellent choix pour le traitement d'images. Il existe de nombreuses bibliothèques de traitement d'image disponibles en Python comme Numpy, Scipy, Scikit, OpenCV, Python Image Library (PIL), etc. Ce tutoriel est axé sur Scikit-image.

Image Scikit :

Scikit-Image est un package Python open source. Avant d'aller plus loin, découvrons les bases d'une image numérique.

Une image est composée de nombres que l'on peut représenter numériquement par des tableaux 2D. Chaque grille d'un tableau représente un pixel dans l'image. Cela rend le processus de segmentation d'image assez simple. Le package scikit-image fonctionne avec les tableaux NumPy.

Une image numérique peut être globalement classée en 2 types de canaux :niveaux de gris et multicanaux. Comme son nom l'indique, une image en niveaux de gris n'aura que des nuances de gris, couvrant différents tons de noir et de blanc. Ils n'ont pas d'autres informations sur la couleur. Le RVB multicanal, le plus courant, comporte 3 couches :Rouge, Vert et Bleu. Différentes approches de la manipulation des couleurs ont été introduites dans d'autres contenus.

Commencer avec Scikit-image

Voici le tutoriel complet étape par étape pour travailler avec cette bibliothèque en Python.

1. Mise en place

Sur l'invite de commande, tapez simplement-

pip install scikit-image

Et l'installation est terminée.

REMARQUE :si vous obtenez une erreur, il est possible que ce soit parce que vous n'avez pas NumPy et Scipy sur votre système et vous devrez peut-être d'abord les installer manuellement.

2. Afficher une image

Commençant notre voyage avec scikit-image, la toute première étape consiste à importer le package en utilisant skimage. Scikit contient un fichier contenant des images préchargées. Pour y accéder, utilisez le fichier module-data. Les données ont des images de démonstration standard qui peuvent être utilisées à des fins de test. Fusée, café, pièces de monnaie, appareil photo, page, etc.

Il existe un autre module - io. Ce module contient toutes les fonctions permettant de lire et d'écrire des images.

from skimage import data, io

image = data.coffee()
io.imshow(image)
io.show()

Le code ci-dessus applique imshow() et montrer()  les fonctions. imshow()  affiche une image. afficher()  affiche les images en attente mises en file d'attente par imshow. Nous devons utiliser show() lors de l'affichage d'images à partir de coques non interactives.

Sortie :

Par conséquent, nous avons terminé avec succès notre premier code et importé une image.

Maintenant, importons une image depuis un répertoire de notre système.

import os
from skimage import io 
file = os.path.join('skimage_data', 'books.jpg')  
book = io.imread(file) 
io.imshow(book) 
io.show()

Sortie :

Fig 2.2 Image des livres importés

3. Enregistrer une image

L'enregistrement n'est-il pas la partie la plus importante de tout type de traitement d'image ? Cela peut être fait en utilisant imsave() fonction. Imsave() prend l'emplacement avec le nom et le format souhaités et bien sûr, l'image qui doit être enregistrée en tant que paramètres.

from skimage import data, io
image = data.logo()
io.imsave('skimage/logo.png', image)

Exécutez le code et c'est fait ! L'image sera enregistrée à l'emplacement choisi.

4. Manipulation de forme à l'aide de scikit-image

La forme d'une image joue un rôle important dans la manipulation d'une image. Vous pouvez récupérer la taille d'une image en utilisant l'attribut shape.

from skimage import data

image = data.coffee()
print(image.shape)

Sortie :

(400, 600, 3)

Ici, 400 et 600 sont respectivement la hauteur et la largeur. 3 indique que l'image est une image multicolore.

Maintenant, redimensionnons cette image.

from skimage import data, io, transform
image = data.coffee()
img = transform.resize(image, (100, 100), anti_aliasing=True)
io.imshow(img)
io.show()
print(img.shape)

La fonction de redimensionnement de la bibliothèque de transformation est utilisée. La sortie donnera la forme de l'image redimensionnée et imprimera la nouvelle taille.

Sortie :

Fig 4.1 Image de café redimensionnée

(100, 100, 3)

Notez que lors d'un zoom avant, la qualité de l'image a diminué.

Vous pouvez même essayer de faire pivoter une image à l'aide de la bibliothèque de transformation.

from skimage import transform, io, data
image = data.coffee()
image_rotated = trasform.rotate(image, angle=45, resize=True)
io.imshow(image)
io.show()

Sortie :

Fig 4.2 Image de café pivotée

Allez jusqu'au bout à 180º pour une image à l'envers. Notez que le paramètre resize est utilisé; si cela est désactivé, la rotation se fera avec la taille d'origine et vous risquez de perdre des données importantes. Par défaut, le redimensionnement est défini sur Faux. La sortie sera affichée comme suit lorsque l'indicateur de redimensionnement n'est pas vrai.

5. Manipulation des couleurs à l'aide de scikit-image

1. Image en niveaux de gris

Les images en niveaux de gris sont simplement une image ayant des nuances de noir et de blanc. Ils représentent essentiellement l'intensité de la lumière et ne donnent aucune autre information de couleur. La représentation tonale de l'image peut aller de 0 (noir pur) à 255 (blanc pur).

2. Image couleur

Les images couleur ont globalement 3 couches - Rouge, Vert et Bleu (RVB). Ces couches sont appelées canaux. Vous pouvez séparer chaque canal (rouge, vert, bleu) comme ceci-

from skimage import data, io

image = data.chelsea()
image[:, :, 0] = 0
io.imshow(image)
io.show()

Les autres canaux de couleur peuvent être filtrés en utilisant [:, :, 1] ou [:, :, 2]. Voici à quoi ressemblera chaque sortie-

Fig 5.1 Filtrage des couleurs

L'image RVB peut être convertie en niveaux de gris et vice versa. La complexité de calcul est réduite lorsqu'une image en niveaux de gris est utilisée. Comme discuté ci-dessus, le format de la forme de l'image est spécifié comme [hauteur, largeur, canal]. Une image en niveaux de gris n'aurait pas de canal car elle ne donne aucune information de couleur.

from skimage import data, color

image = data.astronaut()
gray = color.rgb2grey(image) #conversion to grayscale
color = color.grey2rgb(img)  #back to colour

print(gray.shape)
print(color.shape)

Sortie :

(512, 512)
(512, 512, 3)

Fig 5.2 Image en niveaux de gris

Vous pouvez essayer la même chose avec d'autres canaux de couleur comme HSV (teinte, saturation, valeur), CEILAB, XYZ, etc. Voyons brièvement un exemple de l'un d'entre eux-

  • Teinte :  Le degré sur la roue chromatique commençant par 0º au rouge, 120º au bleu, 240º au vert et 360º retour au rouge.
  • Saturation :  Le pourcentage de couleur, 0 étant blanc et 100 étant en couleur
  • Valeur :  La quantité de blanc ou de noir dans une image.

Fig 5.3 Espace colorimétrique HSV

Prenons un exemple,

from skimage import data, io, color
image = data.coffee()

img = color.rgb2hsv(image)
io.imshow(img)
io.show()

Sortie :

Fig 5.4 RVB vers HSV

En explorant plus loin, une image en niveaux de gris peut même être teintée à la couleur de votre choix simplement en mettant à zéro les autres couleurs. Voici comment procéder-

from skimage import data, io, color
grayscale_image = data.camera()
image = color.gray2rgb(grayscale_image)

red_multiplier = [1, 0, 0]
yellow_multiplier = [1, 1, 0]

io.imshow(yellow_multiplier * image)
io.show()
io.imshow(red_multiplier * image)
io.show()

Fig. 5.5 Teinte de l'image

6. Modification d'une image avec scikit-image

1. Appliquer des filtres

Scikit-image intègre une grande variété d'outils d'édition d'images. Le module Filtres est l'un d'entre eux qui aide à diverses techniques de seuillage et à l'application de nombreux algorithmes de filtrage sur une image.

from skimage import filters
from skimage import data, io

image = data.astronaut()
image_median = filters.median(image)

io.imshow(image_median)
io.show()

Médiane renvoie une image lissée. En comparant avec l'original, voici à quoi ressemblera la sortie.

Fig 6.1 Image lisse et Image originale

2. Réglage de la luminosité

Le module d'exposition de scikit-image est très utile pour analyser les intensités lumineuses des images à l'aide d'histogrammes.

from skimage import exposure, io, data
image = data.rocket()
image_bright = exposure.adjust_gamma(image, gamma=0.5)
image_dark = exposure.adjust_gamma(image, gamma=2)

io.imshow(image)
io.show()

io.imshow(image_bright)
io.show()

io.imshow(image_dark)
io.show()

Par défaut, la valeur gamma est 1.

Sortie :

Fig. 6.2 Images originales, plus claires et plus sombres (de gauche à droite)

7. Segmentation d'image à l'aide de scikit-image

Le processus de division d'une image en segments ou mieux connu sous le nom de pixels pour mettre en évidence et détecter les zones d'intérêt dans une image qui aiderait à une analyse d'image plus efficace est connu sous le nom de segmentation d'image. Il existe de nombreux algorithmes tels que Chan-Vese, Random walker, Felzenswalb, etc. pour aider à segmenter une image. Scikit fournit des modules intégrés de certains de ces algorithmes de segmentation. Voyons un exemple très simple de segmentation d'image.

#import the required modules and image
from skimage import data, io, feature, segmentation
image = data.coins()

#use canny edge detector from feature module
edges = feature.canny(image, sigma=3)

#use mark_boundaries from segmentation module to mark the edges and display the image
io.imshow(segmentation.mark_boundaries(image, edges))
io.show()

Le module de fonctionnalités contient une large gamme de fonctions pour atteindre la détection d'objets et la segmentation d'images. Le rusé() la fonction en est une. Il s'agit d'un détecteur de contours à plusieurs étages qui, comme son nom l'indique, détecte les contours des objets présents dans l'image. Nous avons utilisé le paramètre sigma comme 3 ; cela réduit efficacement le bruit et donne un avantage clair.

Un autre module utilisé est la segmentation. Le module de segmentation tel que mentionné précédemment intègre de nombreux algorithmes ainsi que diverses fonctions de détection d'objets et de segmentation d'images. Nous avons utilisé mark_boundaries()  qui marquera les limites détectées par le détecteur de bord intelligent. Le code exécuté affichera la sortie suivante.

Figure 7.1 Segmentation

8. Histogramme

Wikipedia décrit l'histogramme d'image comme un type d'histogramme qui agit comme une représentation graphique de la distribution tonale dans une image numérique. L'intensité d'une image à chaque pixel différent en fonction de sa couleur est représentée à l'aide d'un histogramme. Le rouge, le vert et le bleu ont chacun un histogramme correspondant; les intensités étant de 0 au noir pur et de 255 au blanc pur.

Prenons un exemple simple d'histogramme.

from skimage import data
import matplotlib.pyplot as plt
image = data.coins()
histogram = plt.hist(image.ravel(), bins=8)
plt.show()

L'histogramme est tracé à l'aide de plt.hist() fonction de la bibliothèque Matplotlib. La gamme d'intensités, comme mentionné précédemment, est de 0 à 255 soit un total de 256 cases. Parfois, la représentation de chaque valeur d'intensité n'est pas nécessaire. Dans ces cas, nous pouvons les quantifier en plusieurs groupes appelés bacs. Ici, nous avons tracé l'histogramme en utilisant 8 bacs.

Sortie :

Figure 8.1 Histogramme

Prenons un autre exemple d'histogramme utilisant le module d'exposition de scikit, avec la bibliothèque matplotlib.

from skimage import data
import matplotlib.pyplot as plt
from skimage.exposure import histogram
image = data.coins()
hist = histogram(image)
plt.plot(hist[0])
plt.show()

Sortie :

Fig 8.2 Histogramme avec Scikit

Remarque :Assurez-vous que le package matplotlib est installé.

L'histogramme a de nombreuses applications dans le traitement d'image, notamment le seuillage, le réglage de la luminosité et du contraste, l'analyse d'une image, etc. Le seuillage est connu pour être la méthode la plus simple de segmentation d'image.

9. Seuil d'image à l'aide de scikit-image

Le seuil est très pratique lorsqu'il s'agit d'isoler des objets dans une image pour des applications telles que la reconnaissance faciale et la détection d'objets. Il sépare principalement l'arrière-plan du premier plan et constitue donc la méthode la plus simple de segmentation d'image.

Le seuillage fonctionne mieux dans les images à contraste élevé. Il existe deux types de seuillage dans Scikit-Global et Local. Le seuil global est basé sur un histogramme et fonctionne bien avec un arrière-plan uniforme. Le seuil local est adaptatif et est utilisé pour les images avec des arrière-plans inégalement éclairés.

Étapes de base pour le seuillage :

  1. Convertir une image RVB en niveaux de gris.
  2. Définissez une valeur seuil, par exemple 127.
  3. Utilisez l'opérateur ">" pour le seuillage et "<=" pour le seuillage inversé.
  4. Afficher l'image.
from skimage import data, io

image = data.camera()
thresh = 127

binary = image > thresh 
#binary = image <= thresh --for inverted thresholding 

io.imshow(binary)
io.show()

Fig 9 Seuil et seuil inversé

1. Seuil global

Comme mentionné ci-dessus, le seuillage global est appliqué lorsque l'image est très contrastée et a un fond uniforme. Dans un premier temps, appelons tous les algorithmes de seuillage global. Les appliquer sur l'image sélectionnée présente la sortie de plusieurs images.

from skimage.filters import try_all_threshold
from skimage import data, io
image = data.page()
thresh = try_all_threshold(image)
io.show()

Sortie :

Fig 9.1.1 Tous les seuils globaux

Ou nous pouvons en prendre un, supposons, threshold_otsu.

from skimage.filters import threshold_otsu
from skimage import data, io

image = data.page()

thresh = threshold_otsu(image)
binary = image > thresh

io.imshow(binary)
io.show()

Sortie :

2. Seuil local

En cas de doute, utilisez le seuil local. Le seuil local divise l'image en petites régions et lui applique la valeur de seuil.

from skimage.filters import threshold_local
from skimage import data, io

image = data.page()

thresh = threshold_local(image, block_size=35, offset=10)
binary = image > thresh

io.imshow(binary)
io.show()

Nous avons défini block_size sur 35 et offset sur 10, qui est la constante pour équilibrer le contraste opposé afin d'obtenir une image plus claire.

Sortie :

Fig 9.2.1 Seuil local

Grâce aux observations, il est clair que le seuil local obtient de meilleurs résultats dans ce cas.

Notes de fin

Résumant l'intégralité du didacticiel de scikit-image, nous avons commencé par l'installation de base et l'importation du package skimage. Ensuite, nous avons affiché et enregistré les images à l'aide du module io. En allant plus loin, nous avons appris la manipulation des formes suivie de la manipulation des couleurs dans scikit-image. Sous manipulation de forme, nous avons essentiellement travaillé avec la bibliothèque de transformation pour la rotation et le redimensionnement des images. La manipulation des couleurs a fondamentalement divisé les images en images en niveaux de gris et en couleurs. Le fonctionnement sur différents canaux de couleur ainsi que les conversions entre différents modèles de couleurs ont été effectués à l'aide du module de couleur.

En avançant plus profondément, nous avons découvert que scikit-image aide grandement dans le processus d'édition d'images. Bien qu'il puisse exister de nombreux outils pour réaliser efficacement les modifications souhaitées, nous en avons implémenté deux. Le module filtres qui utilisait la fonction médiane et le module exposition qui ajustait la correction gamma de l'image.

Et enfin, nous sommes arrivés à l'approche la plus appliquée qui a de nombreuses applications dans divers domaines. La segmentation des images. La segmentation d'image nous a guidés pour réaliser qu'une image numérique est, en fait, un tableau de nombres pixellisés. Scikit-image fournit de nombreux algorithmes de segmentation d'images. En lançant un programme de détection d'objet de base, nous avons détecté les bords de l'objet présent dans l'image et marqué les limites.

Les histogrammes donnent des détails explicites sur les intensités de l'image. Par conséquent, nous avons tracé des histogrammes en utilisant à la fois les bibliothèques matplotlib et scikit-image. En conclusion de notre voyage à travers l'apprentissage de l'image scikit, nous avons enfin mis en œuvre le seuillage. Il existait différents algorithmes pour atteindre la valeur de seuil optimale, et c'était la méthode la plus simple pour atteindre la segmentation d'image.

En conclusion, il existe d'innombrables applications de scikit-image dans le traitement d'image et de nombreuses fonctions plus avancées qui, combinées à d'autres bibliothèques telles que NumPy et Scipy, produiraient des résultats étonnants. Scikit-image étant basé sur python et extrêmement bien documenté est donc fortement préféré.

Scikit-image est bien documenté; vous pouvez trouver une documentation détaillée sur son site officiel, ici.