Annonce

>>> Bienvenue sur codelab! >>> Première visite ? >>> quelques mots sur codelab //// partage de liens //// une carte des membres//// (apéros) codelab


#1 2017-07-17 05:22:53 Kinect + Processing : Point Cloud

alvink
membre
Date d'inscription: 2016-10-23
Messages: 10

Kinect + Processing : Point Cloud



Bonjour à toutes et à tous ! smile

Voilà je suis actuellement en train de tester un code qui me permet d'utiliser la kinect sur Processing, ce code vient de ce site : http://codigogenerativo.com/code/kinect … g-library/ plus précisément la partie "Point Cloud".

Leur code fonctionne très bien il n'y a rien à dire cependant j'aimerai aller plus loin en récupérant les positions x y et z de chaque points pour faire des essais de collisions entre eux (avec une histoire de distance, lorsque les points sont à une certaine distance les unes des autres, une ligne se dessine entre elles).

Le problème c'est que je n'arrive pas à récupérer ces coordonnées voici le code :

/*
Thomas Sanchez Lengeling.
http://codigogenerativo.com/
KinectPV2, Kinect for Windows v2 library for processing

Point Cloud example using openGL and Shaders
*/

import java.nio.*;
import KinectPV2.*;

KinectPV2 kinect;


int  vertLoc;

//transformations
float a = 1.9;
int zval = -200;
float scaleVal = 260;


//value to scale the depth point when accessing each individual point in the PC.
float scaleDepthPoint = 100.0;

//Distance Threashold
int maxD = 4000; // 4m
int minD = 0;  //  0m

//openGL object and shader
PGL     pgl;
PShader sh;

//VBO buffer location in the GPU
int vertexVboId;

public void setup() {
  size(1280, 720, P3D);

  kinect = new KinectPV2(this);

  kinect.enableDepthImg(true);

  kinect.enablePointCloud(true);

  kinect.setLowThresholdPC(minD);
  kinect.setHighThresholdPC(maxD);

  kinect.init();

  sh = loadShader("frag.glsl", "vert.glsl");

  PGL pgl = beginPGL();

  IntBuffer intBuffer = IntBuffer.allocate(1);
  pgl.genBuffers(1, intBuffer);

  //memory location of the VBO
  vertexVboId = intBuffer.get(0);

  endPGL();
 
}


public void draw() {
  background(0);

  //draw the depth capture images
  //image(kinect.getDepthImage(), 0, 0, 320, 240);
  //image(kinect.getPointCloudDepthImage(), 320, 0, 320, 240);

  //translate the scene to the center
  translate(width / 2, height / 2, zval);
  scale(scaleVal, -1 * scaleVal, scaleVal);
  rotate(a, 0.0f, 1.0f, 0.0f);

  // Threahold of the point Cloud.
  kinect.setLowThresholdPC(minD);
  kinect.setHighThresholdPC(maxD);

  //get the points in 3d space
  FloatBuffer pointCloudBuffer = kinect.getPointCloudDepthPos();

  // obtain XYZ the values of the point cloud
 
  stroke(0, 0, 0);
  for(int i = 0; i < kinect.WIDTHDepth * kinect.HEIGHTDepth; i+=3){
      float x = pointCloudBuffer.get(i*3 + 0) * scaleDepthPoint;
      float y = pointCloudBuffer.get(i*3 + 1) * scaleDepthPoint;
      float z = pointCloudBuffer.get(i*3 + 2) * scaleDepthPoint;
   
      point(x, y, z);
   }
   

  //begin openGL calls and bind the shader
  pgl = beginPGL();
  sh.bind();

  //obtain the vertex location in the shaders.
  //useful to know what shader to use when drawing the vertex positions
  vertLoc = pgl.getAttribLocation(sh.glProgram, "vertex");

  pgl.enableVertexAttribArray(vertLoc);

  //data size times 3 for each XYZ coordinate
  int vertData = kinect.WIDTHDepth * kinect.HEIGHTDepth * 3;

  //bind vertex positions to the VBO
  {
    pgl.bindBuffer(PGL.ARRAY_BUFFER, vertexVboId);
    // fill VBO with data
    pgl.bufferData(PGL.ARRAY_BUFFER,   Float.BYTES * vertData, pointCloudBuffer, PGL.DYNAMIC_DRAW);
    // associate currently bound VBO with shader attribute
    pgl.vertexAttribPointer(vertLoc, 3, PGL.FLOAT, false,  Float.BYTES * 3, 0 );
  }
 
   // unbind VBOs
  pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);

  //draw the point buffer as a set of POINTS
  pgl.drawArrays(PGL.POINTS, 0, vertData);

  //disable the vertex positions
  pgl.disableVertexAttribArray(vertLoc);

  //finish drawing
  sh.unbind();
  endPGL();


  stroke(255, 0, 0);
  text(frameRate, 50, height - 50);
 
/* Get the point cloud as a PImage
   * Each pixel of the PointCloudDepthImage correspondes to the value
   * of the Z in the Point Cloud or distances, the values of
   *  the Point cloud are mapped from (0 - 4500) mm  to gray color (0 - 255)
   */
  image(kinect.getPointCloudDepthImage(), 512, 0);
  //raw Data int valeus from [0 - 4500]
  int [] rawData = kinect.getRawDepthData();
 
 
}

public void mousePressed() {
  // saveFrame();
}


public void keyPressed() {
  if (key == 'a') {
    zval +=10;
    println("Z Value "+zval);
  }
  if (key == 's') {
    zval -= 10;
    println("Z Value "+zval);
  }

  if (key == 'z') {
    scaleVal += 0.1;
    println("Scale scene: "+scaleVal);
  }
  if (key == 'x') {
    scaleVal -= 0.1;
    println("Scale scene: "+scaleVal);
  }

  if (key == 'q') {
    a += 0.1;
    println("rotate scene: "+ a);
  }
  if (key == 'w') {
    a -= 0.1;
    println("rotate scene: "+a);
  }

  if (key == '1') {
    minD += 10;
    println("Change min: "+minD);
  }

  if (key == '2') {
    minD -= 10;
    println("Change min: "+minD);
  }

  if (key == '3') {
    maxD += 10;
    println("Change max: "+maxD);
  }

  if (key == '4') {
    maxD -= 10;
    println("Change max: "+maxD);
  }
 
  if(key == 'c'){
    scaleDepthPoint += 1;
    println("Change Scale Depth Point: "+scaleDepthPoint);
  }
 
    if(key == 'v'){
    scaleDepthPoint -= 1;
    println("Change Scale Depth Point: "+scaleDepthPoint);
  }
 
}

Pour ceux qui ont déjà touché à ce genre de code, est ce que cette partie :

  for(int i = 0; i < kinect.WIDTHDepth * kinect.HEIGHTDepth; i+=3){
      float x = pointCloudBuffer.get(i*3 + 0) * scaleDepthPoint;
      float y = pointCloudBuffer.get(i*3 + 1) * scaleDepthPoint;
      float z = pointCloudBuffer.get(i*3 + 2) * scaleDepthPoint;
   
      point(x, y, z);
   }

ou celle ci

/* Get the point cloud as a PImage
   * Each pixel of the PointCloudDepthImage correspondes to the value
   * of the Z in the Point Cloud or distances, the values of
   *  the Point cloud are mapped from (0 - 4500) mm  to gray color (0 - 255)
   */
  image(kinect.getPointCloudDepthImage(), 512, 0);
  //raw Data int valeus from [0 - 4500]
  int [] rawData = kinect.getRawDepthData();

me permettrait d'obtenir les fameuses coordonnées ?

Merci à vous et bonne soirée smile

Hors ligne

 

#2 2017-07-19 16:09:32 Re : Kinect + Processing : Point Cloud

emoc
@#@*$
Lieu: Quimper
Date d'inscription: 2008-01-28
Messages: 1573
Site web

Re: Kinect + Processing : Point Cloud



Hello

Je dirais bien que les coordonnées de chaque point sont enregistrées à la suite dans pointCloudBuffer (sous cette forme  :x0, y0, z0, x1, y1, z1, x2, y2, z2 ,etc...) et que cette boucle permet de les afficher dans un espace 3D

for(int i = 0; i < kinect.WIDTHDepth * kinect.HEIGHTDepth; i+=3){
      float x = pointCloudBuffer.get(i*3 + 0) * scaleDepthPoint;
      float y = pointCloudBuffer.get(i*3 + 1) * scaleDepthPoint;
      float z = pointCloudBuffer.get(i*3 + 2) * scaleDepthPoint;
      point(x, y, z);
   }

Hors ligne

 

#3 2017-07-21 20:07:50 Re : Kinect + Processing : Point Cloud

akherraz
nouveau membre
Date d'inscription: 2016-09-26
Messages: 4

Re: Kinect + Processing : Point Cloud



Salut Emoc merci pour ta réponse ! smile Penses-tu qu’il est possible d’exploiter ce bout de code pour créer des collisions (entres elles et avec le pointeur de ma souris ? (je suppose que c’est une histoire avec dist() ainsi que les positions x et y, j’essaie de comprendre actuellement via internet comment fonctionne ce principe de collision).

Hors ligne

 

#4 2017-07-23 11:54:44 Re : Kinect + Processing : Point Cloud

emoc
@#@*$
Lieu: Quimper
Date d'inscription: 2008-01-28
Messages: 1573
Site web

Re: Kinect + Processing : Point Cloud



akherraz a écrit:

Penses-tu qu’il est possible d’exploiter ce bout de code pour créer des collisions (entres elles et avec le pointeur de ma souris ? (je suppose que c’est une histoire avec dist()

Salut

Oui, dist() permet de calculer une distance en 3D https://processing.org/reference/dist_.html
Le principe est de calculer pour chaque point, sa distance avec tous les autres (boucle dans la boucle), ce qui selon le nombre de points peut prendre pas mal de temps, selon le nombre de points. C'est donc à affiner selon ce que tu veux faire et la vitesse de calcul de ta machine

Hors ligne

 

#5 2017-07-25 15:25:02 Re : Kinect + Processing : Point Cloud

akherraz
nouveau membre
Date d'inscription: 2016-09-26
Messages: 4

Re: Kinect + Processing : Point Cloud



Ok merci pour l’info big_smile

Je vais voir ce que je peux faire car depuis j’essaie de créer des collisions entre ces points et des particules que je génère au mousePressed. Il y a donc un tableau pour les points du Cloud et un tableau pour la génération des particules (c’est plus difficile de lier les deux haha).

Hors ligne

 

#6 2017-07-29 01:26:26 Re : Kinect + Processing : Point Cloud

alvink
membre
Date d'inscription: 2016-10-23
Messages: 10

Re: Kinect + Processing : Point Cloud



Hello tout le monde, étant désespéré je vous montre mon code en espérant que quelqu'un puisse voir où se trouve le problème :

//kinect//


//librairies kinect
import java.nio.*;
import KinectPV2.*;

KinectPV2 kinect;


int  vertLoc;

//transformations
float a = 0;
int zval = -50;
float scaleVal = 320;


//value to scale the depth point when accessing each individual point in the PC.
float scaleDepthPoint = 100.0;

//Distance Threashold
int maxD = 4000; // 4m
int minD = 0;  //  0m

//openGL object and shader
PGL     pgl;
PShader sh;

//VBO buffer location in the GPU
int vertexVboId;



//touchEvent receiver

// on importe la bibliothèque OscP5
import oscP5.*;
import netP5.*;

//création d'un objet OscP5 appelé 'oscP5'
OscP5 oscP5;
NetAddress myRemoteLocation;

//creation des variables qui récupèreront les positions x et y du doigt sur les écrans des smartphones
float positionX, positionY, positionX02, positionY02, positionX03, positionY03;

// creation des particles
import java.util.Iterator;
ArrayList<Part> parts;
float w = 600;
float h = 900;
float g = 1.8;
float noiseoff=0;
//GifMaker gifExport;
color bgc = #495455;
boolean record=false;




public void setup() {
  size(1280, 720, P3D);

  kinect = new KinectPV2(this);

  kinect.enableDepthImg(true);

  kinect.enablePointCloud(true);

  kinect.setLowThresholdPC(minD);
  kinect.setHighThresholdPC(maxD);

  kinect.init();

  sh = loadShader("frag.glsl", "vert.glsl");

  PGL pgl = beginPGL();

  IntBuffer intBuffer = IntBuffer.allocate(1);
  pgl.genBuffers(1, intBuffer);

  //memory location of the VBO
  vertexVboId = intBuffer.get(0);

  endPGL();

  //touchEvent receiver
  //paramétrage de l'objet oscP5 qui recevra les données
  oscP5 = new OscP5(this, 12000);
  myRemoteLocation = new NetAddress("192.168.0.101", 32000);
  //au départ, on place notre cercle au centre
  positionX = width/2;
  positionY = height/2;
  //on desactive les dessin des contours
  noStroke();

  // creation des particules
  smooth();
  background(bgc);
  frameRate(25);
  parts = new ArrayList();
}

public void draw() {

  background(0);

  //draw the depth capture images
  //image(kinect.getDepthImage(), 0, 0, 320, 240);
  //image(kinect.getPointCloudDepthImage(), 320, 0, 320, 240);


  // creation des particles : si record = true alors on lance la fonction création des particules
  if (record) {
    paint();
    paint02();
    paint03();
  }

  updateParticles();
  fill(255);


  //translate the scene to the center
  translate(width / 2, height / 2, zval);
  scale(scaleVal, -1 * scaleVal, scaleVal);
  rotate(a, 0.0f, 1.0f, 0.0f);

  // Threahold of the point Cloud.
  kinect.setLowThresholdPC(minD);
  kinect.setHighThresholdPC(maxD);

  //get the points in 3d space
  FloatBuffer pointCloudBuffer = kinect.getPointCloudDepthPos();

  // obtain XYZ the values of the point cloud

  stroke(0, 0, 0);
  for (int i = 0; i < kinect.WIDTHDepth * kinect.HEIGHTDepth; i+=3) {
    float x = pointCloudBuffer.get(i*3 + 0) * scaleDepthPoint;
    float y = pointCloudBuffer.get(i*3 + 1) * scaleDepthPoint;
    float z = pointCloudBuffer.get(i*3 + 2) * scaleDepthPoint;
  }


  //begin openGL calls and bind the shader
  pgl = beginPGL();
  sh.bind();

  //obtain the vertex location in the shaders.
  //useful to know what shader to use when drawing the vertex positions
  vertLoc = pgl.getAttribLocation(sh.glProgram, "vertex");

  pgl.enableVertexAttribArray(vertLoc);

  //data size times 3 for each XYZ coordinate
  int vertData = kinect.WIDTHDepth * kinect.HEIGHTDepth * 3;


  //bind vertex positions to the VBO
  {
    pgl.bindBuffer(PGL.ARRAY_BUFFER, vertexVboId);
    // fill VBO with data
    pgl.bufferData(PGL.ARRAY_BUFFER, Float.BYTES * vertData, pointCloudBuffer, PGL.DYNAMIC_DRAW);
    // associate currently bound VBO with shader attribute
    pgl.vertexAttribPointer(vertLoc, 3, PGL.FLOAT, false, Float.BYTES * 3, 0 );
  }

  // unbind VBOs
  pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);

  //draw the point buffer as a set of POINTS
  pgl.drawArrays(PGL.POINTS, 0, vertData);

  //disable the vertex positions
  pgl.disableVertexAttribArray(vertLoc);

  //finish drawing
  sh.unbind();
  endPGL();


  stroke(255, 0, 0);
  text(frameRate, 50, height - 50);
}


//touchEvent receiver
// fonction creation des particles pour le smartphone 01
void paint() {
  float tx = positionX;
  float ty = positionY;
  color c1 = #FFFFFF;
  color c2 = #FFFFFF;

  float x = random(w);
  float y = random(h);
  float t=15+random(20);

  color c = lerpColor(c1, c2, random(1));
  Part p = new Part(tx, ty, random(5)+1, c); 
  p.velocity.x=0;
  p.velocity.y=0;
  p.acceleration.x=random(1)-.5;
  p.acceleration.y=random(1)-.5;
  p.life=1;
  parts.add(p);
}

// fonction creation des particles pour le smartphone 02
void paint02() {
  float tx = positionX02;
  float ty = positionY02;
  color c1 = #FFFFFF;
  color c2 = #FFFFFF;

  float x = random(w);
  float y = random(h);
  float t=15+random(20);

  color c = lerpColor(c1, c2, random(1));
  Part p = new Part(tx, ty, random(5)+1, c); 
  p.velocity.x=0;
  p.velocity.y=0;
  p.acceleration.x=random(1)-.5;
  p.acceleration.y=random(1)-.5;
  p.life=1;
  parts.add(p);
}

// fonction creation des particles pour le smartphone 03
void paint03() {
  float tx = positionX03;
  float ty = positionY03;
  color c1 = #FFFFFF;
  color c2 = #FFFFFF;

  float x = random(w);
  float y = random(h);
  float t=15+random(20);

  color c = lerpColor(c1, c2, random(1));
  Part p = new Part(tx, ty, random(5)+1, c); 
  p.velocity.x=0;
  p.velocity.y=0;
  p.acceleration.x=random(1)-.5;
  p.acceleration.y=random(1)-.5;
  p.life=1;
  parts.add(p);
}


void updateParticles() {
  if (parts.size()>=0) {
    for (int i = parts.size()-1; i >= 0; i--) {
      Part p = (Part) parts.get(i);

      p.update();
      //p.render();
      if (p.life<0) {
        parts.remove(p);
      }
    }
    for (Part p : parts) {

      // p.update();
      p.render();
    }
  }
}

//class pour les particules

class Part {
  float life = 1;
  float maxspeed=10;
  // float g=1.8;
  PVector position = new PVector(0, 0);
  PVector velocity = new PVector(0, 0);
  PVector acceleration = new PVector(0, 0);
  float size = 10;
  color c;
  float min_d = 90;
  Part nei = null;
  Part(float x, float y, float size, color c) {
    position.x=x;
    position.y=y;
    this.size = size;
    this.c=c;
  }
  void update() {
    life-=.01;

    // size=random(5);
    if (position.x>w) {
      position.x=0;
    } else if (position.x<0) {
      position.x=w;
    }
    if (position.y>h) {
      position.y=0;
    } else if (position.y<0) {
      position.y=w;
    } 

    //collision entre particules et génération des lignes entre elles
    for (Part p : parts) {
      if (p!=this) {       
        float d = PVector.dist(p.position, position);
        if (d<min_d) {
          acceleration = PVector.sub(p.position, position);
          acceleration.normalize();
          acceleration.mult(.1);

          pushMatrix();
          translate(position.x, position.y);
          //stroke(c, 110-d/min_d*100);
          stroke(255, 1+life*155);
          //strokeWeight(d/min_d*2);
          //    line(-velocity.x, -velocity.y, 0, 0);
          line(p.position.x-position.x, p.position.y-position.y, 0, 0);
          popMatrix();
        }
      }
    }
    velocity.add(acceleration);
    velocity.limit(3);

    position.add(velocity);
  }
  void render() {   
    pushMatrix();
    translate(position.x, position.y);


    //stroke(c);
    //    line(-velocity.x, -velocity.y, 0, 0);
    //line(nei.position.x-position.x, nei.position.y-position.y, 0, 0);
    noStroke();

    fill(c, 3+life*255);
    //fill(c);
    //rectMode(CENTER);
    //rect(0, 0, size+6, size+6);
    ellipseMode(CENTER);
    // taille particules
    ellipse(0, 0, size+1, size+1);

    popMatrix();
  }
  //
}



// methode oscevent permettant d'ecouter les evenements OSC
void oscEvent(OscMessage theOscMessage) {
  // si l'applet reçoit un messag OSC avec l'address pattern "/positionsCurseur"
  if (theOscMessage.checkAddrPattern("/positionsCurseur")==true) {
    //on assigne les valeurs de l'index 0, de type integer (.intValue)  du message OSC
    //à la variable positionX que l'on assignera à la coordonnée x de notre cercle
    positionX = theOscMessage.get(0).intValue();
    //on assigne les valeurs de l'index 1, de type integer (.intValue)  du message OSC
    //à la variable positionY que l'on assignera à la coordonnée y de notre cercle
    positionY = theOscMessage.get(1).intValue();   
    record=true;
  } else if (theOscMessage.checkAddrPattern("/positionsCurseur02")==true) {
    //on assigne les valeurs de l'index 0, de type integer (.intValue)  du message OSC
    //à la variable positionX que l'on assignera à la coordonnée x de notre cercle
    positionX02 = theOscMessage.get(0).intValue();
    //on assigne les valeurs de l'index 1, de type integer (.intValue)  du message OSC
    //à la variable positionY que l'on assignera à la coordonnée y de notre cercle
    positionY02 = theOscMessage.get(1).intValue();   
    record=true;
  } else if (theOscMessage.checkAddrPattern("/positionsCurseur03")==true) {
    //on assigne les valeurs de l'index 0, de type integer (.intValue)  du message OSC
    //à la variable positionX que l'on assignera à la coordonnée x de notre cercle
    positionX03 = theOscMessage.get(0).intValue();
    //on assigne les valeurs de l'index 1, de type integer (.intValue)  du message OSC
    //à la variable positionY que l'on assignera à la coordonnée y de notre cercle
    positionY03 = theOscMessage.get(1).intValue();   
    record=true;
  }
}


/*
Simple class that manager saving each FloatBuffer and writes the data into a OBJ file
*/
class FrameBuffer {

  FloatBuffer frame;

  //id of the frame
  int frameId;

  FrameBuffer(FloatBuffer f) {
    frame = clone(f);
  }

  void setFrameId(int fId) {
    frameId = fId;
  }

  /*
  Writing of the obj file,
   */
  void saveOBJFrame() {
    int vertData = 1024 * 848;
    String[] points = new String[vertData];

    //Iterate through all the XYZ points
    for (int i = 0; i < vertData; i++) {
      float x =  frame.get(i*3 + 0);
      float y =  frame.get(i*3 + 1);
      float z =  frame.get(i*3 + 3);
      points[i] = "v "+x+" "+y+" "+z;
    }

    saveStrings("data/frame0"+frameId+".obj", points);
    println("Done Saving Frame "+frameId);
  }

  //Simple function that copys the FloatBuffer to another FloatBuffer
  public  FloatBuffer clone(FloatBuffer original) {
    FloatBuffer clone = FloatBuffer.allocate(original.capacity());
    original.rewind();//copy from the beginning
    clone.put(original);
    original.rewind();
    clone.flip();
    return clone;
  }
}




/*

public void mousePressed() {
// saveFrame();
}


public void keyPressed() {
if (key == 'a') {
zval +=10;
println("Z Value "+zval);
}
if (key == 's') {
zval -= 10;
println("Z Value "+zval);
}

if (key == 'z') {
scaleVal += 0.1;
println("Scale scene: "+scaleVal);
}
if (key == 'x') {
scaleVal -= 0.1;
println("Scale scene: "+scaleVal);
}

if (key == 'q') {
a += 0.1;
println("rotate scene: "+ a);
}
if (key == 'w') {
a -= 0.1;
println("rotate scene: "+a);
}

if (key == '1') {
minD += 10;
println("Change min: "+minD);
}

if (key == '2') {
minD -= 10;
println("Change min: "+minD);
}

if (key == '3') {
maxD += 10;
println("Change max: "+maxD);
}

if (key == '4') {
maxD -= 10;
println("Change max: "+maxD);
}

if(key == 'c'){
scaleDepthPoint += 1;
println("Change Scale Depth Point: "+scaleDepthPoint);
}

if(key == 'v'){
scaleDepthPoint -= 1;
println("Change Scale Depth Point: "+scaleDepthPoint);
}

}

*/


Il y a sûrement des doublons etc mais tout le code fonctionne, je cherche seulement à faire en sorte que mes particules générées grâce à la fonction paint, paint02 ou paint03 (car ce sont les mêmes) et la class Part puisse entrer en contact avec les points du cloud et ainsi générer des lignes entres eux.

Merci d'avance je continue de me creuser la tête...

Dernière modification par alvink (2017-07-29 01:28:12)

Hors ligne

 

fil rss de cette discussion : rss

Pied de page des forums

Powered by FluxBB

codelab, graphisme & code : emoc / 2008-2017