Segmentation d'image dans OpenCV
-
Segmentation d’image à l’aide de
opencv
en Python -
Utiliser l’algorithme
GrabCut
pour la segmentation d’images à l’aide deopencv
-
Utiliser la détection des couleurs pour la segmentation d’image à l’aide de
opencv
- Conclusion
Le traitement d’image est une étape cruciale dans les tâches de vision par ordinateur. En Python, nous pouvons utiliser la bibliothèque opencv
pour implémenter plusieurs techniques de traitement d’images utilisant différents objets et méthodes.
Ce didacticiel montrera comment effectuer une segmentation d’image à l’aide de opencv
en Python.
Segmentation d’image à l’aide de opencv
en Python
La segmentation d’image fait référence au processus de division d’une image donnée en plusieurs parties.
Nous ajoutons des courbes qui joignent les points le long de la limite des parties segmentées. Ces courbes sont appelées contours.
La segmentation d’image est très utile en vision par ordinateur et a de nombreuses applications réelles. Nous pouvons utiliser cette technique pour segmenter des parties d’une image afin de classer divers objets.
Plusieurs méthodes disponibles peuvent être utilisées pour la segmentation d’images en utilisant opencv
en Python.
La principale méthode qui diffère dans chaque technique de segmentation d’image est généralement basée sur le critère de l’image segmentée. Nous pouvons avoir une segmentation d’image basée sur la détection de certaines couleurs, des algorithmes prédéfinis comme l’algorithme Watershed, la détection des bords et même la sélection des parties segmentées en fonction des entrées de l’utilisateur.
Nous aborderons certaines de ces méthodes dans les sections suivantes.
Utiliser l’algorithme GrabCut
pour la segmentation d’images à l’aide de opencv
Cette méthode nécessite une interaction de l’utilisateur avec la souris et le clavier. La bibliothèque opencv
intégrée contient des objets et des méthodes qui peuvent lire les entrées de l’utilisateur à partir de la souris et du clavier.
L’algorithme GrabCut
est un outil très simple et utile pour la segmentation d’images. Dans cette technique, nous utilisons l’entrée de l’utilisateur pour sélectionner une région d’une image donnée.
Cet algorithme détecte automatiquement le premier plan et l’arrière-plan de la partie segmentée, et nous pouvons les afficher.
Nous pouvons utiliser la fonction grabCut()
de la bibliothèque opencv
pour implémenter cet algorithme. Nous transmettrons l’image avec la case de la région sélectionnée dans cette fonction pour la segmentation de l’image.
Voir le code suivant pour un exemple.
import cv2
import numpy as np
def algo_grabcut(img, bounding_box):
seg = np.zeros(img.shape[:2], np.uint8)
x, y, width, height = bounding_box
seg[y : y + height, x : x + width] = 1
background_mdl = np.zeros((1, 65), np.float64)
foreground_mdl = np.zeros((1, 65), np.float64)
cv2.grabCut(
img, seg, bounding_box, background_mdl, foreground_mdl, 5, cv2.GC_INIT_WITH_RECT
)
mask_new = np.where((seg == 2) | (seg == 0), 0, 1).astype("uint8")
img = img * mask_new[:, :, np.newaxis]
cv2.imshow("Output", img)
def box_draw(click, x, y, flag_param, parameters):
global x_pt, y_pt, drawing, topleft_pt, bottomright_pt, img
if click == cv2.EVENT_LBUTTONDOWN:
drawing = True
x_pt, y_pt = x, y
elif click == cv2.EVENT_MOUSEMOVE:
if drawing:
topleft_pt, bottomright_pt = (x_pt, y_pt), (x, y)
image[y_pt:y, x_pt:x] = 255 - img[y_pt:y, x_pt:x]
cv2.rectangle(image, topleft_pt, bottomright_pt, (0, 255, 0), 2)
elif click == cv2.EVENT_LBUTTONUP:
drawing = False
topleft_pt, bottomright_pt = (x_pt, y_pt), (x, y)
image[y_pt:y, x_pt:x] = 255 - image[y_pt:y, x_pt:x]
cv2.rectangle(image, topleft_pt, bottomright_pt, (0, 255, 0), 2)
bounding_box = (x_pt, y_pt, x - x_pt, y - y_pt)
algo_grabcut(img, bounding_box)
drawing = False
topleft_pt, bottomright_pt = (-1, -1), (-1, -1)
img = cv2.imread("img4.jpg")
img = cv2.resize(img, (500, 500))
image = img.copy()
cv2.namedWindow("Frame")
cv2.setMouseCallback("Frame", box_draw)
while True:
cv2.imshow("Frame", image)
ch = cv2.waitKey(1)
if ch == 32:
break
cv2.destroyAllWindows()
Production:
Comprenons ce qui se passe dans l’exemple ci-dessus.
La fonction box_draw()
lit l’interaction de l’utilisateur avec la souris pour sélectionner la région de segmentation de l’image. La boîte et l’image sont passées à la fonction algo_grabcut()
qui prend l’image et crée le masque binaire pour l’image segmentée.
Nous utilisons ce masque et affichons le premier plan de la partie segmentée.
Utiliser la détection des couleurs pour la segmentation d’image à l’aide de opencv
En Python, on peut utiliser le opencv
pour la détection des couleurs. Il existe différents espaces colorimétriques disponibles pour qu’une image représente ses couleurs.
Dans notre cas, nous utiliserons l’espace colorimétrique HSV pour déterminer les plages de la couleur donnée.
Nous utiliserons différentes couleurs pour la segmentation des images. Nous créons une gamme pour une couleur donnée et utilisons la fonction inRange()
de la bibliothèque opencv
pour détecter les objets qui correspondent à cette couleur.
Cela renvoie un masque binaire. On affine ensuite ce masque et on ajoute des contours à cette partie détectée.
Comme indiqué précédemment, les contours sont les courbes sur les limites de la partie segmentée. Nous allons utiliser la fonction findContours()
pour trouver les bordures à l’aide du masque créé puis dessiner ces contours avec la fonction drawContours()
.
Voir le code ci-dessous.
import cv2
import numpy as np
img = cv2.imread("img4.jpg")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
bound_lower = np.array([36, 25, 25])
bound_upper = np.array([70, 255, 255])
mask_green = cv2.inRange(hsv_img, bound_lower, bound_upper)
kernel = np.ones((7, 7), np.uint8)
mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_CLOSE, kernel)
mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_OPEN, kernel)
seg_img = cv2.bitwise_and(img, img, mask=mask_green)
contours, hier = cv2.findContours(
mask_green.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
output = cv2.drawContours(seg_img, contours, -1, (0, 0, 255), 3)
cv2.imshow("Result", seg_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Production:
Dans le code ci-dessus, nous segmentons les objets verts d’une image donnée. Tout d’abord, nous convertissons l’image dans l’espace colorimétrique HSV à l’aide de la fonction cvtColor
.
Ensuite, nous procédons à la création du masque qui stocke la couleur détectée. Nous supprimons également tout bruit indésirable de ce masque.
Ensuite, nous dessinons les contours du segment détecté et l’affichons. La fonction waitKey()
empêche la fermeture automatique de la fenêtre d’image.
Il attend que l’utilisateur appuie sur une touche puis la ferme.
Conclusion
Dans ce didacticiel, nous avons abordé la segmentation d’images à l’aide de la bibliothèque opencv
de Python. Nous avons également mis en place quelques techniques pour cela, bien que beaucoup d’autres soient possibles.
Nous avons discuté des bases de la segmentation d’image et de l’approche et du résultat final dans chaque méthode.
Nous avons discuté en détail de deux méthodes. Dans un premier temps, nous avons implémenté l’algorithme GrabCut
.
Dans cet algorithme, l’utilisateur sélectionne une région qu’il souhaite utiliser pour la segmentation. A partir de cette portion, nous détectons les objets de premier plan et les affichons.
Dans la deuxième technique, nous avons utilisé la détection de couleur. Nous avons détecté des objets de couleur verte.
Dans ce type de segmentation, nous convertissons l’image dans l’espace colorimétrique donné et utilisons les gammes de couleurs de ce modèle pour détecter les couleurs à l’aide de la fonction inRange()
. Nous utilisons ce masque pour segmenter l’image et tracer des contours autour des bords.
Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.
LinkedIn