Recording a Colored Point Cloud
santoshnpl54 opened this issue · 2 comments
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!
Did you find solution?Obj does not record color, you have to use ply
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.