tutorial de programmation
|
![]() |
As a technological discipline, computer vision seeks to apply the theories and models of computer vision to the construction of computer vision systems. Examples of applications of computer vision systems include systems for:
source : http://en.wikipedia.org/wiki/Computer_vision
La vision par ordinateur est aussi aujourd'hui un outil et sujet de nombreux oeuvres artistiques. Depuis des pionniers tels que Myron Krueger ou David Rokeby dans les années 80, la CV est utilisé dans des installations, performances, créations chorégraphiques et théâtrale.
Dans ce cours, nous utilisons la bibliothèque OpenCV pour l'instant juste pour récupérer une images de la webcam afin d'appliquer quelques algorithmes simples de la computer vision
La lecture d'un webcam avec OpenCV est quasi la même procédure que la lecture d'un vidéo
import hypermedia.video.*;
OpenCV monOpenCV
void setup(){
size(320,240);
monOpenCV= new OpenCV(this);
monOpenCV.capture(width, height);// allouer la mémoire pour la capture de vidéo
}
void draw() {
monOpenCV.read();
image( monOpenCV.image(), 0, 0 );
}
L'un des principales taches de la 'computer vision' est le traitement d'image (image processing). Le but du traitement d'image est la transformation de l'image ou d'une partie permettant d'aller vers une interprétation des images traitées. Différents algorithmes ou opérateurs de traitement d'image nous permet d'extraire des informations pertinents. Une des ces opérateurs est le 'pixel à pixel' (aussi appelés opérateurs point à point). Voici un algorithme simple pour extraire le pixel le plus lumineux.
Pour aller plus loin / traitement image: http://fr.wikipedia.org/wiki/Traitement_d%27images
import hypermedia.video.*;
OpenCV monOpenCV;
void setup() {
size(320, 240);
monOpenCV = new OpenCV(this);
monOpenCV.capture (width, height);
noStroke();
void draw() {
monOpenCV.read();
image(monOpenCV.image(), 0, 0); // affiche la webcam
loadPixels(); // charge la liste de pixels qui sont actuellement sur l'écran
int brightestX = 0; // variable pour l'X-coordonée du pixels le plus lumineux
int brightestY = 0; // et Y-coordonée du pixels le plus lumineux
float brightestValue = 0; // la valeur de "brightness " du pixels le plus lumineux
//regarde chaque pixel de la liste et prend sa couleur
for (int i = 0; i < pixels.length; i++) {
color pixelValue = pixels[i];
// Détermine la "brightness" du pixel
float pixelBrightness = brightness(pixelValue);
// si la "brightness" valeur du pixel actuel est plus grand que le plus grand,
//prend lui comme plus grand et convertit sa position dans la liste en coordonnée x, y
if (pixelBrightness > brightestValue) {
brightestValue = pixelBrightness;
brightestX = i%width;
brightestY = (i-brightestX)/width;
}
}
updatePixels();// update les pixels dans la matrix
fill(255, 204, 0, 128);
ellipse(brightestX, brightestY, 20, 20); //dessine un ellipse a la position du pixel le plus lumineux
}
Le traitement d'image par seuil (thresholding image processing) est un groupe d'algorithme pour segmenter des images digitales. L'exemple, précédent a été déjà un premier cas de segmentation. On découpe le groupe de pixel en deux segments, le groupe du pixel le plus lumineux et les autres.
La segmentation est un étape important dans l'analyse de l'image, pour par exemple reconnaître des objets. Avec l'aide du seuilage on peut distinguer un objet de son environnement. Le traitement par seuil produit des images binaires.
Voici un autre algorithme simple de binarisation d'image qui transforme l'image RGB en image binaire N/B
import hypermedia.video.*;
OpenCV monOpenCV;
int threshold=127;
void setup() {
size(320, 240);
monOpenCV = new OpenCV(this);
monOpenCV.capture (width, height);
}
void draw() {
monOpenCV.read();
monOpenCV.convert( OpenCV.GRAY );// transforme l'image en N/B
image(monOpenCV.image(), 0, 0); // affiche la webcam
loadPixels();// charge la liste de pixels qui sont actuellement sur l'écran
for (int i = 0; i < pixels.length; i++) { //regarde chaque pixel de la liste
float pixelValue =red(pixels[i]);// et prend sa couleur, dans 'GRAY' les valeurs de R+G+B sont pareils
if (pixelValue>threshold)pixelValue=255;// décide si le pixel devient noir ou blanc
else pixelValue =0;
pixels[i]=color(pixelValue);
}
updatePixels();// update les pixels dans la matrix
fill(255, 204, 0, 128);
ellipse(brightestX, brightestY, 20, 20); //dessine un ellipse à la position du pixel le plus lumineux
}
OpenCV nous propose déjà une série de seuilages d'images. La méthode la plus simple est threshold (int valeur<255). L'argument indique le seuil ou le pixel devient noir ou blanc, comme dans l'exemple au dessus. Si il s'agit d'un image en RGB, chaque composant devient soit 0 soit 255, c-a-d l'image se transforme en couleurs premières et secondaires (R, G, B, R+G, G+B...).
Il y a d'autres façon plus sophistiqué qui exige trois arguments
threshold(value, max, type);
value = le valeur du threshold <255,
max= la valeur qui prend les pixels au delà du seuil. Si j'indique 200, l'image se décompose en deux couleur 0 et 200.
type= Il y a plusieurs type qui sont décrit ci-dessus
exemple
monOpenCV.threshold(127, 200, OpenCV.THRESH_TOZERO_INV);
CV_THRESH_BINARY: |
![]() |
Il y a un type supplémentaire qui s'appelle OTSU, nommé d'après Nobuyuki Otsu qui a développé un algorithme en 1979 pour trouver le "threshold' optimal dans un image. Il fait recours aux méthodes de la statistique et de la variance. Si on utilise 'OTSU' dans la méthode threshold(), le 'value' doit être renseigné, mais il sera calculé par OpenCV.
Pour aller plus loin avec Otsu =>
exemple
monOpenCV.threshold(127, 200, OpenCV.THRESH_TOZERO_INV + OpenCV.THRESH_OTSU);
Documentation OpenCV/Processsing: threshold()
DocumentationOpenCV
http://opencv.willowgarage.com/wiki/CvReference#FiltersandColorConversion
( descend jusqu'a threshold)
en anglais http://en.wikipedia.org/wiki/Thresholding_(image_processing)
en francais http://www.siteduzero.com/tutoriel-3-8607-binarisation-et-images-binaires.html
Voici l'algorithme qui révèle la différence entre deux images, n et n-1(l'image dans le buffer). Il y a également la fonction absDiff() qui fait la même tache, l'avantage de l'algorithme est que je maîtrise chaque pixel et je peux mesurer la 'grandeur' du changement.
import hypermedia.video.*;
OpenCV monOpenCV;
color bkgdPixels[];// liste mémoire pour les pixels
void setup() {
size(320/2, 240/2);
monOpenCV = new OpenCV(this);
monOpenCV.capture (width, height);
bkgdPixels= new color[width*height];
}
void draw() {
monOpenCV.read();
monOpenCV.convert(OpenCV.GRAY);// transformer l'image en N/B
image(monOpenCV.image(), 0, 0);
bkgdSubstraction();// appelle la fonction de soustraction
}
void keyPressed() {
loadPixels();
arraycopy(pixels, bkgdPixels);// copie les pixels de l'image dans le mémoire
}
void bkgdSubstraction(){
loadPixels();// charge la liste de pixels qui sont actuellement sur l'écran
int diffTotal=0;// variable pour stocker la différence entre les pixels
for (int i = 0; i < pixels.length; i++) {// examiner pixel par pixel
float currR=red(pixels[i]);// la valeur du rouge du pixel actuel
// float currG=green(pixels[i]);// desactivé si on travail on Gray
// float currB=blue(pixels[i]);
float bkgdR=red(bkgdPixels[i]);//la valeur du rouge du pixel du memoire
// float bkgdG=green(bkgdPixels[i]);// desactivé si on travail on Gray
// float bkgdB=blue(bkgdPixels[i]);
float diffR = abs(currR - bkgdR);// calculer la différence entre pixel mémoire et actuel
// float diffG = abs(currG - bkgdG);
// float diffB = abs(currB - bkgdB);
// diffTotal+= diffR + diffG + diffB;
//println(diffTotal);
// println(diffR);
// pixels[i] = color(diffR, diffG, diffB);
pixels[i] = color(diffR); // actualiser la liste des pixels avec la couleur de soustraction
}
updatePixels();// update les pixels dans la matrix
}