Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recording a Colored Point Cloud #69

Open
santoshnpl54 opened this issue Jul 25, 2018 · 2 comments
Open

Recording a Colored Point Cloud #69

santoshnpl54 opened this issue Jul 25, 2018 · 2 comments

Comments

@santoshnpl54
Copy link

santoshnpl54 commented Jul 25, 2018

Hello!
Not sure this is a good place to put this but I didn't know where else to. I'm trying to record a point cloud with color into the .obj frames to make a 3D model. I was using the ColorPointCloud and RecordPointCloud examples to try and accomplish this, but keep running across this error...

"OpenGL error 1281 at top endDraw(): invalid value"

It only happens when I add in ..

FloatBuffer colorBuffer = kinect.getColorChannelBuffer();
int vertColorData = kinect.WIDTHColor * kinect.HEIGHTColor * 3;

and..

// color
  {
    pgl.bindBuffer(PGL.ARRAY_BUFFER, colorVboId);
    // fill VBO with data
    pgl.bufferData(PGL.ARRAY_BUFFER, Float.BYTES * vertColorData, colorBuffer, PGL.DYNAMIC_DRAW);
    // associate currently bound VBO with shader attribute
    pgl.vertexAttribPointer(colorLoc, 3, PGL.FLOAT, false, Float.BYTES * 3, 0);
  }

I'm assuming it is because the depth and color buffers are colliding in a way, but I'm not sure how to combine them in the correct way. This is the current code I've pieced together (Leaving out the keys to record and such)...

/*
Thomas Sanchez Lengeling.
 http://codigogenerativo.com/
 
 KinectPV2, Kinect for Windows v2 library for processing
 
 How to record Point Cloud Data and store it in several obj files.
 Record with 'r'
 */

import java.util.ArrayList;
import java.nio.*;
import KinectPV2.*;

KinectPV2 kinect;

PGL pgl;
PShader sh;

int  vertLoc;
int colorLoc;

//transformations
float a = 7;
int zval = -50;
float scaleVal = 220;

//Distance Threashold
int maxD = 4500; // 4.5 m
int minD = 0;  //  50 cm


int numFrames =  30; // 30 frames  = 1s of recording
int frameCounter = 0; // frame counter

boolean recordFrame = false;  //recording flag
boolean doneRecording = false;

//Array where all the frames are allocated
ArrayList<FrameBuffer> mFrames;

//VBO buffer location in the GPU
int vertexVboId;
int colorVboId;

void setup() {
  size(1024, 768, P3D);

  kinect = new KinectPV2(this);

  //create arrayList
  mFrames = new ArrayList<FrameBuffer>();

  //Enable point cloud
  kinect.enableDepthImg(true);
  kinect.enablePointCloud(true);

  kinect.init();

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

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

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

  endPGL();

  //set framerate to 30
  frameRate(30);
}

void draw() {
  background(0);
  background(0);

  //draw the depth capture images
  image(kinect.getDepthImage(), 0, 0, 320, 240);
  image(kinect.getColorImage(), 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();
  
  //get the color for each point of the cloud Points
  FloatBuffer colorBuffer      = kinect.getColorChannelBuffer();

  //data size, 512 x 424 x 3 (XYZ) coordinate
  int vertData = kinect.WIDTHDepth * kinect.HEIGHTDepth  * 3;
  int vertColorData = kinect.WIDTHColor * kinect.HEIGHTColor * 3;

  pgl = beginPGL();
  sh.bind();

  vertLoc = pgl.getAttribLocation(sh.glProgram, "vertex");
  colorLoc = pgl.getAttribLocation(sh.glProgram, "color");
  
  pgl.enableVertexAttribArray(colorLoc);
  pgl.enableVertexAttribArray(vertLoc);

  //vertex
  {
    pgl.bindBuffer(PGL.ARRAY_BUFFER, vertexVboId);

    pgl.bufferData(PGL.ARRAY_BUFFER, Float.BYTES * vertData, pointCloudBuffer, PGL.DYNAMIC_DRAW);

    pgl.vertexAttribPointer(vertLoc, 3, PGL.FLOAT, false, Float.BYTES * 3, 0);
  }
  
  // color
  {
    pgl.bindBuffer(PGL.ARRAY_BUFFER, colorVboId);
    // fill VBO with data
    pgl.bufferData(PGL.ARRAY_BUFFER, Float.BYTES * vertData, colorBuffer, PGL.DYNAMIC_DRAW);
    // associate currently bound VBO with shader attribute
    pgl.vertexAttribPointer(colorLoc, 3, PGL.FLOAT, false, Float.BYTES * 3, 0);
  }
  
  // unbind VBOs
  pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);

  pgl.drawArrays(PGL.POINTS, 0, vertData);

  pgl.disableVertexAttribArray(vertLoc);

  sh.unbind();
  endPGL();

  //allocate the current pointCloudBuffer into an array of FloatBuffers
  allocateFrame(pointCloudBuffer);

  //when the allocation is done write the obj frames
  writeFrames();

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

//allocate all the frame in a temporary array
void allocateFrame(FloatBuffer buffer) {
  if (recordFrame) {
    if ( frameCounter < numFrames) {
      FrameBuffer frameBuffer = new FrameBuffer(buffer);
      frameBuffer.setFrameId(frameCounter);
      mFrames.add(frameBuffer);
    } else {
      recordFrame = false;
      doneRecording = true;
    }
    frameCounter++;
  }
}

//Write all the frames recorded
void writeFrames() {
  if (doneRecording) {
    for (int i = 0; i < mFrames.size(); i++) {
      FrameBuffer fBuffer =  (FrameBuffer)mFrames.get(i);
      fBuffer.saveOBJFrame();
    }
    doneRecording = false;
    println("Done Recording frames: "+numFrames);
  }
}

Would anyone have a better idea of what to do, or what I'm doing wrong?

Thanks!

@Phaidonas
Copy link

Phaidonas commented Apr 27, 2019

Did you find solution?Obj does not record color, you have to use ply

@Phaidonas
Copy link

my code is somehow different, i used kinect.enableColorPointCloud(true) and then tried to see the values that are stored in the buffer with a for loop:

import java.util.ArrayList;
import java.nio.*;
import KinectPV2.*;

KinectPV2 kinect;

PGL pgl;
PShader sh;

int  vertLoc;
int colorLoc;

//transformations
float a = 7;
int zval = -50;
float scaleVal = 220;

//Distance Threashold
int maxD = 4500; // 4.5 m
int minD = 0;  //  50 cm


int numFrames =  100; // 30 frames  = 1s of recording
int frameCounter = 0; // frame counter

boolean recordFrame = false;  //recording flag
boolean doneRecording = false;

//Array where all the frames are allocated
ArrayList<FrameBuffer> mFrames;

//VBO buffer location in the GPU
int vertexVboId;
int colorVboId;


void setup() {
  size(1024, 768, P3D);

  kinect = new KinectPV2(this);

  //create arrayList
  mFrames = new ArrayList<FrameBuffer>();

  //Enable point cloud
  kinect.enableDepthImg(true);
  kinect.enableColorImg(true);
  kinect.enableColorPointCloud(true);

  kinect.init();

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

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

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

  endPGL();

  //set framerate to 30
  frameRate(30);
}

void draw() {
  background(0);
  background(0);

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

  pushMatrix();
  //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);
  pgl = beginPGL();
  sh.bind();
  //get the points in 3d space
  FloatBuffer pointCloudBuffer = kinect.getPointCloudColorPos();
  
  FloatBuffer colorBuffer      = kinect.getColorChannelBuffer();


  //data size, 512 x 424 x 3 (XYZ) coordinate
  int vertData = kinect.WIDTHColor * kinect.HEIGHTColor  * 3;



  vertLoc = pgl.getAttribLocation(sh.glProgram, "vertex");

  pgl.enableVertexAttribArray(vertLoc);

  //vertex
  {
    pgl.bindBuffer(PGL.ARRAY_BUFFER, vertexVboId);

    pgl.bufferData(PGL.ARRAY_BUFFER, Float.BYTES * vertData, pointCloudBuffer, PGL.DYNAMIC_DRAW);

    pgl.vertexAttribPointer(vertLoc, 3, PGL.FLOAT, false, Float.BYTES * 3, 0);
  }
  
    {
    pgl.bindBuffer(PGL.ARRAY_BUFFER, colorVboId);
    // fill VBO with data
    pgl.bufferData(PGL.ARRAY_BUFFER, Float.BYTES * vertData, colorBuffer, PGL.DYNAMIC_DRAW);
    // associate currently bound VBO with shader attribute
    pgl.vertexAttribPointer(colorLoc, 3, PGL.FLOAT, false, Float.BYTES * 3, 0);
  }
  
  
  // unbind VBOs
  pgl.bindBuffer(PGL.ARRAY_BUFFER, 0);

  pgl.drawArrays(PGL.POINTS, 0, vertData);

  pgl.disableVertexAttribArray(vertLoc);
  pgl.disableVertexAttribArray(colorLoc);

  sh.unbind();
  endPGL();

popMatrix();
  //allocate the current pointCloudBuffer into an array of FloatBuffers
  allocateFrame(pointCloudBuffer);
for (int i = 0; i < 5000; i++) {
  println("r :"+colorBuffer.get(i*3 + 0));
  println("g :"+colorBuffer.get(i*3 + 1));
  println("b :"+colorBuffer.get(i*3 + 2));
    println("x :"+pointCloudBuffer.get(i*3 + 0));
  println("y :"+pointCloudBuffer.get(i*3 + 1));
  println("z :"+pointCloudBuffer.get(i*3 + 2));
}
  //when the allocation is done write the obj frames
  writeFrames();

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

//allocate all the frame in a temporary array
void allocateFrame(FloatBuffer buffer) {
  if (recordFrame) {
    if ( frameCounter < numFrames) {
      FrameBuffer frameBuffer = new FrameBuffer(buffer);
      frameBuffer.setFrameId(frameCounter);
      mFrames.add(frameBuffer);
    } else {
      recordFrame = false;
      doneRecording = true;
    }
    frameCounter++;
  }
}

//Write all the frames recorded
void writeFrames() {
  if (doneRecording) {
    for (int i = 0; i < mFrames.size(); i++) {
      FrameBuffer fBuffer =  (FrameBuffer)mFrames.get(i);
      fBuffer.saveOBJFrame();
    }
    doneRecording = false;
    println("Done Recording frames: "+numFrames);
  }
}

public void mousePressed() {

  println(frameRate);
  // saveFrame();
}

public void keyPressed() {

  //start recording 30 frames with 'r'
  if (key == 'r') {
    recordFrame = true;
  }
  if (key == 'a') {
    zval +=1;
    println(zval);
  }
  if (key == 's') {
    zval -= 1;
    println(zval);
  }

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

  if (key == 'q') {
    a += 0.1;
    println(a);
  }
  if (key == 'w') {
    a -= 0.1;
    println(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);
  }
}

Now the main problem is that some of the values of pointCloudBuffer return - infinity, but in the record point cloud return regular, also the color is not rendered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants