Traitement d'image OpenCV

Traitement D Image Opencv



Nous allons étudier les méthodes de traitement d'image dans cet article. Nous examinerons certains sujets fondamentaux mais critiques en vision par ordinateur et en apprentissage automatique. Ces techniques fondamentales de traitement d'images peuvent résoudre des problèmes complexes, tels que des ensembles de données. En conséquence, il existe six étapes fondamentales dans le traitement d'image, qui sont énumérées ci-dessous :
  1. Traduction d'images
  2. Rotation des images
  3. Arithmétique des images
  4. Retournement d'image
  5. Recadrage d'image
  6. Redimensionnement d'image

Nous allons maintenant expliquer en détail tous les sujets de traitement d'image mentionnés ci-dessus.

1. Traduction d'images

La traduction d'image est une méthode de traitement d'image qui nous aide à déplacer l'image le long des axes x et y. Nous pouvons déplacer l'image vers le haut, le bas, la droite, la gauche ou n'importe quelle combinaison.







Nous pouvons définir la matrice de traduction avec le symbole M, et nous pouvons la représenter sous forme mathématique, comme indiqué ci-dessous :





Nous pouvons comprendre le concept de l'image de traduction grâce à ce programme.





Code Python : Nous conserverons le nom du programme suivant comme traduire.py .

# importer les packages requis

importer numpy comme par exemple.

importer argumenter

importer imutil

importer cv2

# nous implémentons l'analyseur d'arguments

ap_obj = argumenter. ArgumentParser ( )

ap_obj. ajouter_argument ( '-k' , '--image' , obligatoire = Vrai ,

aider = 'emplacement du fichier image' )

arguments = à qui ( ap_obj. parse_args ( ) )

# charger l'image et l'afficher à l'écran

image = cv2. imlu ( arguments [ 'image' ] )

cv2. imshow ( 'Image originale' , image )

# La traduction de l'image est une matrice NumPy qui est donnée ci-dessous :

# [[1, 0, décalageX], [0, 1, décalageY]]

# Nous allons utiliser la matrice NumPy ci-dessus pour décaler les images le long de la

# directions de l'axe x et de l'axe y. Pour cela, nous devons simplement passer les valeurs de pixel.

# Dans ce programme, nous allons déplacer l'image de 30 pixels vers la droite

# et 70 pixels vers le bas.

translation_mat = par exemple. float32 ( [ [ 1 , 0 , 30 ] , [ 0 , 1 , 70 ] ] )

image_translation = cv2. warpAffine ( image , translation_mat ,

( image. façonner [ 1 ] , image. façonner [ 0 ] ) )

cv2. imshow ( 'Traduction d'image vers le bas et vers la droite' , image_translation )

# maintenant, nous allons utiliser la matrice NumPy ci-dessus pour décaler les images le long de la

# Directions de l'axe des x (à gauche) et de l'axe des y (en haut).

# Ici, nous allons déplacer les images de 50 pixels vers la gauche

# et 90 pixels vers le haut.

translation_mat = par exemple. float32 ( [ [ 1 , 0 , - cinquante ] , [ 0 , 1 , - 90 ] ] )

image_translation = cv2. warpAffine ( image , translation_mat ,

( image. façonner [ 1 ] , image. façonner [ 0 ] ) )

cv2. imshow ( 'Traduction d'image vers le haut et vers la gauche' , image_translation )

cv2. waitKey ( 0 )

Lignes 1 à 5 : Nous importons tous les packages requis pour ce programme, comme OpenCV, argparser et NumPy. Veuillez noter qu'il existe une autre bibliothèque qui est imutils. Ce n'est pas un paquet d'OpenCV. Ceci est juste une bibliothèque qui montrera facilement le même traitement d'image.



La bibliothèque imutils ne sera pas incluse automatiquement lors de l'installation d'OpenCV. Donc pour installer les imutils, nous devons utiliser la méthode suivante :

pip installer imutils

Lignes 8 à 15 : Nous avons créé notre agrparser et chargé notre image.

Lignes 24 à 25 : Cette section du programme est l'endroit où la traduction se produit. La matrice de translation nous indique de combien de pixels l'image sera déplacée vers le haut ou vers le bas ou vers la gauche ou la droite. Comme OpenCV exige que la valeur de la matrice soit dans un tableau à virgule flottante, la matrice de traduction prend des valeurs dans des tableaux à virgule flottante.

La première ligne de la matrice de traduction ressemble à ceci :

Cette ligne de la matrice est pour l'axe des x. La valeur de t X décidera si l'image sera décalée vers la gauche ou vers la droite. Si nous passons une valeur négative, cela signifie que l'image sera décalée vers la gauche, et si la valeur est positive, cela signifie que l'image sera décalée vers la droite.

Nous allons maintenant définir la deuxième ligne de la matrice comme suit :

Cette ligne de la matrice correspond à l'axe des ordonnées. La valeur de t Oui décidera si l'image sera décalée vers le haut ou vers le bas. Si nous passons une valeur négative, cela signifie que l'image sera décalée vers le haut, et si la valeur est positive, cela signifie que l'image sera décalée vers le bas.

Dans le programme précédent à la ligne 24, nous définissons le t X = 30 et le t Oui = 70. Nous déplaçons donc l'image de 30 pixels vers la droite et de 70 pixels vers le bas.

Mais le processus principal de traduction d'image a lieu à la ligne 25, où nous définissons la matrice de traduction cv2.warpAffine . Dans cette fonction, nous passons trois paramètres : le premier paramètre est l'image, le deuxième paramètre est la matrice de traduction et le troisième paramètre est la dimension de l'image.

Ligne 27 : La ligne 27 affichera le résultat dans la sortie.

Maintenant, nous allons implémenter une autre matrice de traduction pour la gauche et le haut. Pour cela, nous devons définir les valeurs en négatif.

Ligne 33 à 34 : Dans le programme précédent à la ligne 33, nous définissons le t X = -50 et le t Oui = -90. Nous déplaçons donc l'image de 50 pixels vers la gauche et de 90 pixels vers le haut. Mais le processus principal de traduction d'image a lieu à la ligne 34, où nous définissons la matrice de traduction cv2.warpAffine .

Ligne 36 : La ligne 36 affichera le résultat comme indiqué dans la sortie.

Pour exécuter le code précédent, nous devons donner le chemin de l'image comme indiqué ci-dessous.

Production: python translate.py –image écureuil.jpg

Maintenant, nous allons implémenter le même programme de traduction d'image en utilisant le imutil bibliothèque. Cette librairie est très simple d'utilisation pour le traitement d'image. Dans cette bibliothèque, nous n'avons pas à penser à la cv2.warpAffine parce que cette bibliothèque s'en chargera. Implémentons donc ce programme de traduction d'images à l'aide de la bibliothèque imutils.

Code Python : Nous conserverons le nom du programme suivant comme translate_imutils.py .

# importer les packages nécessaires

importer numpy comme par exemple.

importer argumenter

importer imutil

importer cv2

# Cette fonction implémente la traduction d'image et

# renvoie l'image traduite à la fonction appelante.

définitivement Traduire ( image , X , Oui ) :

translation_matrix = par exemple. float32 ( [ [ 1 , 0 , X ] , [ 0 , 1 , Oui ] ] )

image_translation = cv2. warpAffine ( image , translation_matrix ,

( image. façonner [ 1 ] , image. façonner [ 0 ] ) )

retour image_translation

# construire l'analyseur d'arguments et analyser les arguments

ap = argumenter. ArgumentParser ( )

ap. ajouter_argument ( '-je' , '--image' , obligatoire = Vrai , aider = 'Chemin vers l'image' )

arguments = à qui ( ap. parse_args ( ) )

# charger l'image et l'afficher à l'écran

image = cv2. imlu ( arguments [ 'image' ] )

cv2. imshow ( 'Image originale' , image )

image_translation = imutil. Traduire ( image , dix , 70 )

cv2. imshow ( 'Traduction de l'image vers la droite et vers le bas' ,

image_translation )

cv2. waitKey ( 0 )

Lignes 9 à 13 : Cette section du programme est l'endroit où la traduction se produit. La matrice de translation nous informe de combien de pixels l'image sera déplacée vers le haut ou vers le bas ou vers la gauche ou la droite.

Ces lignes ont déjà été expliquées, mais nous allons maintenant créer une fonction appelée translate () et lui envoyer trois paramètres distincts. L'image elle-même sert de premier paramètre. Les valeurs x et y de la matrice de traduction correspondent aux deuxième et troisième paramètres.

Noter : Il n'est pas nécessaire de définir cette fonction de traduction dans le programme car elle est déjà incluse dans le package de la bibliothèque imutils. Je l'ai utilisé dans le programme par souci d'explication simple. Nous pouvons appeler cette fonction directement avec les imutils, comme indiqué à la ligne 24.

Ligne 24 : Le programme précédent montrera qu'à la ligne 24, nous définissons le tx = 10 et le ty = 70. Nous déplaçons donc l'image de 10 pixels vers la droite et de 70 pixels vers le bas.

Dans ce programme, nous ne nous soucions pas des fonctions cv2.warpAffine car elles se trouvent déjà dans le package de la bibliothèque imutils.

Pour exécuter le code précédent, nous devons donner le chemin de l'image, comme indiqué ci-dessous :

Production:

python imutils. py --image écureuil. jpg

2. Rotation des images

Nous avons expliqué comment traduire (c'est-à-dire décaler) une image vers le haut, le bas, la gauche et la droite dans la leçon précédente (ou toute combinaison). Ensuite, nous discuterons de la rotation en ce qui concerne le traitement d'image.

Une image est tournée d'un angle, thêta, dans un processus connu sous le nom de rotation. L'angle de rotation de l'image sera représenté par thêta. De plus, je fournirai par la suite la fonction pratique de rotation pour simplifier la rotation des images.

Semblable à la translation, et peut-être sans surprise, à la rotation d'un angle, thêta est déterminé en construisant une matrice M au format suivant :

Cette matrice peut faire pivoter un vecteur thêta degrés (dans le sens antihoraire) autour de l'origine donnée (x, y) - plan cartésien. Normalement, dans ce scénario, l'origine serait le centre de l'image, mais en réalité, nous pourrions désigner n'importe quel point aléatoire (x, y) comme notre centre de rotation.

L'image pivotée R est ensuite créée à partir de l'image originale I en utilisant une simple multiplication matricielle : R = IM

OpenCV, d'autre part, offre en outre la capacité de (1) mettre à l'échelle (c'est-à-dire redimensionner) une image et (2) offrir un centre de rotation arbitraire pour effectuer la rotation autour.

Notre matrice de rotation modifiée M est illustrée ci-dessous :

Commençons par ouvrir et générer un nouveau fichier appelé rotation.py :

# importer les packages requis

importer numpy comme par exemple.

importer argumenter

importer imutil

importer cv2

# création de l'objet argumentparser et de l'argument d'analyse

apobj = argumenter. ArgumentParser ( )

apobj. ajouter_argument ( '-k' , '--image' , obligatoire = Vrai , aider = 'chemin de l'image' )

arguments = à qui ( apobj. parse_args ( ) )

image = cv2. imlu ( arguments [ 'image' ] )

cv2. imshow ( 'Image originale' , image )

# Calculer le centre de l'image en utilisant les dimensions de l'image.

( la taille , largeur ) = image. façonner [ : 2 ]

( centreX , centreY ) = ( largeur / 2 , la taille / 2 )

# Maintenant, en utilisant cv2, nous allons faire pivoter l'image de 55 degrés pour

# déterminer la matrice de rotation en utilisant getRotationMatrix2D()

rotationMatrice = cv2. getRotationMatrix2D ( ( centreX , centreY ) , 55 , 1.0 )

RotatedImage = cv2. warpAffine ( image , rotationMatrice , ( largeur , la taille ) )

cv2. imshow ( 'A fait pivoter l'image de 55 degrés' , RotatedImage )

cv2. waitKey ( 0 )

# L'image sera maintenant tournée de -85 degrés.

rotationMatrice = cv2. getRotationMatrix2D ( ( centreX , centreY ) , - 85 , 1.0 )

RotatedImage = cv2. warpAffine ( image , rotationMatrice , ( largeur , la taille ) )

cv2. imshow ( 'A fait pivoter l'image de -85 degrés' , RotatedImage )

cv2. waitKey ( 0 )

Lignes 1 à 5 : Nous importons tous les packages requis pour ce programme, comme OpenCV, argparser et NumPy. Veuillez noter qu'il existe une autre bibliothèque qui est imutils. Ce n'est pas un paquet d'OpenCV. Ceci est juste une bibliothèque qui sera utilisée pour montrer facilement le même traitement d'image.

La bibliothèque imutils ne sera pas incluse automatiquement lors de l'installation d'OpenCV. OpenCV installe les imutils. Nous devons utiliser la méthode suivante :

pip installer imutils

Lignes 8 à 14 : Nous avons créé notre agrparser et chargé notre image. Dans cet analyseur d'arguments, nous n'utilisons qu'un seul argument d'image, qui nous indiquera le chemin de l'image que nous utiliserons dans ce programme pour démontrer la rotation.

Lors de la rotation d'une image, nous devons définir le point de pivot de la rotation. La plupart du temps, vous voudrez faire pivoter une image autour de son centre, mais OpenCV vous permet de choisir n'importe quel point aléatoire à la place. Tournons simplement l'image autour de son centre.

Lignes 17 à 18 prenez la largeur et la hauteur de l'image, respectivement, puis divisez chaque dimension par deux pour établir le centre de l'image.

Nous construisons une matrice pour faire pivoter une image de la même manière que nous avons défini une matrice pour traduire une image. Nous appellerons simplement le cv2.getRotationMatrix2D fonction sur la ligne 22 plutôt que de créer manuellement la matrice à l'aide de NumPy (ce qui peut être un peu lourd).

Le cv2.getRotationMatrix2D La fonction nécessite trois paramètres. La première entrée est l'angle de rotation souhaité (dans ce cas, le centre de l'image). Theta est ensuite utilisé pour spécifier de combien de degrés (dans le sens inverse des aiguilles d'une montre) nous allons faire pivoter l'image. Ici, nous allons faire pivoter l'image de 45 degrés. La dernière option est liée à la taille de l'image.

Indépendamment du fait que nous n'avons pas encore discuté de la mise à l'échelle d'une image, vous pouvez fournir ici un nombre à virgule flottante avec 1.0 indiquant que l'image doit être utilisée dans ses proportions d'origine. Cependant, si vous avez tapé une valeur de 2,0, la taille de l'image doublerait. Un nombre de 0,5 réduit ainsi la taille de l'image.

Ligne 22 à 23 : Après avoir reçu notre matrice de rotation M du cv2.getRotationMatrix2D fonction, nous faisons pivoter notre image en utilisant la cv2.warpAffine technique sur la ligne 23. La première entrée de la fonction est l'image que nous voulons faire pivoter. La largeur et la hauteur de notre image de sortie sont alors définies, ainsi que notre matrice de rotation M. Sur la ligne 23, l'image est alors tournée de 55 degrés.

Vous pouvez remarquer que notre image a été pivotée.

Lignes 28 à 30 constituent la deuxième rotation. Les lignes 22 à 23 du code sont identiques, sauf que cette fois nous tournons de -85 degrés au lieu de 55.

Nous avons simplement fait pivoter une image autour de son centre jusqu'à ce point. Et si nous souhaitions faire pivoter l'image autour d'un point aléatoire ?

Commençons par ouvrir et générer un nouveau fichier appelé rotation.py :

# importer les packages requis

importer numpy comme par exemple.

importer argumenter

importer imutil

importer cv2

# création de l'objet argumentparser et de l'argument d'analyse

ap_obj = argumenter. ArgumentParser ( )

ap_obj. ajouter_argument ( '-k' , '--image' , obligatoire = Vrai , aider = 'chemin de l'image' )

argument = à qui ( ap_obj. parse_args ( ) )

# charger l'image et l'afficher à l'écran

image = cv2. imlu ( argument [ 'image' ] )

cv2. imshow ( 'Image originale' , image )

# Calculer le centre de l'image en utilisant les dimensions de l'image.

( la taille , largeur ) = image. façonner [ : 2 ]

( centreX , centreY ) = ( largeur / 2 , la taille / 2 )

# Maintenant, en utilisant cv2, nous allons faire pivoter l'image de 55 degrés pour

# déterminer la matrice de rotation en utilisant getRotationMatrix2D()

rotationMatrice = cv2. getRotationMatrix2D ( ( centreX , centreY ) , 55 , 1.0 )

RotatedImage = cv2. warpAffine ( image , rotationMatrice , ( largeur , la taille ) )

cv2. imshow ( 'A fait pivoter l'image de 55 degrés' , RotatedImage )

cv2. waitKey ( 0 )

# L'image sera maintenant tournée de -85 degrés.

rotationMatrice = cv2. getRotationMatrix2D ( ( centreX , centreY ) , - 85 , 1.0 )

RotatedImage = cv2. warpAffine ( image , rotationMatrice , ( largeur , la taille ) )

cv2. imshow ( 'A fait pivoter l'image de -85 degrés' , RotatedImage )

cv2. waitKey ( 0 )

# rotation de l'image à partir d'un point arbitraire, pas du centre

rotationMatrice = cv2. getRotationMatrix2D ( ( centreX - 40 , centreY - 40 ) , 55 , 1.0 )

RotatedImage = cv2. warpAffine ( image , rotationMatrice , ( largeur , la taille ) )

cv2. imshow ( 'Rotation d'image à partir de points arbitraires' , RotatedImage )

cv2. waitKey ( 0 )

Ligne 34 à 35 : Maintenant, ce code devrait sembler assez courant pour faire pivoter un objet. Pour faire pivoter l'image autour d'un point situé à 40 pixels vers la gauche et 40 pixels au-dessus de son centre, nous demandons au cv2.getRotationMatrix2D fonction de prêter attention à son premier paramètre.

L'image produite lorsque nous appliquons cette rotation est illustrée ci-dessous :

Nous pouvons clairement voir que le centre de la rotation est maintenant la coordonnée (x, y), qui est de 40 pixels à gauche et 40 pixels au-dessus du centre calculé de l'image.

3. Arithmétique des images

En fait, l'arithmétique d'image n'est qu'un ajout de matrice avec quelques restrictions supplémentaires sur les types de données que nous aborderons plus tard.

Prenons un moment pour passer en revue quelques principes fondamentaux de l'algèbre linéaire.

Envisagez de combiner les deux matrices suivantes :

Quel résultat l'addition de la matrice produirait-elle ? La réponse simple est la somme des entrées de la matrice, élément par élément :

Assez simple, non?

Nous comprenons tous les opérations fondamentales d'addition et de soustraction à l'heure actuelle. Cependant, nous devons être conscients des restrictions imposées par notre espace colorimétrique et notre type de données lorsque nous travaillons avec des images.

Les pixels des images RVB, par exemple, se situent entre [0, 255]. Que se passe-t-il si nous essayons d'ajouter 10 à un pixel d'une intensité de 250 en le regardant ?

Nous arriverions à une valeur de 260 si nous appliquions les principes arithmétiques standards. 260 n'est pas une valeur valide, car les images RVB sont représentées sous forme d'entiers non signés 8 bits.

Alors que devrait-il se passer ? Devrions-nous exécuter une vérification pour nous assurer qu'aucun pixel n'est au-delà de la plage de [0, 255], en coupant chaque pixel pour qu'il ait une valeur comprise entre 0 et 255 ?

Ou devons-nous 'boucler' et effectuer une opération de module ? Conformément aux règles du module, l'ajout de 10 à 255 donnerait simplement une valeur de 9.

Comment les additions et les soustractions aux images au-delà de la plage de [0, 255] doivent-elles être gérées ?

La vérité est qu'il n'y a pas de bonne ou de mauvaise technique ; tout dépend de la façon dont vous travaillez avec vos pixels et de ce que vous espérez réaliser.

Mais rappelez-vous qu'il existe des différences entre l'ajout dans OpenCV et l'ajout dans NumPy. L'arithmétique du module et le 'bouclage' seront effectués par NumPy. En revanche, OpenCV exécutera le découpage et s'assurera que les valeurs de pixel ne quittent jamais la plage [0, 255].

Commençons par créer un nouveau fichier appelé arithmétique.py et l'ouvrir :

# python arithmétique.py --image écureuil.jpg

# importer les packages requis

importer numpy comme par exemple.

importer argumenter

importer imutil

importer cv2

# création de l'objet argumentparser et de l'argument d'analyse

apObj = argumenter. ArgumentParser ( )

apObj. ajouter_argument ( '-k' , '--image' , obligatoire = Vrai , aider = 'chemin de l'image' )

arguments = à qui ( apObj. parse_args ( ) )

image = cv2. imlu ( arguments [ 'image' ] )

cv2. imshow ( 'Image originale' , image )

'''

Les valeurs de nos pixels seront dans la plage [0, 255]

puisque les images sont des tableaux NumPy, qui sont stockés sous forme d'entiers 8 bits non signés.

Lors de l'utilisation de fonctions telles que cv2.add et cv2.subtract, les valeurs seront tronquées

à cette plage même s'ils sont ajoutés ou soustraits de l'extérieur de la

[0, 255] plage. Voici une illustration :

'''


imprimer ( 'maximum de 255 : {}' . format ( chaîne ( cv2. ajouter ( par exemple. uint8 ( [ 201 ] ) ,

par exemple. uint8 ( [ 100 ] ) ) ) ) )

imprimer ( 'minimum de 0 : {}' . format ( chaîne ( cv2. soustraire ( par exemple. uint8 ( [ 60 ] ) ,

par exemple. uint8 ( [ 100 ] ) ) ) ) )

'''

Lorsque vous effectuez des opérations arithmétiques avec ces tableaux à l'aide de NumPy,

la valeur s'enroulera autour plutôt que d'être écrêtée à la

[0, 255] plage. Lors de l'utilisation d'images, il est essentiel de garder cette

à l'esprit.

'''


imprimer ( 'enrouler autour: {}' . format ( chaîne ( par exemple. uint8 ( [ 201 ] ) + ex. uint8 ( [ 100 ] ) ) ) )

imprimer ( 'enrouler autour: {}' . format ( chaîne ( par exemple. uint8 ( [ 60 ] ) - par exemple. uint8 ( [ 100 ] ) ) ) )

'''

Multiplions la luminosité de chaque pixel de notre image par 101.

Pour ce faire, nous générons un tableau NumPy de la même taille que notre matrice,

rempli de uns, et multipliez-le par 101 pour produire un tableau rempli

avec 101s. Enfin, nous fusionnons les deux images.

Vous remarquerez que l'image est désormais 'plus lumineuse'.

'''


Matrice = par exemple. ceux ( image. façonner , dtype = 'uint8' ) * 101

image_ajoutée = cv2. ajouter ( image , Matrice )

cv2. imshow ( 'Résultat d'image ajouté' , image_ajoutée )

#De la même manière, nous pouvons assombrir notre image en prenant

# 60 loin de tous les pixels.

Matrice = par exemple. ceux ( image. façonner , dtype = 'uint8' ) * 60

image_soustraite = cv2. soustraire ( image , Matrice )

cv2. imshow ( 'Résultat de l'image soustraite' , image_soustraite )

cv2. waitKey ( 0 )

Lignes 1 à 16 sera utilisé pour effectuer notre processus normal, qui implique l'importation de nos packages, la configuration de notre analyseur d'arguments et le chargement de notre image.

Rappelez-vous comment j'ai précédemment discuté de la distinction entre l'ajout d'OpenCV et de NumPy ? Maintenant que nous l'avons couvert à fond, examinons un cas spécifique pour nous assurer que nous le comprenons.

Deux tableaux NumPy d'entiers non signés 8 bits sont définis sur ligne 26 . Une valeur de 201 est le seul élément du premier tableau. Bien qu'un seul membre soit dans le deuxième tableau, il a une valeur de 100. Les valeurs sont ensuite ajoutées à l'aide de la fonction cv2.add d'OpenCV.

Qu'attendez-vous du résultat ?

Conformément aux principes arithmétiques classiques, la réponse devrait être 301. Mais rappelez-vous que nous avons affaire à des entiers non signés de 8 bits, qui ne peuvent être que dans la plage [0, 255]. Parce que nous utilisons la méthode cv2.add, OpenCV gère le découpage et garantit que l'addition ne renvoie qu'un résultat maximum de 255.

La première ligne de la liste ci-dessous montre le résultat de l'exécution de ce code :

arithmétique. py

maximale de 255 : [ [ 255 ] ]

La somme a en effet produit un nombre de 255.

D'après cela, ligne 26 utilise cv2.subtract pour effectuer une soustraction. Une fois de plus, nous définissons deux tableaux NumPy d'entiers non signés 8 bits avec un seul élément dans chacun. La valeur du premier tableau est 60, tandis que la valeur du second tableau est 100.

Notre arithmétique dicte que la soustraction doit aboutir à une valeur de -40, mais OpenCV gère le découpage pour nous une fois de plus. Nous découvrons que la valeur a été réduite à 0. Notre résultat ci-dessous le démontre :

arithmétique. py

minimale de 0 : [ [ 0 ] ]

En utilisant cv2, soustrayez 100 de 60 soustraire, produisant la valeur 0.

Mais que se passe-t-il si nous utilisons NumPy à la place d'OpenCV pour effectuer les calculs ?

Lignes 38 et 39 résoudre ce problème.

Tout d'abord, deux tableaux NumPy d'entiers non signés de 8 bits avec un seul élément chacun sont définis. La valeur du premier tableau est 201, tandis que la valeur du second tableau est 100. Notre addition serait coupée et une valeur de 255 serait renvoyée si nous utilisions la fonction cv2.add.

NumPy, d'autre part, 's'enroule' et fait de l'arithmétique modulo plutôt que du découpage. NumPy revient à zéro une fois qu'une valeur de 255 est atteinte, puis recommence à compter jusqu'à ce que 100 étapes aient été atteintes. Ceci est confirmé par la première ligne de sortie, qui est illustrée ci-dessous :

arithmétique. py
enrouler autour: [ Quatre cinq ]

Ensuite, deux autres tableaux NumPy sont définis, l'un avec une valeur de 50 et l'autre avec 100. Cette soustraction serait ajustée par la méthode cv2.subtract pour renvoyer un résultat de 0. Mais nous sommes conscients qu'au lieu d'écrêter, NumPy exécute arithmétique modulo. Au lieu de cela, les procédures modulo s'enroulent et commencent à compter à rebours à partir de 255 une fois que 0 est atteint pendant la soustraction. Nous pouvons le voir à partir de la sortie suivante :

arithmétique. py

enrouler autour: [ 207 ]

Une fois de plus, notre sortie de terminal démontre la distinction entre le découpage et l'enroulement :

Il est crucial de garder à l'esprit le résultat souhaité lors de l'exécution de l'arithmétique entière. Souhaitez-vous que toutes les valeurs en dehors de la plage [0, 255] soient tronquées ? Utilisez ensuite les techniques d'arithmétique d'image intégrées d'OpenCV.

Souhaitez-vous que les valeurs s'enroulent si elles sont en dehors de la plage de [0, 255] et des opérations arithmétiques de module ? Les tableaux NumPy sont ensuite simplement ajoutés et soustraits comme d'habitude.

Ligne 48 définit un tableau NumPy unidimensionnel avec les mêmes dimensions que notre image. Une fois de plus, nous nous assurons que notre type de données est des entiers non signés de 8 bits. Nous multiplions simplement notre matrice de valeurs à un chiffre par 101 pour la remplir avec des valeurs de 101 au lieu de 1. Enfin, nous utilisons la fonction cv2.add pour ajouter notre matrice de 100 à l'image d'origine. Cela augmente l'intensité de chaque pixel de 101 tout en garantissant que toutes les valeurs qui tentent de dépasser 255 sont écrêtées dans la plage [0, 255].

Observez comment l'image est nettement plus lumineuse et apparaît plus 'délavée' que l'original. En effet, nous orientons les pixels vers des couleurs plus vives en augmentant leurs intensités de pixels de 101.

Afin de soustraire 60 de chaque intensité de pixel de l'image, nous établissons d'abord un deuxième tableau NumPy sur la ligne 54 qui est rempli avec les 60.

Les résultats de cette soustraction sont illustrés dans l'image suivante :

Les objets qui nous entourent apparaissent nettement plus sombres qu'auparavant. En effet, en soustrayant 60 de chaque pixel, nous déplaçons les pixels de l'espace colorimétrique RVB vers les régions les plus sombres.

4. Retournement d'image

Semblable à la rotation, retourner une image sur son axe x ou y est une autre option offerte par OpenCV. Même si les opérations de retournement ne sont pas utilisées aussi fréquemment, les connaître est incroyablement bénéfique pour diverses raisons que vous ne voyez peut-être pas immédiatement.

Nous développons un classificateur d'apprentissage automatique pour une petite start-up qui cherche à identifier les visages dans les images. Pour que notre système 'apprenne' ce qu'est un visage, nous aurions besoin d'une sorte d'ensemble de données avec des exemples de visages. Malheureusement, la société ne nous a fourni qu'un petit ensemble de données de 40 visages et nous ne sommes pas en mesure de recueillir plus d'informations.

Que faisons-nous alors ?

Puisqu'un visage reste un visage, qu'il soit en miroir ou non, nous pouvons retourner horizontalement chaque image d'un visage et utiliser les versions en miroir comme données d'entraînement supplémentaires.

Cet exemple peut sembler stupide et artificiel, mais il ne l'est pas. Le retournement est une stratégie délibérée utilisée par de puissants algorithmes d'apprentissage en profondeur pour produire plus de données pendant la phase de formation.

Il ressort clairement de ce qui précède que les méthodes de traitement d'image que vous apprenez dans ce module servent de base à de plus grands systèmes de vision par ordinateur.

Objectifs:

En utilisant le cv2.flip fonction, vous apprendrez à retourner une image à la fois horizontalement et verticalement dans cette session.

Le retournement est la prochaine manipulation d'image que nous étudierons. Les axes x et y d'une image peuvent être inversés ou même les deux. Avant de plonger dans le codage, il est préférable de regarder d'abord les résultats d'un retournement d'image. Voir une image qui a été retournée horizontalement dans l'image suivante :


Notez comment notre image originale est sur la gauche et comment l'image a été reflétée horizontalement sur la droite.

Commençons par créer un nouveau fichier appelé flipping.py .

Vous avez vu un exemple de retournement d'image, alors examinons le code :

# python flipping.py --image quirrel.jpg

# importer les packages requis

importer argumenter

importer cv2

# création de l'objet de l'analyseur d'arguments et analyse de l'argument

apObj = argumenter. ArgumentParser ( )

apObj. ajouter_argument ( '-je' , '--image' , obligatoire = Vrai , aider = 'chemin de l'image' )

argument = à qui ( apObj. parse_args ( ) )

image = cv2. imlu ( argument [ 'image' ] )

cv2. imshow ( 'Original' , image )

# retourner horizontalement l'image

image retournée = cv2. retourner ( image , 1 )

cv2. imshow ( 'Image retournée horizontalement' , image retournée )

# retourner l'image verticalement

image retournée = cv2. retourner ( image , 0 )

cv2. imshow ( 'Image retournée verticalement' , image retournée )

# retournement d'image le long des deux axes

image retournée = cv2. retourner ( image , - 1 )

cv2. imshow ( 'Retourné horizontalement et verticalement' , image retournée )

cv2. waitKey ( 0 )

Les étapes que nous prenons pour importer nos packages, analyser nos entrées et charger notre image à partir du disque sont gérées dans l lignes 1 à 12 .

En appelant la fonction cv2.flip sur Ligne 15 , il est simple de retourner une image horizontalement. L'image que nous cherchons à retourner et un code ou un drapeau spécifique qui spécifie comment retourner l'image sont les deux arguments nécessaires à la méthode cv2.flip.

Une valeur de code de retournement de 1 signifie que nous allons faire pivoter l'image autour de l'axe y pour la retourner horizontalement ( Ligne 15 ). Si nous spécifions un code de retournement de 0, nous souhaitons faire pivoter l'image autour de l'axe des x ( Ligne 19 ). Un flip code négatif ( Ligne 23 ) fait pivoter l'image sur les deux axes.

L'un des exemples les plus simples dans ce domaine consiste à retourner une image, ce qui est basique.

Ensuite, nous discuterons du recadrage des images et utiliserons des tranches de tableau NumPy pour extraire des portions d'image spécifiques.

5. Recadrage d'image

Le recadrage, comme son nom l'indique, est le processus de sélection et de suppression de la région d'intérêt (ou simplement du retour sur investissement), qui est la zone de l'image qui nous intéresse.

Le visage devrait être recadré à partir d'une image pour une application de détection de visage. De plus, si nous créons un script Python pour trouver des chiens dans des images, nous pourrions vouloir rogner le chien de l'image lorsque nous le localisons.

Objectifs: Notre objectif principal est de se familiariser et d'être à l'aise avec le découpage de tableaux NumPy pour recadrer des zones à partir d'une image.

Recadrage : Lorsque nous recadrons une image, notre objectif est d'éliminer les éléments extérieurs qui ne nous intéressent pas. Le processus de choix de notre retour sur investissement est souvent appelé le choix de notre région d'intérêt.

Créez un nouveau fichier appelé crop.py , ouvrez-le et ajoutez le code suivant :

# culture python.py

# importer les packages requis

importer cv2

# chargement et affichage de l'image à l'écran

image = cv2. imlu ( 'écureuil.jpg' )

imprimer ( image. façonner )

cv2. imshow ( 'Original' , image )

# Les tranches de tableau NumPy sont utilisées pour découper rapidement une image

# nous allons recadrer le visage de l'écureuil de l'image

écureuil = image [ 35 : 90 , 35 : 100 ]

cv2. imshow ( 'visage d'écureuil' , écureuil )

cv2. waitKey ( 0 )

# Et maintenant, ici on va recadrer tout le corps

# de l'écureuil

corps d'écureuil = image [ 35 : 148 , 23 : 143 ]

cv2. imshow ( 'Corps d'écureuil' , corps d'écureuil )

cv2. waitKey ( 0 )

Nous allons montrer le recadrage en Python et OpenCV en utilisant une image que nous chargeons à partir du disque sur Lignes 5 et 6 .

Image originale que nous allons recadrer

En utilisant uniquement des techniques de culture de base, nous visons à séparer le visage et le corps de l'écureuil de la zone environnante.

Nous utiliserons notre connaissance préalable de l'image et fournirons manuellement les tranches de tableau NumPy de l'endroit où le corps et le visage existent. Dans des conditions normales, nous utiliserions généralement des algorithmes d'apprentissage automatique et de vision par ordinateur pour reconnaître le visage et le corps dans l'image. Mais gardons les choses simples pour le moment et évitons d'utiliser des modèles de détection.

Nous pouvons identifier le visage dans l'image avec une seule ligne de code. Ligne 13 , Pour extraire une partie rectangulaire de l'image, à partir de (35, 35), nous fournissons des tranches de tableau NumPy (90, 100). Il peut sembler déroutant que nous alimentions le recadrage avec les index dans l'ordre de la hauteur en premier et de la largeur en second lieu, mais gardez à l'esprit qu'OpenCV stocke les images sous forme de tableaux NumPy. Par conséquent, nous devons fournir les valeurs de l'axe des ordonnées avant l'axe des abscisses.

NumPy nécessite les quatre index suivants pour effectuer notre recadrage :

Commencer : La coordonnée y au début. Pour cet exemple, nous commençons à y=35.

Fin y : La coordonnée y à la fin. Notre recadrage s'arrêtera lorsque y = 90.

Début x : Coordonnée x de début de la tranche. Le recadrage commence à x=35.

Fin x : Coordonnée de l'axe x de la fin de la tranche. A x=100, notre tranche est terminée.

De même, nous recadrons les régions (23, 35) et (143, 148) de l'image originale pour extraire le corps entier de l'image sur Ligne 19 .

Vous pouvez observer que l'image a été recadrée pour ne montrer que le corps et le visage.

6. Redimensionnement des images

Le processus d'augmentation ou de diminution de la largeur et de la hauteur d'une image est connu sous le nom de mise à l'échelle ou simplement de redimensionnement. Le rapport d'aspect, qui est la proportion de la largeur d'une image à sa hauteur, doit être pris en compte lors du redimensionnement d'une image. Si vous négligez le format d'image, les images mises à l'échelle peuvent apparaître compressées et déformées :

Notre image initiale est à gauche. Sur la droite, vous verrez deux images qui ont été mises à l'échelle sans conserver le rapport d'aspect, déformant la proportion de la largeur de l'image à sa hauteur. Lorsque vous redimensionnez vos images, vous devez généralement tenir compte du rapport d'aspect.

La technique d'interpolation utilisée par notre algorithme de redimensionnement doit également tenir compte de l'objectif de la fonction d'interpolation d'utiliser ces voisinages de pixels pour augmenter ou diminuer la taille de l'image.

En général, la réduction de la taille de l'image est beaucoup plus efficace. En effet, la suppression de pixels d'une image est tout ce que la fonction d'interpolation doit faire. D'autre part, la méthode d'interpolation aurait besoin de 'remplir les lacunes' entre les pixels qui n'existaient pas auparavant si la taille de l'image devait être augmentée.

Nous avons notre image originale sur la gauche. L'image a été réduite à la moitié de sa taille d'origine au centre, mais à part cela, il n'y a pas eu de perte de 'qualité' de l'image. Néanmoins, la taille de l'image a été considérablement agrandie sur la droite. Il apparaît maintenant 'gonflé' et 'pixelisé'.

Comme je l'ai déjà dit, vous voudrez généralement réduire la taille d'une image plutôt que de l'augmenter. En réduisant la taille de l'image, nous analysons moins de pixels et devons faire face à moins de « bruit », ce qui rend les algorithmes de traitement d'image plus rapides et plus précis.

La translation et la rotation sont les deux transformations d'image abordées jusqu'à présent. Nous allons maintenant voir comment redimensionner une image.

Sans surprise, nous redimensionnerons nos images en utilisant la méthode cv2.resize. Comme je l'ai indiqué précédemment, nous devons tenir compte du rapport d'aspect de l'image lors de l'utilisation de cette méthode. Mais avant d'entrer trop profondément dans les détails, permettez-moi de vous donner une illustration :

# python redimensionner.py --image écureuil.jpg

# importer les packages requis

importer argumenter

importer cv2

# création de l'objet de l'analyseur d'arguments et analyse de l'argument

apObj = argumenter. ArgumentParser ( )

apObj. ajouter_argument ( '-k' , '--image' , obligatoire = Vrai , aider = 'chemin de l'image' )

arguments = à qui ( apObj. parse_args ( ) )

# charger l'image et l'afficher à l'écran

image = cv2. imlu ( arguments [ 'image' ] )

cv2. imshow ( 'Original' , image )

# Afin d'éviter que l'image n'apparaisse de travers, le format d'image

# doit être considéré ou déformé ; par conséquent, nous découvrons ce que

# le rapport de la nouvelle image à l'image courante.

# Faisons la largeur de notre nouvelle image de 160 pixels.

aspect = 160,0 / image. façonner [ 1 ]

dimension = ( 160 , entier ( image. façonner [ 0 ] * aspect ) )

# cette ligne affichera les opérations de redimensionnement réelles

image redimensionnée = cv2. redimensionner ( image , dimension , interpolation = cv2. INTER_AREA )

cv2. imshow ( 'Largeur de l'image redimensionnée' , image redimensionnée )

# Et si on voulait changer la hauteur de l'image ? - en utilisant le

# même principe, on peut calculer le rapport d'aspect en fonction

# sur la hauteur plutôt que sur la largeur. Faisons l'échelle

# hauteur de l'image 70 pixels.

aspect = 70,0 / image. façonner [ 0 ]

dimension = ( entier ( image. façonner [ 1 ] * aspect ) , 70 )

# effectuer le redimensionnement

image redimensionnée = cv2. redimensionner ( image , dimension , interpolation = cv2. INTER_AREA )

cv2. imshow ( 'Hauteur de l'image redimensionnée' , image redimensionnée )

cv2. waitKey ( 0 )

Lignes 1 à 14 , Après avoir importé nos packages et configuré notre analyseur d'arguments, nous allons charger et afficher notre image.

Lignes 20 et 21 : Le codage pertinent commence dans ces lignes . Le rapport d'aspect de l'image doit être pris en considération lors du redimensionnement. La proportion entre la largeur et la hauteur de l'image est connue sous le nom de rapport d'aspect.

Hauteur largeur est le rapport d'aspect.

Si nous ne prenons pas en compte le rapport d'aspect, les résultats de notre redimensionnement seront déformés.

Au Ligne 20 , le calcul du rapport redimensionné est effectué. Nous fournissons la largeur de notre nouvelle image à 160 pixels dans cette ligne de code. Nous définissons simplement notre rapport (aspectratio) comme la nouvelle largeur (160 pixels) divisée par l'ancienne largeur, à laquelle nous accédons à l'aide de l'image, pour calculer le rapport de la nouvelle hauteur à l'ancienne hauteur. forme[1].

Les nouvelles dimensions de l'image sur Ligne 21 peut être calculé maintenant que nous connaissons notre ratio. Une fois de plus, la nouvelle image aura une largeur de 160 pixels. Après avoir multiplié l'ancienne hauteur par notre ratio et converti le résultat en entier, la hauteur est calculée. Nous pouvons conserver le rapport d'aspect d'origine de l'image en effectuant cette opération.

Ligne 24 C'est là que l'image est vraiment redimensionnée. L'image que nous voulons redimensionner est le premier argument, et le second est les dimensions que nous avons calculées pour la nouvelle image. Notre méthode d'interpolation, qui est l'algorithme de redimensionnement de l'image réelle, est le dernier paramètre.

Enfin, sur Ligne 25 , nous affichons notre image à l'échelle.

Nous redéfinissons notre ratio (rapport d'aspect) sur Ligne 31 . La hauteur de notre nouvelle image sera de 70 pixels. Nous divisons 70 par la hauteur d'origine pour obtenir le nouveau rapport hauteur/hauteur d'origine.

Ensuite, nous établissons les dimensions de la nouvelle image. La nouvelle image aura une hauteur de 70 pixels, ce qui est déjà connu. Nous pouvons une fois de plus conserver le rapport d'aspect d'origine de l'image en multipliant l'ancienne largeur par le rapport pour produire la nouvelle largeur.

L'image est alors réellement redimensionnée sur Ligne 35 , et il s'affiche sur Ligne 36.

Ici, nous pouvons voir que nous avons réduit la largeur et la hauteur de notre image d'origine tout en conservant le rapport d'aspect. Notre image apparaîtrait déformée si le rapport d'aspect n'était pas maintenu.

Conclusion

Dans ce blog, nous avons étudié les différents concepts de base du traitement d'image. Nous avons vu la traduction d'images à l'aide du package OpenCV. Nous avons vu les méthodes pour déplacer l'image vers le haut, le bas, la droite et la gauche. Ces méthodes sont très utiles lorsque nous créons un ensemble de données d'images similaires à donner comme ensemble de données d'apprentissage, de sorte que la machine verra des images différentes même si elles sont identiques. Cet article vous a également appris à faire pivoter une image autour de n'importe quel point de l'espace cartésien à l'aide d'une matrice de rotation. Ensuite, vous avez découvert comment OpenCV fait pivoter les images à l'aide de cette matrice et avez vu quelques illustrations d'images en rotation.

Les deux opérations arithmétiques d'image fondamentales (mais significatives) d'addition et de soustraction ont été examinées dans cette section. Comme vous pouvez le voir, l'ajout et la soustraction de matrices fondamentales sont toutes les opérations arithmétiques d'image.

De plus, nous avons utilisé OpenCV et NumPy pour étudier les particularités de l'arithmétique des images. Ces restrictions doivent être gardées à l'esprit, sinon vous risquez d'obtenir des résultats inattendus lors de l'exécution d'opérations arithmétiques sur vos images.

Il est important de se rappeler que bien que NumPy effectue une opération de module et 's'enroule', l'addition et la soustraction d'OpenCV coupent les valeurs au-delà de la plage [0, 255] pour s'adapter à l'intérieur de la plage. Lorsque vous développez vos propres applications de vision par ordinateur, vous en souvenir vous aidera à éviter de traquer les bugs délicats.

Le retournement d'image est sans aucun doute l'une des idées les plus simples que nous explorerons dans ce cours. Le retournement est fréquemment utilisé dans l'apprentissage automatique pour générer davantage d'échantillons de données d'apprentissage, ce qui se traduit par des classificateurs d'images plus puissants et plus fiables.

Nous avons également appris à utiliser OpenCV pour redimensionner une image. Il est crucial de prendre en compte à la fois la méthode d'interpolation que vous utilisez et le rapport d'aspect de votre image d'origine lors du redimensionnement afin que le résultat n'apparaisse pas déformé.

Enfin, il est crucial de se rappeler que si la qualité de l'image est un problème, il est toujours préférable de passer d'une image plus grande à une image plus petite. Dans la plupart des cas, l'agrandissement d'une image crée des artefacts et dégrade sa qualité.