Dans cet article, nous allons voir comment sélectionner une partie de l’image, une région d’intérêt (ROI), 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 🙂

selection de zone d'interet avec la fonction cv2.selectROI

Sélection d’une région d’intérêt (ROI)

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 de 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 ».

m = re.search('[^.]*',args["image"])
path=m.group(0)+'_crop.jpg'

Nous recherchons donc la chaîne 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.

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)

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()

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 la touche c.

Enregistrement de l’image découpée

Si l’opération est annulée, la ROI renvoyée 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.

Nous avons vu aujourd’hui comment utiliser la fonction cv2.selectROI. Cette fonction va nous être utile lorsque nous voudrons créer un dataset pour un algorithme d’apprentissage ou encore pour sélectionner Charlie.


2 commentaires

mikael · 18 juin 2019 à 17 h 31 min

Merci pour ce petit tutoriel interessant. Cependant je me pose la question de savoir s il est possible aa la suite de sauvegarder les coordonnees des regions d interet dans un fichier texte par exemple

    Florent · 19 juin 2019 à 8 h 44 min

    Bonjour,
    Il est tout à fait possible d’enregistrer ces coordonnées dans un fichier texte.
    Pour ce faire, il sera nécessaire de créer une chaîne de caractère à partir des coordonnées.

    Pour l’enregistrement, vous pouvez jeter un coup d’œil à cette page : https://python-django.dev/page-lire-ecrire-creer-fichier-python

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.