Biblio-thèque externe et vidéo

tutorial de programmation
en processing

invisibleShape
  Joachim Sauter & Dirk Lüsebrink
The Invisible Shape of Things Past (1995)

 

bibliothèque externe

Processing a été développé à l'origine pour développer facilement des graphismes statiques et dynamique ainsi que de pouvoir récupérer des inputs de la souris ou du clavier. Cette réduction volontaire rend Processing simple pour débuter. Mais son architecture (Java) lui permet d'élargir ses capacités très facilement. A travers l'importation des bibliothèques (libraires en anglais) on peut communiquer à travers différents protocoles de communication avec d'autres ordinateurs (midi, osc...), exporter des graphismes sous différents formats (pdf, dxf...), travailler en 3D, intégrer du son, ou encore traiter des images vidéos et faire plein d'autres choses.

Les bibliothèques de Processing

 

Core libraires et contributions

On voit sur la page de libraires qu'il y a deux sections. La première concerne les bibliothèques qui sont intégré dans Processing, comme OpenGl ou Minim pour le son. Mais l'architecture Open Source de Processing ainsi que la OOP de Java permet et facilite l'intégration d'autres bibliothèques qui sont en effet des class (cf. cours sur les class). Ainsi la communauté de Processing qui a développé énormément des bibliothèques, appelé contributions, et qui se trouvent dans la deuxième section. Les core libraires sont documenté sur le site de Processing, les 'contributions' sont documenté sur le site de ses auteurs.

 

Importation

Pour utiliser les libraires dans le sketch, il faut d'abord l'importer. Ceci se fait simplement par une ligne de code. Pour accélérer le rendu graphique, on peut intégrer par exemple la bibliothèque OpenGl. Soit on l'écrit directement dans le code ou on passe par le menu "Sketch" -> "Import Libraires" -> le nom de la bibliothèque.

import processing.opengl.*; 

La commande import désigne que les class de la bibliothèque en question peuvent être utiliser. processing.opengl indique le chemin ou se trouve les class et l'astérisque désigne que tous les class d'Opengl sont chargé.

 

Installation des bibliothèque externes

Les class des cores libraries sont déjà installé dans processing, par contre les contributions doivent être téléchargé sur son site respectif. Normalement, les différents étapes d'installation sont décrit par les auteurs des bibliothèques. La procédure classique est de télécharger un fichier zip et de le décompresser directement dans un dossier 'librairies' qui se trouve dans le dossier ou se trouve les sketchs de processing, pour windows dans le dossier mes Documents > Processing > librairies sous Mac dans ~/Documents/Processing. Si c'est la première librairie à installer, il faut créer le dossier "librairies" manullement (attention à l'orthographie, en englais, miniscule et pluriel).

La plus part du temps il y a également un dossier 'exemple' dans le dossier downloadé. On peut ouvrir ces exemples par le menu files -> exemples.... Il est toutefois aussi possible d'installer les fichiers de la bibliothèque (.jar) directement dans le dossier du sketch qui l'utilise. Il faut créer un nouveau dossier "code" dans lequel on installe les fichiers de la bibliothèque.

 

Video dans Processing

Référence et littérature

Golan Levin: slitscan

OPENCV pour Processing

OpenCV est un des bibliothèques parmi d'autres qui permet à Processing de travailler avec des images vidéos. Il existe dans Processing une core library pour acquisition et traitement d'image vidéo, mais il est relativement lente et étant donné qu'elle utilise la compression Quick time, son usage avec un PC est compliqué. La bibliothèque la plus rapide et la plus complète actuellement est probablement OpenCV.

OpenCV est une bibliothèque graphique libre, développée à la base par Intel, spécialisée dans le traitement d'image temps réel. Cette bibliothèque est distribuée sous licence BSD. Elle est développé en C/C++.

Le wiki de OpenCV

La bibliothèque dans Processing d'OpenCV est une sorte d'intégration (binding) de la bibliothèque d'origine. Elle utilise certaines fonctionnalité d'OpenCV et a été développé à l'Atelier hypermédia à l'École Supérieure d'Art d'Aix-en-Provence par Stéphane Cousot et Douglas Edric Stanley.

Les principales fonctionnalités de la bibliothèque sont:

 

Téléchargement d'OpenCV pour Processing

Pour télécharger la bibliothèque, il faut aller sur le site :

http://ubaa.net/shared/processing/opencv/

Ici vous trouvera la description détaillé de téléchargement et d'installation. Contrairement à la plus part des autres bibliothèques externe, ici il faut aussi télécharger et installer un logiciel, ou bien la bibliothèque d'origine: OpenCV.

Dans 95% des cas, les installations ne posent pas des problèmes, mais il y a toujours des exceptions. Il y a eu des étudiants qui ont pu réglé le problème en copiant les fichiers suivants dans le dossier de Processing. Ces fichiers se trouvent normalement à l'adresse: C:\Program Files\OpenCV\bin

libguide40.dll
cxcore100.dll
cv100.dll

 

Lecture de vidéo

La bibliothèque permet de lire des vidéos enregistré. Pour cela, il faut d'abord importer la bibliothèque. Soit on passe par Menu: Sketch ->Import Library ->OpenCV et ainsi on voit si l'installation a été bien fait ou bien on écrit directement

import hypermedia.video.*;

Ensuite on crée un objet (la référence) de la class OpenCV qu'on nom monOpenCV

OpenCV monOpenCV

Dans le setup() on instancie l'objet avec le constructeur et on charge le fichier vidéo qui doit se trouver dans un dossier data dans le dossier du sketch. Pour ce faire, il suffit de glisser la vidéo dans la fenêtre de Processing. Les deux autres arguments de la méthode movie() met à disposition la mémoire correspondant à la taille du vidéo.

void setup(){
size(320,240);
monOpenCV= new OpenCV(this); // le constructeur de la class
monOpenCV.movie("bunny.avi", width, height);// charge le fichier vidé
}

Dans le draw(), on saisit (grab) d'abord un frame du vidéo dans le' buffer' avec la méthode read et ensuite on l'affiche dans la fenêtre de Processing à travers la méthode processing image. Pour cela on utilise la méthode image() de OpenCV qui donne en retour un image.

void draw(){
monOpenCV.read(); //lit un nouveau 'frame';
image(monOpenCV.image(),0,0); // affiche le frame
}

Les références des méthodes OpenCV utilisé pour afficher le vidéo.

movie()
read()
image()

 

Filtre et manipulation d'image

OpenCV propose une série de filtre d'image.Pour l'appliquer il faut l'appeler entre le read() et l'affichage de l'image. Comme c'est sont des méthodes de la class OpenCV il faut l'appeler à travers l'objet par exemple: monOpenCV.brightness(50);

le voici les principaux:
blur() méthode pour flouer l'image. Différents techniques (Gaussian, Median, et Bilateral) sont proposé.
brightness()
modifie la luminosité, l'argument est un int entre -128 et +128
contrast() modifie le contrast, l'argument est un int entre -128 et +128
convert() / restore() modifie un image de RGB -> GRAY, restore le met en RGB
invert() inverti les couleurs
ROI() = Region of interest, définit une zone dans laquelle les traitements d'images s'applique. Ses arguments sont les mêmes que pour rect()

Pour aller plus loin avec le filtre d'image =>Bilateral Filtering

DIfférents méthodes permets de manipuler l'image entier. flip() bascule l'image sur l'axe horizontal, vertical ou le deux: l'argument et: FLIP_HORIZONTAL, FLIP_VERTICAL or FLIP_BOTH


Lecture de vidéo

La fonction jump() permet de sauter dans la lecture du vidéo. La surcharge de la méthode ** permet de définir comme argument à travers un int le millisseconde dans la timeline du vidéo ou à travers un float une ratio entre 0 et 1 de la durée totale (0.5 =la moitié de temps totale...). Si je veux accéder aux frames, je dois le spécifier et renseigner le frame en question

jump(60, MOVIE_FRAMES) m'afficher le frame 60.

jump()

**plusieurs méthodes du même nom mais différents type ou nombre d'arguments

 

l'image et mémoire

Avant que l'image soit affiché elle passe d'abord dans une sorte de transit qu'on appelle buffer. Le buffer est en effet un espace de mémoire réservé. C'est pour cela on passe par deux étapes: D'abord on enregistre l'image dans le buffer avec monOpenCV.read() et ensuite on l'affiche avec image(monOpenCV.image(),x,y);

OpenCV nous met a disposition un autre lieu de transit qui s'appelle MEMORY. Pour mettre des images dans cette espace de transit, on utilise la méthode remember() et pour appeler ensuite l'image qui est y stocké, on précis dans la méthode image son lieu de stockage image(monOpenCV.image(monOpenCV.MEMORY),x,y); on aurait pu précisé qu'on veut utiliser l'image de buffer avec BUFFER, mais ceci n'est pas nécessaire car c'est l'argument par défaut dans la méthode image() d'OpenCV.

Il est toute à fait possible de modifier l'image dans le buffer avant qu'il soit afficher. On peut rajouter des images, modifier l'image avec le filtre ect.. Pour rajouter (remplacer une partie de l'image), il y a la méthode copy(). La méthode peut prend comme argument seulement une image; copy( img) prendra l'image entier et le rajoute (remplace la zone en question par l'image) dans le buffer.

import hypermedia.video.*;
PImage img;
OpenCV monOpenCV;
int w=320, h=240;

void setup(){
size(w,h);
img=loadImage("bunnyFriend.png");
monOpenCV= new OpenCV(this);
monOpenCV.movie("bunny.avi", w, h);
}
void draw(){
monOpenCV.read();
monOpenCV.copy(img);
image(monOpenCV.image(), 0,0);
}

void mouseReleased(){
saveFrame("bunny.jpg");
}

bunnyFriend
bunny2

Étant donne que l'image se place par défaut a 0,0, et il est trop grand, j'ai aussi la possibilité de choisir sa position et sa taille. Pour cela, j'indique un cadre (les arguments de rect()) de capture et un cadre de restitution comme argument dans copy().

monOpenCV.copy(img, 0,0,144,159, w-60, 50, 144/2, 159/2 );

( les valeurs alpha ne sont pas traiter dans OpenCV ;-( ....
remember()
copy()

 

Slit scanning Video

Le slit scanning est un méthode de transformation d'un flux video. Le principe est qu'elle coupe un fine tranché d'un image du flux et agence par la suite ces différents tranche l'un à coté de l'autre.Le principe de ce code suivant est simple: Nous créerons au début une image vide d''un pixel de large et l'hauteur du vidéo.
slice = createImage(1, height, RGB);Par la suite, nous récupérons les pixels d'un tranche d'un pixel au milieu du flux vidéo et le copierons dans l'image vide. slice.pixels[i]= opencv.image().pixels[width/2+width*i]; A la fin on affiche l'image on se déplaçons à chaque frame d'un pixel. image(slice, incrX, 0);

slitscan

 

import hypermedia.video.*;
OpenCV opencv;
PImage slice;
int incrX;

void setup(){
size(320, 240);
opencv = new OpenCV(this);
opencv.capture(width, height);
slice = createImage(1, height, RGB);
}

void draw(){
opencv.read();
incrX++;
if (mousePressed) {
println(frameRate);
opencv.flip(OpenCV.FLIP_HORIZONTAL);
image(opencv.image(), 0,0);
stroke(255,0,0);
line(width/2, 0, width/2, height);
}
else{
for (int i = 0; i<height; i++){
slice.pixels[i]= opencv.image().pixels[width/2+width*i];
}
slice.updatePixels();
image(slice, incrX, 0);
}

if (incrX>width){
saveFrame("slitscan.png");
exit();
}
}

Exercice

  • Capture un flux vidéo à l'aide de la libraire OpenCV.
  • Analyse l'image avec deux boucle for afin de récupérer les valeurs de couleur d'un matrice de tout le 10px.
  • Recrée d'abord un image pixelisé à partir des valeurs récupérées.
  • Transforme ces nouveaux rectangles (pixel) par rapport à sa taille, couleur et vis à vis d'un autre valeur (brightness, valeur de rouge...) >
mirror