Dans cet article, nous allons voir comment sélectionner une partie de l’image, une région d’intérêt, grâce à OpenCV. Nous allons illustrer cette fonction à travers un programme qui prend en entrée une image. L’utilisateur sélectionne avec sa souris la zone d’intérêt.Enfin, on enregistre l’image découpée.
Dans les anciennes versions d’OpenCV, il était nécessaire de créer une fonction afin de récupérer les évènements de cliques de la souris: enregistrer les coordonnées de la souris lorsque le bouton gauche de la souris était enclenché (cv2.EVENT_LBUTTONDOWN) et de nouveau quand il était relâché (cv2.EVENT_LBUTTONUP). Nous obtenions ainsi les coordonnées de la zone d’intérêt.
Depuis la version 3.0 d’OpenCV, plus besoin de se prendre la tête, une fonction a été implémentée: cv2.selectROI. Utilisons donc cette fonction 🙂
Sélection d’une région d’intérêt
Notre fonction sera donc composée de 3 parties:
- Lire une image.
- Sélectionner la zone d’intérêt.
- Afficher et enregistrer la zone d’intérêt.
Nous aurons besoin de 3 bibliothèques pour notre programme: argparse, permettant récupérer l’image en entrée de notre programme; re permettant de gérer les expressions régulières (regex) et enfin cv2
import argparse import cv2 import re
Lecture de l’image
Nous commençons logiquement par la lecture de l’image. Cette image est fournie en argument lors de l’appel de notre programme. Nous définissons donc l’argument attendu aux lignes 5-7, c’est-à-dire le chemin de l’image, et nous la lisons ligne 8.
ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required=True, help="Chemin de l'image") args = vars(ap.parse_args()) img=cv2.imread(args["image"])
Ensuite, nous allons définir le nom du fichier de sortie. Nous allons reprendre le nom du fichier d’origine auquel nous allons ajouter « _crop » ainsi que l’extension « .jpg ».
Nous recherchons donc la chaine de caractère précédant un point dans le chemin fournit lors de l’appel de la fonction (l. 10). Nous ajoutons ensuite le complément du nouveau nom, ainsi l’extension (l. 11).
SI nous n’utilisions que des images avec une extension à 3 caractères (‘.jpg’, ‘.png’, ‘.bmp’, …), nous aurions pu utiliser une expression du type args[« image »][:-4] afin de sélectionner le nom de l’image de l’extension. Cependant le résultat obtenu avec une image ‘.tiff’ ou ‘.jpeg’, ne serait pas celui espéré: ‘test._crop.jpg’. Les regex nous permettent de pallier ce problème.
m = re.search('[^.]*',args["image"]) path=m.group(0)+'_crop.jpg'
Passons maintenant à ce qui nous intéresse: la sélection de la ROI !
Sélection de la région d’intérêt
ROI = cv2.selectROI(img)
Pour cela, rien de plus simple, il suffit d’appeler la fonction cv2.selectROI. Cette fonction prend en entrée l’image d’origine et renvoie un tuple de la forme [x,y,w,h], avec x,y les coordonnées du point supérieur gauche, w (width) la largeur et h (height) la hauteur.
De base, cette fonction vous permet de sélectionner un rectangle en partant du coin supérieur gauche vers le point inférieur droit. Si vous souhaitez sélectionner et ensuite élargir la région d’intérêt, il suffit de passer l’argument fromCenter=True lors de l’appel de la fonction.
Lors de l’appel de la fonction cv2.selectROI deux options nous sont proposées: sélectionner une ROI et appuyer sur espace ou entrer pour valider, ou annuler le processus de sélection en appuyant sur le touche c.
Enregistrement de l’image découpée
Si l’opération est annulée, la ROI renvoyé sera (0,0,0,0), ce qui posera problème pour découper l’image d’origine. Le programme se terminera avec une erreur. Nous ajoutons donc une condition ligne 15 pour découper l’image uniquement lorsqu’une zone est définie. Nous découpons ensuite l’image ligne 16, nous l’affichons lignes 17-18. Pour finir, nous enregistrons l’image découpée ligne 19.
if ROI!=(0,0,0,0): imgCrop = img[int(ROI[1]):int(ROI[1]+ROI[3]), int(ROI[0]):int(ROI[0]+ROI[2])] cv2.imshow("Image", imgCrop) cv2.waitKey(0) cv2.imwrite(path,imgCrop) cv2.destroyAllWindows()
0 commentaire