====== ALYCIA RAINAUD - PROJETS WEBCAM PROCESSING ======
* Porteur(s) du projet : Alycia Rainaud
* Date : Mars 2017
* Contexte : Cours de programmation
-----
===== PROJET 1 =====
===== Webcam & Control P5 =====
Ce premier projet sous Processing est une mise en relation de l'utilisation de la webcam et de la librairie Control P5 + librairie processing video, afin de créer des effets visuels applicables à une image caméra. L'utilisateur peut donc appliquer différents filtres sur l'image caméra via des boutons de type knob (rotatif) qui permettent d'accentuer l'intensité de chaque filtre, et permettent également la superposition des filtres. De plus, il est possible pour l'utilisateur de générer des captures d'images en appuyant sur la touche ENTER. Ce programmme a été réalisé dans l'esprit de la référence [[https://gaze.bitrot.ooo/|GAZE]] sur Chrome Experiment.
{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_15.38.05.png?300|}}{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_15.38.14.png?300|}}{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_15.38.23.png?300|}}{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_15.38.36.png?300|}}
===== Fichiers nécessaires pour l'utilisation du code =====
* {{:wiki:projets:projets-processing-dsaa1:projet_webcam3.zip|Code du programme}}
* {{:wiki:projets:projets-processing-dsaa1:controlp5.zip|Librairie CONTROLP5}}
* {{:wiki:projets:projets-processing-dsaa1:video.zip|Librairie Processing Video}}
===== Code du Programme =====
/*
Alycia Rainaud
Premier test pour un programme webcam/control p5
À améliorer = diversité des filtres
*/
import processing.video.*; //Importer la librairie video
import controlP5.*; // Importer la librairie controlP5 interfaces graphiques
// Initialisation des variables
ControlP5 controlP5; // Déclarer la variable controlP5
Capture cam; // Déclarer la variable caméra
color c; // Déclarer la variable color
// Attributs des boutons control P5
int myColorBackground = color(0,0,0); // Couleur de fond de base
int knobValue = 100; // Valeur du bouton knob 1
int knobValue2 = 100; // Valeur du bouton knob 2
int knobValue3 = 100; // Valeur du bouton knob 3
Knob myKnobA; // Déclarer l'objet KnobA
Knob myKnobB; // Déclarer l'objet KnobB
Knob myKnobC; // Déclarer l'objet KnobC
// Initialisation des paramètres d'affichages
void setup() {
size(640,480); // Taille de la fenêtre d'affichage
smooth(); // Lissage
noStroke(); // Pas de contour
controlP5 = new ControlP5(this); // Création d'une nouvelle interface Control P5
//controlP5.addKnob("knob",0, 360, 0, 10,10,50); // création d'un bouton pitch
//controlP5.addToggle("toggle", true, 160,10,50,50); // création d'un bouton ouvert ou eteint
//controlP5.addSlider("slider",0, 255, 123, 240, 10,50,20); // création d'une barre slide de valeurs
// Constructeur de Paramétrage du premier Bouton Knob
myKnobA = controlP5.addKnob("knobValue")
.setRange(0,255) // Détermination du segment de valeur compris entre 0 et 255
.setValue(60) // Détermination de la valeur initiale à l'affichage
.setPosition(510,50) // Position du bouton dans la fenêtre d'affichage
.setRadius(40) // Diamètre du bouton
.setDragDirection(Knob.VERTICAL) // Détermination du mouvement bouton à la verticale
;
// Constructeur de Paramétrage du deuxième Bouton Knob
myKnobB = controlP5.addKnob("knobValue2")
.setRange(0,255) // Détermination du segment de valeur compris entre 0 et 255
.setValue(150) // Détermination de la valeur initiale à l'affichage
.setPosition(510,200) // Position du bouton dans la fenêtre d'affichage
.setRadius(40) // Diamètre du bouton
.setDragDirection(Knob.VERTICAL) // Détermination du mouvement bouton à la verticale
;
// Constructeur de Paramétrage du troisième Bouton Knob
myKnobC = controlP5.addKnob("knobValue3")
.setRange(0,255) // Détermination du segment de valeur compris entre 0 et 255
.setValue(60) // Détermination de la valeur initiale à l'affichage
.setPosition(510,350) // Position du bouton dans la fenêtre d'affichage
.setRadius(40) // Diamètre du bouton
.setDragDirection(Knob.VERTICAL) // Détermination du mouvement bouton à la verticale
;
// Affichage caméra
String[] cameras = Capture.list();
if (cameras.length == 0) { // Initialisation d'une boucle if
println("There are no cameras available for capture."); // Si pas de caméra disponible
exit(); // alors fin du programme
} else { // cas contraire
println("Available cameras:"); // si caméra disponible
for (int i = 0; i < cameras.length; i++) { // alors incémentation de la caméra
println(cameras[i]);
}
cam = new Capture(this, width, height); // création d'une nouvelle image caméra
cam.start(); // démarage de la caméra
}
}
// Initialisation des boucles d'affichages
void draw() {
background(myColorBackground); // couleur du fond
if (cam.available() == true) { // initialisation de la boucle d'affichage caméra
cam.read(); // lecture de la caméra
}
image(cam, 0, 0);
// Boucle d'oscillation du rendu visuel appliqué au Knob A
for (int i = 0; i < 640; i = i+2) { // largeur
for (int j = 0; j < 480; j = j+2) { // longueur
fill(cam.get(i, j)*10,knobValue); // Remplir 10 fois les valeurs i et j
rect(i, j, 2,2); // carrés
}
}
// Boucle d'oscillation du rendu visuel appliqué au Knob B
for (int i = 0; i < 640; i = i+2) { // largeur
for (int j = 0; j < 480; j = j+2) { // longueur
fill(cam.get(i, j),knobValue2); // Remplir les valeurs i et j
tint(random(255), random(255), random(255), knobValue2); // filtre de couleur aléatoire
}
}
// Boucle d'oscillation du rendu visuel appliqué au Knob C
for (int i = 0; i < 640; i = i+2) { // largeur
for (int j = 0; j < 480; j = j+2) { // longueur
fill(cam.get(i, j)/20,knobValue3); // Remplir les valeurs i et j divisé par 40
rect(i, j, 2,2); // carrés
}
}
}
// Méthode pour Prendre une photo en appuyant sur la touche ENTER
void keyPressed() {
if (key == ENTER) { // si la touche ENTER est pressée
saveFrame("image-"+hour()+minute()+second()+".png"); // alors enregistrement de l'image avec pour nom d'image heure minute et seconde au format png
}
}
// FIN DU PROGRAMME //
----
===== PROJET 2 =====
===== Réalité Augmentée Processing =====
Ce second projet sous Processing est une mise en relation de l'utilisation de la webcam et de marqueurs papier, pour créer de la réalitée augmentée de façon assez simple et générale. Ici, on retrouve l'utilisation de la librairie processing video (webcam), de la librairie Nyar4PSG (réalité augmentée), la librairie OBJLoader (models 3D) et la librairie OPENGL. Ce programme permet à l'utilisateur de faire apparaitre des objets 2D, 3D etc, lorsqu'il passe le marqueur devant sa caméra. Ce programme est intéressant à développer, en vue d'un prototypage de livre augmenté par exemple.
===== Références & Documentation =====
* Exemples de la librairie OBJ Loader et Nyar4PSG
* Forum Processing
* Projet Réalité Augmentée [[http://www.creativeapplications.net/processing/augmented-reality-with-processing-tutorial-processing/|Amnon Owed ]]
{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_16.17.01.png?|}}
{{:wiki:projets:projets-processing-dsaa1:18073327_10212707288574053_1811320501_n.jpg?340|}}{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_16.18.34.png?345|}}{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_16.18.52.png?345|}}{{:wiki:projets:projets-processing-dsaa1:capture_d_e_cran_2017-04-22_a_16.19.16.png?343|}}
===== Fichiers et Matériel nécessaire =====
* {{:wiki:projets:projets-processing-dsaa1:ra.zip|Fichier Complet du Programme}}
* [[https://processing.org/download/|Processing 1.5.1]], les autres versions ne supportent pas la librairie de réalité augmentée
* {{:wiki:projets:projets-processing-dsaa1:nyar4psg.zip|La librairie Nyar4PSG}} pour les fonctions de réalité augmentée
* {{:wiki:projets:projets-processing-dsaa1:objloader.zip|La librairie OBJLoader}} pour importer des objet 3D type blender
* La librairie OPENGL pour gérer la 3D et les rendus type textures etc (NE FONCTIONNE PAS ENCORE DANS CE CODE)
* Des marqueurs de réalité augmentée, ici patt.hiro patt.kanji et patt.4x4_1 que vous retrouverez également dans le dossier data du code
* Impression de ces marqueur (8x8cm) sur papier, en laissant une bordure blanche au tour (voir photo ci-dessus)
===== À noter =====
* Ce programme est une première ébauche fonctionnelle dans sa globalité, qui sera à développer en vue d'un éventuel prototypage
* Les fonctions d'imports textures ne sont pas encore gérées dans ce programme
* Si vous souhaitez d'autres marqueurs, téléchargez ce fichier Pattern Maker où vous trouverez un générateur de marqueurs, mais également 100 marqueurs prédéfinis dans le dossier examples que je vous conseille vivement d'utiliser
* Un bug sympa dans le programme à la ligne background(0); si elle est supprimée, permet de pouvoir laisser une "trace" de la couleur de l'objet augmenté et de ce fait, il est possible de s'amuser à dessiner avec ;)
===== Code du Programme =====
/*
Alycia Rainaud
Premier test pour un programme de réalité augmentée.
Gestion de plusieurs marqueurs
À régler : importation des textures à revoir
*/
import processing.video.*; // Importer la librairie Vidéo, permet d'appeler la webcam par exemple
import jp.nyatla.nyar4psg.*; // Importer la librairie Nyar4Psg, permet la réalité augmentée
import saito.objloader.*; // Impporter la librairie OBJLoader, permet d'importer des objets 3D
import processing.opengl.*; // Importer la librairie OPENGL, permet de gérer la 3D et les rendus de textures etc
// Déclaration des attributs du programme
Capture cam; // Déclaration de la variable caméra
MultiMarker nya; // Déclaration de la variable Nyar
OBJModel model; // Déclaration de la variable objet model
// Variables à utiliser lorsque l'import de texture marche
//boolean bTexture = false;
//boolean bStroke = false;
//boolean bMaterial = false;
// Méthode d'initialisation des paramètres d'affichages
void setup() {
size(640,480,P3D); // Taille de la fenêtre + appel de la 3D
colorMode(RGB); // Mode colorimétrique
cam=new Capture(this,width,height); // Taille de la caméra
// Appel de la fonction MultiMarker (reconnaissance multiples des marqueurs)
nya=new MultiMarker(this,width,height,"camera_para.dat",new NyAR4PsgConfig(NyAR4PsgConfig.CS_RIGHT_HAND,NyAR4PsgConfig.TM_NYARTK));
nya.addARMarker("patt.hiro",80); // Marqueur 1 + taille
nya.addARMarker("patt.kanji",80); // Marqueur 2 + taille
nya.addARMarker("4x4_1.patt",80); // Marqueur 3 + taille
// Appel d'un modèle 3D format .obj créé dans blender
model = new OBJModel(this, "data/circle.obj", "absolute", TRIANGLES); // Création d'un nouvel objet appelé model, instancié par OBJModel
model.enableDebug(); // fonction de débug
model.scale(20); // taille de l'objet
model.translateToCenter(); // Centrer l'objet sur le marqueur
}
// Méthode d'initialisation des boucles d'affichages
void draw() {
// Vérification de l'activation de la caméra
if (cam.available() !=true) {
return;
}
background(0); // !!! si cette ligne est supprimée, on peut dessiner avec l'objet du marqueur
cam.read(); // Lecture de l'image caméra
nya.drawBackground(cam); // Applique l'image de la caméra en fond
nya.detect(cam); // Detection des marqueurs via la caméra
// Boucles de vérifications des marqueurs
// Premier marqueur
if(nya.isExistMarker(0)){ // Si la caméra detecte un marqueur via Nyar
nya.beginTransform(0); // Alors Nyar créé ou applique une transformation
{
// Apparition d'un cube
fill(0,0,255); // Remplir de bleu
translate(0,0,20);
translate(0,0,-20);
box(40); // Dessin d'un cube de 40px
}
nya.endTransform(); // Si Nyar ne détecte pas de marqueur alors il ne se passe rien
}
// Deuxième marqueur
if(nya.isExistMarker(1)){ // Si la caméra detecte un marqueur via Nyar
nya.beginTransform(1); // Alors Nyar créé ou applique une transformation
{
pushStyle();
model.draw(); // Dessin de l'objet model
lights();
popStyle();
// À note : problème d'importation de textures à régler
}
nya.endTransform(); // Si Nyar ne détecte pas de marqueur alors il ne se passe rien
}
// Troisième marqueur
if(nya.isExistMarker(2)){ // Si la caméra detecte un marqueur via Nyar
nya.beginTransform(2); // Alors Nyar créé ou applique une transformation
{
// Apparition d'une sphère
fill(255,255,0); // Remplir de jaune
translate(0,0,30);
translate(0,0,-30);
sphere(30); // Dessin d'une sphere de 30px
}
nya.endTransform(); // Si Nyar ne détecte pas de marqueur alors il ne se passe rien
}
}
// FIN DU PROGRAMME //