Tutoriel de Vision par Ordinateur 2 : Les Fondamentaux des Images

Ce tutoriel constitue la base de la vision par ordinateur présentée dans le cadre de « Leçon 2 » de la série ; d’autres leçons sont à venir qui aborderont en détail la création de vos propres projets de vision par ordinateur basés sur l’apprentissage profond. Vous pouvez trouver le plan complet et la table des matières ici.

Les points clés de cet article sont les suivants :

  • Chargement d’une image à partir du disque.
  • Obtention de la ‘hauteur’, de la ‘largeur’ et de la ‘profondeur’ de l’image.
  • Recherche des composants R, G et B de l’image.
  • Dessiner à l’aide d’OpenCV.

Chargement d’une Image à partir du Disque

Avant de réaliser des opérations ou des manipulations sur une image, il est important de charger une image de notre choix sur le disque. Nous allons réaliser cette opération en utilisant OpenCV. Il existe deux façons d’effectuer cette opération de chargement. Une façon est de charger l’image en passant simplement le chemin de l’image et le fichier image à la fonction « imread » d’OpenCV. L’autre façon est de passer l’image via un argument de ligne de commande en utilisant le module python argparse.

Fig 2.1 Loading an Image from Disk by hard coding the image path and name in code.

Python

 

#Chargement de l'Image à partir du disque

import cv2
image = cv2.imread(“C:/Sample_program/example.jpg”)
cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Créons un fichier nommé Loading_image_from_disk.py dans un éditeur de texte notepad++. Premièrement, nous importons notre bibliothèque OpenCV, qui contient nos fonctions de traitement d’images. Nous importons la bibliothèque en utilisant la première ligne de code comme cv2. La deuxième ligne de code est l’endroit où nous lisons notre image en utilisant la fonction cv2.imread d’OpenCV, et nous transmettons le chemin de l’image en tant que paramètre ; le chemin doit également contenir le nom de fichier avec son extension de format d’image .jpg, .jpeg, .png ou .tiff.

syntaxe // image=cv2.imread(« chemin/vers/votre/image.jpg ») //

Il faut absolument faire attention lors de la spécification de l’extension du nom de fichier. Nous risquons de recevoir l’erreur ci-dessous si nous fournissons une extension erronée.

Python

 

ERROR :

c:\Sample_program>python Loading_image_from_disk.py
Traceback (most recent call last):
File “Loading_image_from_disk.py”, line 4, in <module>
cv2.imshow(‘Image’, image)
cv2.error: OpenCV(4.3.0) C:\projects\opencv-python\opencv\modules\highgui\src\window.cpp:376: error: (-215:Assertion failed) size.width>0 && size.height>0 in function ‘cv::imshow’

La troisième ligne de code est l’endroit où nous affichons réellement notre image chargée. Le premier paramètre est une chaîne, ou le « nom » de notre fenêtre. Le deuxième paramètre est l’objet auquel l’image a été chargée.

Enfin, un appel à cv2.waitKey met en pause l’exécution du script jusqu’à ce que nous appuyions sur une touche de notre clavier. L’utilisation d’un paramètre de « 0 » indique qu’un appui sur n’importe quelle touche relancera l’exécution. N’hésitez pas à exécuter votre programme sans la dernière ligne de code pour voir la différence.

Fig 2.2 Loading an Image using Argparse module.

Python

 

#Lecture d'image à partir du disque en utilisant Argparse

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Savoir lire une image ou un fichier à l’aide d’un argument de ligne de commande (argparse) est une compétence absolument nécessaire.

Les deux premières lignes de code sont pour importer les bibliothèques nécessaires ; ici, nous importons OpenCV et Argparse. Nous répéterons cela tout au long du cours.

Les trois lignes de code suivantes gèrent l’analyse des arguments de ligne de commande. Le seul argument dont nous avons besoin est — image: le chemin de notre image sur le disque. Enfin, nous analysons les arguments et les stockons dans un dictionnaire appelé args.

Prenons un moment pour discuter rapidement de ce qu’est exactement l’interrupteur — image. L’interrupteur — image (« switch » est un synonyme de « argument de ligne de commande » et les termes peuvent être utilisés de manière interchangeable) est une chaîne que nous spécifions à la ligne de commande. Cet interrupteur indique à notre script Loading_image_from_disk.py, où l’image que nous voulons charger se trouve sur le disque.

Les trois dernières lignes de code sont discutées précédemment ; la fonction cv2.imread prend args[« image »] en paramètre, qui n’est rien d’autre que l’image que nous fournissons dans l’invite de commande. cv2.imshow affiche l’image, qui est déjà stockée dans un objet image depuis la ligne précédente. La dernière ligne suspend l’exécution du script jusqu’à ce que nous appuyions sur une touche de notre clavier.

L’un des principaux avantages de l’utilisation d’un argparse — argument de ligne de commande est que nous pourrons charger des images à partir de différents emplacements de dossiers sans avoir à changer le chemin de l’image dans notre programme en passant dynamiquement le chemin de l’image Ex — « C:\CV_Material\image\sample.jpg » dans l’invite de commande en tant qu’argument lorsque nous exécutons notre programme python.

Fig 2.3 Loading Images from different folder locations using Argparse.

c:\Sample_program>python Loading_image_from_disk.py — image C:\CV_Material\session1.JPG

Ici, nous exécutons le fichier python Loading_image_from_disk.py à partir de l’emplacement c:\sample_program en passant le paramètre “-image” avec le chemin de l’image C:\CV_Material\session1.JPG.

Obtention de la ‘Hauteur’, ‘Largeur’ et ‘Profondeur’ de l’Image

Puisque les images sont représentées sous forme d’arrays NumPy, nous pouvons simplement utiliser l’attribut .shape pour examiner la largeur, la hauteur et le nombre de canaux.

En utilisant l’attribut .shape sur l’objet image que nous venons de charger, nous pouvons trouver la hauteur, la largeur et la profondeur de l’image. Comme discuté dans le cours précédent — 1, la hauteur et la largeur de l’image peuvent être vérifiées en ouvrant l’image dans MS Paint. Reportez-vous au cours précédent. Nous discuterons de la profondeur de l’image dans les leçons à venir. La profondeur est également appelée canal d’une image. Les images en couleur sont généralement de 3 canaux en raison de la composition RVB de ses pixels et les images en niveaux de gris sont de 1 canal. C’est quelque chose que nous avons discuté dans le Cours-1.

Fig 2.4 Prints the Height, Width, and Depth of the Image.

Python

 

#Obtenir la Hauteur, la Largeur et la Profondeur d'une Image

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

# Seule différence avec les codes précédents — application de l'attribut shape sur l'objet image

print(f’(Height,Width,Depth) of the image is: {image.shape}’)

image = cv2.imread(args[“image”])
cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Résultat:

(Hauteur, Largeur, Profondeur) de l’image est : (538, 723, 3)

La seule différence avec les codes précédents est l’instruction print qui applique l’attribut shape à l’objet image chargé. f’ est la chaîne F-string @ chaîne formatée qui prend des variables dynamiquement et imprime.

f’ write anything here that you want to see in the print statement: {variables, variables, object, object.attribute,}’

Ici, nous avons utilisé {object.attribute} à l’intérieur des accolades pour l’attribut .shape afin de calculer la hauteur, la largeur et la profondeur de l’objet image.

Python

 

#Obtenir séparément la hauteur, la largeur et la profondeur

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

# Tranchage de tableau NumPy pour obtenir séparément la hauteur, la largeur et la profondeur

print(“height: %d pixels” % (image.shape[0]))
print(“width: %d pixels” % (image.shape[1]))
print(“depth: %d” % (image.shape[2]))

cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Résultat:

largeur : 723 pixels
hauteur : 538 pixels
profondeur : 3

Ici, au lieu d’obtenir (hauteur, largeur et profondeur) ensemble sous forme de tuple. Nous effectuons un tranchage de tableau et obtenons individuellement la hauteur, la largeur et la profondeur de l’image. L’index 0 du tableau contient la hauteur de l’image, l’index 1 contient la largeur de l’image et l’index 2 contient la profondeur de l’image.

Recherche des composantes R, G et B de l’image

Fig 2.5 BGR value printed after taking the pixel co-ordinate position (y,x).

Résultat :

La valeur des composantes Bleu Vert Rouge de l’image à la position (321, 308) est : (238, 242, 253)

Notez comment la valeur y est passée avant la valeur x — cette syntaxe peut sembler contre-intuitive au début, mais elle est cohérente avec la manière dont nous accédons aux valeurs dans une matrice : d’abord nous spécifions le numéro de la ligne, puis le numéro de la colonne. À partir de là, nous obtenons un tuple représentant les composantes Bleu, Vert et Rouge de l’image.

Nous pouvons également changer la couleur d’un pixel à une position donnée en inversant l’opération.

Python

 

#Recherche des composantes R, B, G de l'image à la position (x, y)

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

# Recevoir la valeur de coordonnées de pixel sous forme de [y, x] de l'utilisateur, pour laquelle les valeurs RGB doivent être calculées
[y,x] = list(int(x.strip()) for x in input().split(‘,’))

# Extraire les valeurs (Bleu, vert, rouge) du pixel coordonné reçu
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)

cv2.imshow(‘Image’, image)
cv2.waitKey(0)

(b,g,r) = image[y,x] à image[y,x] = (b,g,r)

Ici, nous attribuons la couleur en (BGR) au pixel de coordonnées de l’image. Essayons en attribuant la couleur ROUGE au pixel à la position (321,308) et vérifions cela en imprimant les valeurs BGR du pixel à cette position.

Python

 

#Inversement de l'opération pour attribuer une valeur RGB au pixel de notre choix

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

#Recevoir la valeur de coordonnées de pixel [y,x] de l'utilisateur, pour lesquelles les valeurs RGB doivent être calculées
[y,x] = list(int(x.strip()) for x in input().split(‘,’))

#Extraire les valeurs (Bleu, Vert, Rouge) du pixel coordonnée reçue
image[y,x] = (0,0,255)
(b,g,r) = image[y,x]
print(f’The Blue Green Red component value of the image at position {(y,x)} is: {(b,g,r)}’)

cv2.imshow(‘Image’, image)
cv2.waitKey(0)

Résultat:

Les valeurs des composantes Bleu, Vert et Rouge de l’image à la position (321, 308) sont (0, 0, 255)

Dans le code ci-dessus, nous recevons les coordonnées du pixel via l’invite de commande en entrant la valeur comme indiqué dans la Fig 2.6 ci-dessous et attribuons la couleur rouge au pixel coordonnée en attribuant (0,0,255) c’est-à-dire (Bleu, Vert, Rouge) et vérifions cela en imprimant le pixel coordonnée d’entrée.

Dessin avec OpenCV

Apprenez à dessiner différentes formes comme des rectangles, des carrés et des cercles en utilisant OpenCV en dessinant des cercles pour masquer mes yeux, des rectangles pour masquer mes lèvres et des rectangles pour masquer le poisson matra-ray à côté de moi.

Le résultat devrait ressembler à ceci:

Fig 2.6 Masked Photo of me with the mantra-ray fish.

Cette photo est masquée avec des formes en utilisant MS Paint; nous allons essayer de faire de même en utilisant OpenCV en dessinant des cercles autour de mes yeux et des rectangles pour masquer mes lèvres et le poisson matra-ray à côté de moi.

Nous utilisons la méthode cv2.rectangle pour dessiner un rectangle et la méthode cv2.circle pour dessiner un cercle dans OpenCV.

cv2.rectangle(image, (x1, y1), (x2, y2), (Bleu, Vert, Rouge), Épaisseur)

La méthode cv2.rectangle prend en premier argument une image sur laquelle nous voulons dessiner notre rectangle. Nous voulons dessiner sur l’objet image chargé, donc nous le passons à la méthode. Le second argument est la position de départ (x1, y1) de notre rectangle — ici, nous commençons notre rectangle aux points (156 et 340). Ensuite, nous devons fournir un point de fin (x2, y2) pour le rectangle. Nous décidons de terminer notre rectangle aux coordonnées (360, 450). L’argument suivant est la couleur du rectangle que nous voulons dessiner ; ici, dans ce cas, nous passons la couleur noire en format BGR, c’est-à-dire (0,0,0). Enfin, le dernier argument que nous passons est l’épaisseur de la ligne. Nous donnons -1 pour dessiner des formes solides, comme on le voit dans la Fig 2.6.

De même, nous utilisons la méthode cv2.circle pour dessiner le cercle.

cv2.circle(image, (x, y), r, (Bleu, Vert, Rouge), Épaisseur)

La méthode cv2.circle prend en premier argument une image sur laquelle nous voulons dessiner notre rectangle. Nous voulons dessiner sur l’objet image que nous avons chargé, donc nous le passons à la méthode. Le second argument est la position centrale (x, y) de notre cercle — ici, nous avons pris notre cercle au point (343, 243). L’argument suivant est le rayon du cercle que nous voulons dessiner. L’argument suivant est la couleur du cercle ; ici, dans ce cas, nous passons la couleur ROUGE en format BGR, c’est-à-dire (0,0,255). Enfin, le dernier argument que nous passons est l’épaisseur de la ligne. Nous donnons -1 pour dessiner des formes solides, comme on le voit dans la Fig 2.6.

D’accord ! Sachant tout cela, essayons d’accomplir ce que nous avons commencé. Pour dessiner les formes dans l’image, nous devons identifier les coordonnées de début et de fin (x, y) de la région masquée pour les transmettre à la méthode respective.

Comment ?

Nous allons de nouveau demander l’aide de MS Paint. En plaçant le curseur sur l’une des coordonnées (coin supérieur gauche) ou (coin inférieur droit) de la région à masquer, les coordonnées sont affichées dans la partie surlignée de MS Paint comme le montre la Fig 2.7.

Fig 2.7 MSPaint to find the co-ordinates of the masking region.

De même, nous prendrons toutes les coordonnées (x1, y1) (x2, y2) pour toutes les régions masquées comme le montre la Fig 2.8.

Fig 2.8 (x.y) Co-ordinates of masking regions.

Python

 

#Dessiner à l'aide d'OpenCV pour masquer les yeux, la bouche et les objets à proximité

import cv2
import argparse

apr = argparse.ArgumentParser()
apr.add_argument(“-i”, “ — image”, required=True, help=”Path to the image”)
args = vars(apr.parse_args())

image = cv2.imread(args[“image”])

cv2.rectangle(image, (415, 168), (471, 191), (0, 0, 255), -1)
cv2.circle(image, (425, 150), 15, (0, 0, 255), -1)
cv2.circle(image, (457, 154), 15, (0, 0, 255), -1)
cv2.rectangle(image, (156, 340), (360, 450), (0, 0, 0), -1)

#Afficher l'image de sortie
cv2.imshow(“Output drawing “, image)
cv2.waitKey(0)

Résultat :



Fig 2.9 Desired Output.

Source:
https://dzone.com/articles/computer-vision-tutorial-2-image-basics