Cours:Classif

De troyesGEII
Révision datée du 2 février 2026 à 10:40 par Fredmn (discussion | contributions) (Classifieur plus évolué)
Aller à : navigation, rechercher

TP Classification : détection d'objet en temps réel par vision

Le travail de cette étape va consister à

  • analyser des images acquises en "temps réel" afin de détecter et identifier des objets
  • les objets seront
    • dans un premier temps des jetons de nain jaune
    • dans un second temps des briques lego.

Technos matérielles et logicielles

Vous utiliserez :

Étapes :

  • Connexion à la Rpi et test d'acquisition en ligne de commande
  • Capture d'image et affichage en temps réel, avec Python
  • Prétraitement
  • Reconnaissance simple d'un seul objet, avec descripteurs géométriques
  • Classifieur plus évolué (knn, svm)
  • Plusieurs objets

Connexion à la Rpi et test d'acquisition en ligne de commande

  • Connecter (si cela n'est pas fait) la PiCam à la Rpi4
  • Dans un terminal, se connecter à la Rpi en ssh : ssh -X root@10.98.33.XX
  • Tester la PiCam avec libcamera-hello (la capture en video doit s'afficher sur l'écran de la Rpi). Avec les informations affichées, identifier :
    • le modèle du capteur,
    • ses caractéristiques (résolution, format, cadence, etc ...).
  • Tester l'acquisition d'image avec l'éxecutable libcamera-still

Capture d'image et affichage en temps réel

En exploitant la documentation Picamera2 (principalement section 6 - Capturing images and requests)

  • Tester les deux exemples Capturing arrays et Capturing PIL images
  • Écrire un script Python qui :
    • initialise la camera
    • affiche en continu son image
    • sur l'appui d'une touche, réalise une capture (dans un objet array ou PIL) et sauvegarde l'image dans un fichier

En pratique :

  • Vous pouvez lancer un interpréteur Python dans le terminal pour tester des choses
  • Vous pouvez accéder aux dossiers de la Rpi depuis votre PC fixe, depuis le navigateur Dolphin avec comme url sftp://root@10.98.33.83:22/. Ce qui vous permettra par exemple d'éditer le fichier script depuis votre PC fixe.
  • Dans le terminal, python monscript.py pour executer votre script
  • On peut facilement attendre l'appui d'une touche avec cv2.waitkey()
  • Référence Python :

Prétraitement

  • Modification éventuelle de la zone de capture de la camera (crop).
  • Conversion en image niveaux de gris, sur 8 bits.
  • Binarisation (en mettant l'objet à 255, le fond à 0).

Reconnaissance simple d'un seul objet, avec descripteurs géométriques élémentaires

  • En ne plaçant qu'un seul objet dans le champ de la camera, calculer et afficher ses descripteurs de forme : longueur et largeur de l'objet, cf https://raphael.candelier.fr/?blog=Image%20Moments (calcul de l et w)
  • Construire une décision idoine à l'aide de la largeur et de la longueur de l'ellipse englobante, afin de discrimer trois classes d'objets (par exemple : jeton court, jeton long, jeton rond)


Exemple de calcul de l et w à partir d'une image binaire représentée dans un tableau numpy (arr de type ndarray) :

img = arr.astype(np.float64, copy=False)
H, W = img.shape
yy, xx = np.indices((H, W))

M00 = float(np.sum(img))
M10 = float(np.sum(xx * img))
M01 = float(np.sum(yy * img))
M11 = float(np.sum(xx * yy * img))
M20 = float(np.sum((xx * xx) * img))
M02 = float(np.sum((yy * yy) * img))

xm = int(M10 / M00)
ym = int(M01 / M00)

mu20 = M20 / M00 - xm * xm
mu02 = M02 / M00 - ym * ym
mu11 = M11 / M00 - xm * ym

t = math.sqrt(4.0 * mu11 * mu11 + (mu20 - mu02) * (mu20 - mu02))
l = int(math.sqrt(8.0 * (mu20 + mu02 + t)))
w = int(math.sqrt(8.0 * (mu20 + mu02 - t)))

Classifieur plus évolué

from picamera2 import Picamera2
import numpy as np
import cv2

picam = Picamera2()
picam.start()
a = picam.capture_array("main")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 100, 200)
contours, hierarchy = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = max(contours, key=cv2.contourArea)
cnt = cnt.astype(np.float32)

# Paramètres utiles :
# nbElt = nombre de points ré-échantillonnés sur le contour
# nbFD  = nombre de descripteurs gardés
fd = cv2.ximgproc.fourierDescriptor(cnt, nbElt=128, nbFD=16)

print(fd.shape, fd.dtype)

Plusieurs objets

  • Segmentation nécessaire pour séparer les objets.
  • Puis une labellisation pour les numéroter.

Bouts de code Python

  • Convertir une image couleur img (4 canaux) en image OpenCV :
import cv2
im_cv = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR)

Références

OpenCV :

Archives de cette page :