Coopération Humains-Machines / Humain-Humain

Codes des prototypes

Porteur du projet : Thomas Leloup

Date : 20/02/2018

Contexte : Mémoire DSAA

Lien : http://thomasleloup.fr/

Handtracking

Code principal

import kinect4WinSDK.*; //importer bibliothèque Kinect pour windows SDK
import KinectPV2.KJoint; //importer bibliothèque KinectPV2.KJoint
import KinectPV2.*; //importer bibliothèque KinectPV2
KinectPV2 kinect; //créer un attribut KinectPV2 nommé kinect
//attribut couleur en dégradé 1
int r = 255;
int g = 0;
int b = 0;
//boîte de particules de la classe Particle
ArrayList<Particle> allParticles = new ArrayList<Particle>();
float currentHue = 0; //teinte actuelle = 0
ParticleSystem ps; //attribut nommé ps de la classe ParticleSystem
PVector target; //vecteur nommé target
PVector[] points; //boîte de vecteurs nommé points
float x, y, angle, ease = 0.5; //introduire x, y, angle et ease = 0.5
boolean easing = true; //booléen nommé easing en vrai
//num => nombre de particules (cercles) lors du tracking
//frames => nombre d’images
int num=70, frames=165;
PImage main; //créer une image nommé main
PImage main1; //créer une image nommé main1
void setup() {
fullScreen(P3D); //affichage plein écran de la zone de travail (zone en 3D)
frameRate(30); //nombre d’images par seconde
//l’attribut nommé kinect devient une zone de capture de la Kinect
kinect = new KinectPV2(this);
kinect.enableSkeletonColorMap(true); //autorisation détection du squelette
kinect.enableColorImg(true); //autorisation de la colorisation de l’image de la kinect
kinect.init(); //démarrage de la kinect
main = loadImage(«main.png»); // l’image main télécharge le fichier main.png
main1 = loadImage(«main1.png»); // l’image main1 télécharge le fichier main1.png
//ps
ps = new ParticleSystem(new PVector(width/2, 50));
background(255); //fond blanc sur la zone de travail
points = new PVector[num];
for (int i=0; i<num; i++) {
points[i] = new PVector(width/2, height/2);
}
}
void draw() {
background(0); //fond noir sur la zone de travail
fill(255); //remplir en blanc pour toutes formes situées à la suite
textSize(80); //corps du texte en px
textAlign(CENTER); //alignement de tecte centré
text(«Approchez-vous !»,width/2,height/2-100); //texte au coordonnées indiquées derrière
text(«Et placez-votre main gauche en avant !»,width/2,height/2+20); //texte au coordonnées
indiquées derrière
imageMode(CENTER); //mode d’image centré
main1.resize(0,300); //redimension de l’image main1 (300px)
tint(255); //teinture blanche pour toutes formes situées à la suite
image(main1,width/2,height/2+280); //insérer image nommé main1
translate(-200,0); //déplacer de -200 sur x et 0 sur y
scale(1.8,1.6); //redimensionnement de la capture qui suit
//boîte qui comprend le squelette de détection du corps
ArrayList<KSkeleton> skeletonArray = kinect.getSkeletonColorMap();
//pour toutes jointures comprises dans la boîte de valeurs du squelette
for (int i = 0; i < skeletonArray.size(); i++) {
//skeleton de classe KSkeleton prend toutes valeurs i de la boîte du squelette
KSkeleton skeleton = (KSkeleton) skeletonArray.get(i);
if (skeleton.isTracked()) { //si il y a tracking du squelette
//chaque jointures de classe KJoint prends les jointures du squelette
KJoint[] joints = skeleton.getJoints();
background(0); //fond noir sur la zone de travail
//nouvelle couleur nommé col prend les couleurs indexées du squelette
color col = skeleton.getIndexColor();
fill(col); //remplir avec la couleur col
stroke(col); //contours avec la couleur col
//détection seulement de la main gauche
drawHandState(joints[KinectPV2.JointType_HandLeft]);
}
}
}
//lorsqu’il y a tracking de la main gauche
void drawHandState(KJoint joint) {
noStroke(); //pas de contours
pushMatrix(); //début zone restreinte
tint(r,b,g); //teinture par r,g,b
imageMode(CENTER); //mode image centré
main.resize(0,80); //redimension image main (80px)
//image main aux coordonnées de la position de la main gauche
image(main,joint.getX(), joint.getY());
popMatrix(); //fin zone restreinte
//ajout de particules ps aux coordonnées de la position de la main gauche
ps.addParticle(joint.getX(), joint.getY());
//fonctionnement et actualisation des particules ps
ps.run();
programme de transition des couleurs r,g,b
if(g < 255 && b == 0)
{
g = g + 5;
}
//Yellow to green
if (g == 255 && b == 0)
{
if(r >= 0)
{
r = r - 5;
}
}
//Green to cyan
if (r == 0 && g == 255)
{
if(b < 255)
{
b = b + 5;
}
}
//cyan to blue
if (b == 255 && r == 0)
{
if(g > 0)
{
g = g - 5;
}
}
//Purple to magenta
if (b == 255 && g == 0)
{
if(r < 255)
{
r = r + 5;
}
}
//magenta to red
if(r == 255 && g == 0)
{
if(b > 0)
{
b = b - 5;
}
}
}

Classe Système de Particule

class Particle {
//création attributs des particules
PVector location; //positions
PVector location1;
PVector location2;
PVector location3;
PVector velocity; //vitesse de déplacement des particules
PVector acceleration; //accélération de leur vitesse
float lifespan;
Particle(float x, float y) {
acceleration = new PVector(0, 0.05);
//random => valeur aléatoire entre deux chiffres
velocity = new PVector(random(-1, 1), random(-2, 0));
location = new PVector(x, y);
location1 = new PVector(x+random(-10, 8), y+random(-8, 30));
location2 = new PVector(x+random(-30, 5), y+random(-1, 10));
location3 = new PVector(x+random(-20, 6), y+random(-20, 4));
lifespan = 255.0;
}
//méthode pour afficher les deux autres méthodes
void run() {
update();
display();
}
//Méthode pour mettre à jour la position
void update() {
velocity.add(acceleration);
location.add(velocity);
lifespan -= 3;
}
//Méthode pour lire les particules
void display() {
noStroke();
//stroke(255, lifespan);
fill(r,g,b, 205-lifespan/2);
ellipse(location.x, location.y, 20, 20);
ellipse(location1.x, location1.y, 20, 20);
ellipse(location2.x, location2.y, 20, 20);
ellipse(location3.x, location3.y, 20, 20);
}
//Booléen en fonction de l’opacité des particules (au=dessus)
boolean isDead() {
if (lifespan < 100.0) {
return true;
} else {
return false;
}
}
}

Classe Particule

// Classe pour décrire le groupe de Particules
// Un ArrayList est utilisé pour organiser la liste des Particules
class ParticleSystem {
ArrayList<Particle> particles;
PVector origin;
ParticleSystem(PVector location) {
origin = location.get(); //origin prend les valeurs de location (voir autre classe)
particles = new ArrayList<Particle>(); //ajout de particules dans la boîte
}
//méthode d’ajout de particules sur la zone de travail
void addParticle(float x, float y) {
particles.add(new Particle(x,y));
}
//méthode pour afficher les particules dans la zone de travail
void run() {
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = particles.get(i);
p.run();
if (p.isDead()) { //voir booléen de l’autre classe
particles.remove(i);
}
}
}
}

Shake it up

Code principal

import gab.opencv.*; //importer la bibliothèque opencv
import KinectPV2.*; //importer la bibliothèque Kinect
//attribut couleur en dégradé 1
int r = 255;
int g = 0;
int b = 0;
//attribut couleur en dégradé 2
int r1 = 0;
int g1 = 255;
int b1 = 255;
KinectPV2 kinect; //créer un attribut KinectPV2 nommé kinect
OpenCV opencv; //créer un attribut OpenCV nommé opencv
float polygonFactor = 1; //facteur de résolution du corps
int threshold = 10; //seuil de détection
int maxD = 1800; //Distance max de captation 1.8m
int minD = 50; //Distance min de captation 50cm
boolean contourBodyIndex = false; //booléen pour la détection du contour du corps
void setup() {
size(1920, 1080, P3D); //taille de la zone de travail avec 3D
//l’attribut nommé opencv devient une zone de capture de la bibliothèque opencv
opencv = new OpenCV(this, 512, 424);
//l’attribut nommé kinect devient une zone de capture de la Kinect
kinect = new KinectPV2(this);
kinect.enableDepthImg(true); //autorisation profondeur de l’image kinect
kinect.enableBodyTrackImg(true); //autorisation du tracking du corps
kinect.enablePointCloud(true); //autorisation d’un nuage de point de l’image kinect
kinect.init(); //démarrage de la kinect
}
void draw() {
//remplir avec les valeurs de couleurs r,g,b définies auparavant (opacité réduite : 10) pour toutes
formes situées à la suite
fill(r,g,b,10);
rect(0,0,width,height); //rectangle de la taille de zone de travail
noFill(); //pas de remplissage pour toutes formes situées à la suite
strokeWeight(1);//taille des contours 1px
scale(3.75,2.45,5);//redimensionnement de la capture qui suit
if (contourBodyIndex) { //si il détecte un corps
opencv.loadImage(kinect.getBodyTrackImage()); //alors chargement de l’image du tracking de
la kinect
//PImage dst = opencv.getOutput();
} else { //sinon
opencv.loadImage(kinect.getPointCloudDepthImage()); //chargement de l’image de profondeur
de la kinect
//PImage dst = opencv.getOutput();
}
//tableau qui utilise la classe Contour de la bibliothèque où contours prend les valeurs de détection
de contours de opencv
ArrayList<Contour> contours = opencv.findContours(false, false);
if (contours.size() > 0) { //si la taille de countours est supérieur à 0
for (Contour contour : contours) { //pour tout contour de classe Contour prenant la valeurs de
contours
//faire une approximation de la résolution grâce au facteur de résolution définis au départ (en
haut)
contour.setPolygonApproximationFactor(polygonFactor);
if (contour.numPoints() > 50) { //si le nombre de points de contour dépasse 50
noStroke(); //pas de contours pour toutes formes situées à la suite
beginShape(); //début de forme
//remplir avec les valeurs de couleurs r1,g1,b1 définies auparavant pour toutes formes
situées à la suite
fill(r1,g1,b1);
//pour tout point prenant les valeurs d’approximation définies par contour
for (PVector point : contour.getPolygonApproximation ().getPoints()) {
vertex(point.x, point.y); //faire des sommets avec comme coordonnées chaque pixel capté
dans la zone de captation
}
endShape(); //fin de forme
}
}
//programme de transition des couleurs r,g,b
if(g < 255 && b == 0)
{
g = g + 5;
}
//Yellow to green
if (g == 255 && b == 0)
{
if(r >= 0)
{
r = r - 5;
}
}
//Green to cyan
if (r == 0 && g == 255)
{
if(b < 255)
{
b = b + 5;
}
}
//cyan to blue
if (b == 255 && r == 0)
{
if(g > 0)
{
g = g - 5;
}
}
//Purple to magenta
if (b == 255 && g == 0)
{
if(r < 255)
{
r = r + 5;
}
}
//magenta to red
if(r == 255 && g == 0)
{
if(b > 0)
{
b = b - 5;
}
}
//programme de transition des couleurs r1,g1,b1
if(g1 < 255 && b1 == 0)
{
g1 = g1 + 5;
}
//Yellow to green
if (g1 == 255 && b1 == 0)
{
if(r1 >= 0)
{
r1 = r1 - 5;
}
}
//Green to cyan
if (r1 == 0 && g1 == 255)
{
if(b1 < 255)
{
b1 = b1 + 5;
}
}
//cyan to blue
if (b1 == 255 && r1 == 0)
{
if(g1 > 0)
{
g1 = g1 - 5;
}
}
//Purple to magenta
if (b1 == 255 && g1 == 0)
{
if(r1 < 255)
{
r1 = r1 + 5;
}
}
//magenta to red
if(r1 == 255 && g1 == 0)
{
if(b1 > 0)
{
b1 = b1 - 5;
}
}
}
kinect.setLowThresholdPC(minD); //faire un seuil minimale pour la distance minimale de captation
kinect.setHighThresholdPC(maxD); //faire un seuil maximale pour la distance maximale de
captation
}