OpenCV

Open Computer Vision
Avant tout le OpenCV est une bibliothèque permettant le traitement d'images en temps réel
Dans notre cas, nous utiliserons OpenCV sous Python de façon à compléter cette formation.

Installer OpenCV

Tout d'abord il faut installer OpenCV sous python alors pour la démarche :

  1. Installer Python/Numpy/Matplotlib
    1. Installer Python-2.7.x sur C:/Python27/
    2. Installer Numpy
    3. Et enfin Matplotlib
  2. Après l'installation, ouvrir Python(Commande line). import numpy
  3. Télécharger la dernière version de OpenCV et double-click pour extraire.
  4. Aller dans le repertoire opencv/build/python/2.7
  5. Copier le fichier cv2.pyd dans C:/Python27/lib/site-packages
  6. ouvrir Python(Commande line).
    import numpy
    import cv2
    print cv2.__version__
    

Si le résultat est affiché sans erreurs, félicitations !!! Vous avez installé OpenCV Python succès.

Premier exemple
import cv2
im = cv2.imread('3x2.png')
 
print im

Avec comme résultat

[[[  0   0   0]
  [  0 255   0]
  [  0   0   0]]

 [[  0   0 255]
  [255 255 255]
  [255   0   0]]]

Les informations relative au pixel en bas à droite de notre image sont donc accessibles de cette façon. (À noter que le stockage des couleurs est fait dans l'ordre BLEU-VERT-ROUGE, inverse d'un intuitif RVB)

# pour le niveau de Bleu
print im[1][2][0]
# pour le niveau de Vert
print im[1][2][1]
# pour le niveau de Rouge
print im[1][2][2]

De même , le script suivant remplacera le pixel blanc (au milieu, en bas) par un pixel jaune :

import cv2
im = cv2.imread('3x2.png')
 
im[1][1] = [0, 255, 255]
 
# sauvegarde du resultat
cv2.imwrite('resultat.png',im)

Ces manipulations sont, bien évidemment, aussi possibles en vidéo. Par exemple, le script ci-dessous trace une ligne rouge horizontale puis une ligne bleue verticale, en temps-réel, sur un flux vidéo capturé par une webcam.

import cv2
 
# setup video capture
cap = cv2.VideoCapture(0)
 
ret,im = cap.read()
height, width = im.shape[:2]
 
while True:
    ret,im = cap.read()
 
    # trait horizontal
    for i in range(width):
        im[height/2][i] = [0, 0, 255]
 
    # trait vertical
    for i in range(height):
        im[i][width/2] = [255, 0, 0]
 
    cv2.imshow('video test',im)
    key = cv2.waitKey(10)

Remarque:
La fonction pour ajouter une ligne horizontale sans calcul:

cv2.line(img,  point1,  point2,      couleur,  épaisseur)
cv2.line(img, (0, 270), (960, 270), (0, 0, 0), 1)
Taille des sources vidéo

La taille des flux vidéos capturés se définie avec .set(ID, valeur), où ID=3 pour la largeur et ID=4 pour la hauteur.
Le script ci-dessous attribue une taille de 320*240 à cap0 et 160*120 à cap1

import cv2
 
cap0 = cv2.VideoCapture(0)
cap0.set(3,320)
cap0.set(4,240)
 
cap1 = cv2.VideoCapture(1)
cap1.set(3,160)
cap1.set(4,120)
 
while True:
 
    ret0,im0 = cap0.read()
    ret1,im1 = cap1.read()    
 
    cv2.imshow("vid-0",im0)
    cv2.imshow("vid-1",im1)
 
    key = cv2.waitKey(10)


Pour info, voici la liste de ID des propriétés existante pour .set() (et pour .get(), par ailleurs).

ParamètreDescription
0CV_CAP_PROP_POS_MSECPosition dans le film en millisecondes
1CV_CAP_PROP_POS_FRAMESPosition dans le film en nombre de frames
2CV_CAP_PROP_POS_AVI_RATIOPosition dans le film en pourcentage
3CV_CAP_PROP_FRAME_WIDTHLargeur du flux vidéo
4CV_CAP_PROP_FRAME_HEIGHTHauteur du flux vidéo
5CV_CAP_PROP_FPSNombre d'images/seconde du flux vidéo
6CV_CAP_PROP_FOURCCCode du codec du flux vidéo
7CV_CAP_PROP_FRAME_COUNTNombre total de frames (fichier vidéo uniquement)
8CV_CAP_PROP_FORMATFormat des objets Mat retournés par retrieve()
9CV_CAP_PROP_MODELa valeur spécifique à backend indiquant le mode de capture actuel
10CV_CAP_PROP_BRIGHTNESSLuminosité de l'image
11CV_CAP_PROP_CONTRASTContraste de l'image
12CV_CAP_PROP_SATURATIONSaturation de l'image
13CV_CAP_PROP_HUETeinte de l'image
14CV_CAP_PROP_GAINGain de l'image
15CV_CAP_PROP_EXPOSUREExposition de l'image
16CV_CAP_PROP_CONVERT_RGBImage N&B ou RGB
17CV_CAP_PROP_WHITE_BALANCEActuellement non pris en charge
18CV_CAP_PROP_RECTIFICATIONFlag rectification pour caméras stéréo (note: seulement pris en charge actuellement par DC1394 v 2.x)
Déplacement des fenêtres et multiplication des sources

Il est possible de choisir sa source avec cv2.VideoCapture(0).

Il est possible choisir la position de chaque fenêtre de rendu, ainsi que de les déplacer avec cv2.moveWindow(video_name, posX, posY)
Le script ci-dessous ouvre deux flux, affiche 14 fenêtres et les déplacent sur l'écran :

import cv2
 
# setup video capture
cap0 = cv2.VideoCapture(0)
cap1 = cv2.VideoCapture(1)
 
posV, posH = 0, 0
 
while True:
 
    ret0,im0 = cap0.read()
    ret1,im1 = cap1.read()
 
    if (posV == 200):
        posV = 0
 
    if (posH > 900):
        posH = 0
 
    for i in range (6):
 
        video_name = 'test2-{0}'.format(i)
        cv2.imshow(video_name.format(i),im0)
        cv2.moveWindow(video_name, posH+i*80, i*50)
 
    for i in range (8):
 
        video_name = 'test-{0}'.format(i)
        cv2.imshow(video_name.format(i),im1)
        cv2.moveWindow(video_name, 160*i+40, posV+i*50)
 
    key = cv2.waitKey(10)
 
    posV += 10
    posH += 8

Infos utiles dans ce contexte

Liste des paramètres accessibles sur v4l2

Détection d'objets avec Haar

Dans cette partie nous allons voir comment créer un programme capable de reconnaître et localiser un objet dans un image.
Par la suite nous travaillerons sur la reconnaissance de visages mais cela peut être n'importe quel objet.

  1. Rassembler des images avec et sans l'objet à identifier. Pour être réellement efficace, il faut environ 5000 images. D'où l'importance de trouver ou de se constituer une base de données d'images avec et sans l'objet à identifier.
  2. Exécuter objectMaker() (source en bas). Le but de se fichier est de créer un fichier texte avec la localisation des images.
  3.  Exécuter create_list.bat pour créer un fichier avec l'emplacement des images sans l'objet à identifier.
  4. Créer les "samples" (échantillons en français) avec la commande
    createsamples.exe -info positive/info.txt -vec data/vector.vec -num 3527 -w 24 -h 24
    avec positive/info.txt l'emplacement du fichier texte créer à l'étape 2 (liste des images positives)
    3527 le nombre d'images positives et 24 la largeur puis la hauteur minimale de l'objet à reconnaître.
  5. Maintenant l'étape clé : l'entraînement. Ici, il va vous falloir un ordinateur qui va tourner jour et nuit pendant plusieurs jours si vous avez un nombre correct (quelques milliers) d'images positives et négatives.
    haartraining.exe -data data/cascade -vec data/vector.vec -bg negative/infofile.txt -npos 3527 -nneg 2362 -nstages 30 -mem 1000 -mode ALL -w 24 -h 24 -nonsym
    cascade est l'endroit où seront crées les fichiers intermédiaires (qui serviront à créer le fichier XML)
    negative/infofile.txt est l'emplacement du fichier crée à l'étape 3, qui contient le nom des images négatives.
    3527 est le nombre d'images positives
    2362 est le nombre d'images négatives
    30 est le nombre d'étapes qui seront faites : c'est bien d'en mettre assez. Si jamais vous voyez que c'est trop, vous pouvez arrêter en cours de route donc il vaut mieux en mettre trop que pas assez.
    1000 est la quantité de mémoire vive allouée à la tâche
    24 est la largeur puis la hauteur minimale de l'objet à reconnaître.
  6. Une fois que l'entraînement est terminé,  remplacer le "data" de  "haar\cascade2xml" par le répertoire "data" de "haar\temp", copier "vector.vec" dans "haar\cascade2xml". Puis exécuter "convert.bat".Et voilà, le fichier output.xml est crée.