Python >> Tutoriel Python >  >> Python

Oreiller :introduction à la manipulation d'images de base en Python

Dans cet article, nous fournissons une introduction au module Python Pillow. Il est utile d'avoir une certaine expérience dans le traitement d'images, car il est à la base de diverses applications :post-traitement automatique des photographies, génération de vignettes en Python pour le contenu en ligne et prétraitement des images pour l'apprentissage automatique, entre autres.

Le module Python Pillow est un fork de la Python Image Library (PIL). L'oreiller doit être installé par l'utilisateur. La façon la plus simple de le faire est d'utiliser pip. Pour plus d'informations générales, des didacticiels ou des références sur la fonctionnalité, consultez la documentation officielle.

Pour ceux d'entre vous qui débutent dans la programmation, cette piste est un bon point de départ. Il ne suppose aucune connaissance préalable en programmation ou en informatique. Si vous êtes un lecteur régulier de ce blog, vous remarquerez peut-être quelques changements destinés à rendre l'apprentissage de Python encore plus facile. Consultez cet article pour un aperçu des changements.

Ouvrir des images

Il existe plusieurs formats d'image avec lesquels vous pouvez travailler à l'aide du module Python Pillow. Vous êtes probablement plus familier avec les formats d'image raster tels que JPG, PNG et GIF, entre autres.

Les images raster ont un nombre fixe de pixels en fonction de la résolution de l'image, et chaque pixel a une couleur définie. Si vous zoomez suffisamment sur une image raster, les pixels deviennent plus apparents. La grande majorité des images sont stockées de cette manière.

Les images vectorielles, quant à elles, utilisent des courbes définies par des équations mathématiques pour créer des images. Vous pouvez continuer à zoomer sur une image vectorielle et les courbes restent lisses. SVG et EPS sont deux exemples de ce format de fichier.

Cependant, travailler avec des images vectorielles en Python peut être un peu délicat, car cela implique d'utiliser d'autres bibliothèques spécialisées. Pour plus de simplicité, nous limitons notre discussion au format d'image raster familier.

Pour ouvrir et afficher une image à l'aide du module Python Pillow, importez le module Image et ouvrez l'image comme suit :

>>> from PIL import Image
>>> im = Image.open('image.png', mode='r')
>>> im.show()

La fonction renvoie un Image objet, que vous pouvez commencer à analyser et à modifier. Le mot-clé facultatif mode définit si l'image est ouverte en mode lecture ou écriture. Le deuxième format de mot-clé facultatif définit une liste ou un tuple de formats pour essayer de charger le fichier.

Le module Python Pillow prend en charge plus de 30 types de fichiers raster différents pour la lecture. Cependant, la prise en charge de l'écriture de fichiers est moins étendue. Si vous travaillez avec JPG, par exemple, la procédure pour ouvrir un fichier est la même que ci-dessus. Pour afficher l'image, vous pouvez utiliser le show() méthode sur le Image objet. Cela affiche l'image dans une fenêtre séparée et est surtout utile à des fins de débogage.

L'objet im a plusieurs méthodes qui fournissent des informations sur une image. Le format , mode , et size fournissent des informations clés sur votre image. Essayez-les pour voir quelles informations ils renvoient. Ces méthodes seront utiles plus tard. Vous pouvez également trouver la résolution d'une image en utilisant le info méthode, qui renvoie un dictionnaire contenant la clé 'dpi '.

Modifier des images

La force du module Python Pillow est son utilité dans la modification des images. De nombreuses fonctions de pré- et post-traitement d'image sont incluses. Ci-dessous, nous examinons certains des plus utiles.

Un bon point de départ est de connaître la taille de votre image. Pour cela, il suffit d'appeler la méthode size sur un Image objet, qui renvoie un tuple avec la largeur et la hauteur de l'image en pixels.

Vous pouvez générer automatiquement des vignettes en Python en utilisant le thumbnail() méthode, qui est utile si vous êtes dans le domaine de la production de contenu en ligne. Il prend un argument obligatoire size – un tuple de (width, height ) et un argument facultatif resample . Pour voir un bel exemple, y compris comment gérer certaines erreurs, consultez la page des didacticiels dans la documentation.

Si vous souhaitez préparer un grand nombre de photos pour l'impression, il est utile de toutes les convertir dans un format d'image standard. Le rapport d'aspect modifie la composition d'une photo et la façon dont elle est perçue. Un rapport d'aspect de 1:1 est bon pour les photos de profil, et les rapports d'aspect de 3:2 ou 5:4 sont courants dans la photographie et les tirages d'art.

Au fait, si vous avez besoin de plus d'informations sur la gestion automatique d'un grand nombre de fichiers en Python, consultez cet article.

Pour modifier le rapport d'aspect de vos images, vous pouvez essayer le resize , qui vous oblige à spécifier les nouvelles dimensions de hauteur et de largeur en pixels. Cependant, cela déforme l'image si un rapport d'aspect différent est utilisé.

Recadrer des images en Python, c'est mieux. Pour le démontrer, nous avons d'abord besoin d'une photo d'un mignon bébé chèvre. Nous supposons qu'il s'appelle 'goat.jpg' et qu'il est enregistré dans votre répertoire de travail :

	>>> from PIL import Image
	>>> im = Image.open('goat.jgp')
	>>> im.show()

Comme indiqué précédemment, cela ouvre l'image suivante dans une nouvelle fenêtre.

Utilisation du size méthode sur le Image objet, nous trouvons que l'image a une taille de (1124, 750), donnant un rapport d'aspect de 3:2. Nous pouvons le changer en un rapport hauteur/largeur de 1:1 comme suit :

>>> height, width = 500, 500
>>> left, upper, right, lower = 60, 200, width+60, height+200
>>> cropped_image = im.crop((left, upper, right, lower))
>>> cropped_image.show()

Le code ci-dessus produit l'image suivante, encadrant joliment cet adorable petit bonhomme au centre.

Dans le code ci-dessus, nous définissons les variables left , upper , right , et lower , qui spécifient les coordonnées en pixels de la région à recadrer. Remarquez que nous avons dû définir cela manuellement pour que la chèvre soit bien encadrée. Cela dit, il est possible d'automatiser cela en définissant un point dans l'image et en recadrant autour de celui-ci.

La bibliothèque Python Pillow est livrée avec de nombreuses fonctions préprogrammées qui vous aident à tirer le meilleur parti de vos images. Celles-ci incluent des fonctions pour convertir une image en niveaux de gris et des fonctions pour régler la luminosité, le contraste et la netteté, entre autres. Ceux-ci sont inclus dans le ImageOps et ImageEnhance modules de la bibliothèque Python Pillow.

Appliquons quelques-unes de ces fonctions à notre objet image cropped_image nous avons défini plus haut. Nous convertissons l'image en niveaux de gris et améliorons la netteté d'un facteur de 1,2 :

>>> from PIL import ImageOps, ImageEnhance
>>> im_gray = ImageOps.grayscale(cropped_image)
>>> im_sharp = ImageEnhance.Sharpness(im_gray).enhance(1.2)
>>> im_sharp.show()

Un autre ensemble d'outils utiles est contenu dans le ImageFilter module. Vous trouverez ici quelques fonctions de traitement d'image utiles si vous êtes intéressé par l'apprentissage automatique avec des données d'image.

Comme nous l'avons déjà dit, Python est idéal pour les projets d'apprentissage automatique. Par exemple, si vous programmez une application de détection d'objets, en utilisant EDGE_ENHANCE ou FIND_EDGES sur vos images d'entrée peut aider à augmenter la précision de votre application. Consultez la documentation si vous souhaitez obtenir plus d'informations sur ces filtres.

Traitement d'image Python plus avancé

Lorsque nous chargeons notre image à l'aide du module Python Pillow, les valeurs de pixel individuelles sont stockées dans une structure de données. Cela signifie que nous pouvons manipuler notre image pixel par pixel, ce qui ouvre tout un éventail de possibilités intéressantes comme la création de filtres personnalisés.

Nous pouvons accéder aux valeurs de pixel de notre image recadrée comme suit :

>>> pixels = list(cropped_image.getdata())

Le get_data La méthode renvoie un objet séquence aplati pour contenir les valeurs de pixel les unes après les autres. La variable pixels est une liste de tuples, et chaque tuple contient les valeurs RVB pour chaque pixel. La méthode contient un argument facultatif, band, qui vous permet de renvoyer une seule bande d'une image RVB en fournissant un index :0 pour la bande 'R', 1 pour la bande 'G' et 2 pour la bande 'B' . La longueur du pixels la liste est 250.000 , ce qui correspond à sa taille de 500 x 500 (hauteur x largeur).

Disons que nous voulons créer un filtre personnalisé en modifiant les valeurs de pixel. Pour rendre ce que nous faisons ici un peu plus clair, nous séparons les canaux à l'aide d'une compréhension de liste et les reformulons sous forme de tableaux à l'aide de NumPy :

>>> import numpy as np
>>> input_R = np.array([pix[0] for pix in pixels])
>>> input_G = np.array([pix[1] for pix in pixels])
>>> input_B = np.array([pix[2] for pix in pixels])

Maintenant, pour créer un filtre, nous modifions les canaux comme suit :

>>> output_R = (input_R*0.6358) + (input_G*0.4614) + (input_B*0.1134)
>>> output_G = (input_R*0.2093) + (input_G*0.8116) + (input_B*0.1008)
>>> output_B = (input_R*0.1324) + (input_G*0.3204) + (input_B*0.4786)

Assemblons les tableaux de sortie et assurons-nous que le résultat a la bonne forme (hauteur, largeur, canaux) :

>>> new_pixels = np.array([output_R, output_G, output_B]).T.reshape(500, 500, 3)

En mode RVB, chaque canal de couleur est représenté par un entier compris entre 0 et 255. Nous devons limiter les valeurs de pixel à cette plage, puis convertir les éléments du tableau dans le type de données correct :

>>> new_pixels[new_pixels>255]=255
>>> new_pixels = new_pixels.astype(np.uint8)

La dernière étape consiste à convertir notre tableau de valeurs de pixels en un Image objectez et jetez un coup d'œil à notre travail acharné :

>>> new_image = Image.fromarray(np.array(new_pixels))
>>> new_image.show()

Où puis-je aller ?

Il y a plus à Pillow que nous ne pouvons couvrir dans cet article. Nous aimerions vous encourager à prendre ce que vous avez appris ici et à commencer à expérimenter avec vos propres images. Vous pouvez peut-être créer votre propre filtre d'image ou automatiser le post-traitement de vos photos.

Comme nous l'avons mentionné, les aspirants scientifiques des données devraient s'en servir comme base pour commencer à explorer la classification d'images ou la détection d'objets. Bonne chance !