We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Primarily for @wblut
I have a series of points culled from a kinect point cloud (basically only those points relevant to the person, any past a certain depth are ignored)
I am having trouble choosing the appropriate tool in he_mesh to generate a mesh of these point clouds. I have been going through the examples and the references but I cannot seem to find the most appropriate method for achieving this.
If I set things up using the triangulate2d, I lose any depth information, resulting in a flat plane in the shape of the silhouette
I tried triangulate3d, but I get tetrahedra, which don't really feel like they are the right tools for this. I am hoping for a mesh I can use to finagle some awesome things out of. The example with the tetrahedra is... not that.
So, in short, what would be the best way to generate a mesh whose surface is composed of specific points from a Kinect point cloud? I'm not interested in the back of the mesh right now.
This is the code I have so far, minus the he_mesh stuff that would let me explore further.
import org.openkinect.freenect.*;
import org.openkinect.processing.*;
import java.util.List;
//for the hemesh stuff
import wblut.hemesh.*;
import wblut.core.*;
import wblut.geom.*;
import wblut.processing.*;
import wblut.math.*;
///for the gui control
import controlP5.*;
// Kinect Library object
Kinect kinect;
//for the hemesh stuff
HE_Mesh firstMesh;
WB_Render3D renderMesh;
int[] tetrahedra;
boolean makeMesh;
boolean newMesh;
///for gui controls
ControlP5 sliderStuff;
///for control values
int dCutoff = 848;
// Angle for rotation
float a = 0;
//to store points from each frame of kinect
//WB_Point[] points;
//List <WB_Coords> points
List <WB_Point> points;
// We'll use a lookup table so that we don't have to repeat the math over and over
float[] depthLookUp = new float[2048];
void setup() {
// Rendering in P3D
size(800, 600, P3D);
kinect = new Kinect(this);
kinect.initDepth();
// Lookup table for all possible depth values (0 - 2047)
for (int i = 0; i < depthLookUp.length; i++) {
depthLookUp[i] = rawDepthToMeters(i);
}
//slider to remove points past a certain depth from consideration.
sliderStuff = new ControlP5(this);
sliderStuff.addSlider("dCutoff").setPosition(10,10).setRange(0,2048);
///only make the mesh once
makeMesh = false;
newMesh = false;
}
void draw(){
background(0);
text("depth cutoff: " + dCutoff,60,60);
pushMatrix();
// Get the raw depth as array of integers
int[] depth = kinect.getRawDepth();
translate(width/2, height/2,0);
int skip = 8;
points = new ArrayList <WB_Point>();
for (int x = 0; x < kinect.width; x += skip) {
for (int y = 0; y < kinect.height; y += skip) {
int offset = x + y*kinect.width;
// Convert kinect data to world xyz coordinate
int rawDepth = depth[offset];
if (rawDepth<dCutoff){
PVector v = depthToWorld(x, y, rawDepth);
stroke(255);
pushMatrix();
// Scale up by 200
float factor = 200;
translate(v.x*factor, v.y*factor, factor-v.z*factor);
/* used for when points was an array
points[x+y*(kinect.width/skip)][0] = v.x;
points[x+y*(kinect.width/skip)][1] = v.y;
points[x+y*(kinect.width/skip)][2] = v.z;
*/
points.add (new WB_Point(v.x, v.y, v.z));
// Draw a point
point(0, 0);
popMatrix();
}
}
}
if (makeMesh & newMesh) {
//tried this, have no idea what to do with tetrahedra
//WB_Triangulation3D triangulation = WB_Triangulate.triangulate3D(points);
//tetrahedra=triangulation.getTetrahedra();
//confirms that there are points being generated
println ("there are "+points.size()+" points");
//HE_Mesh thisMesh = new HEC_FromTriangulation().setPoints(points);
//this next line results in a Null Pointer Exception, but the previous line works so: ??
firstMesh=new HE_Mesh(new HEC_FromTriangulation().setPoints(points));
firstMesh.smooth();
newMesh = false; //only make the mesh once
}
if (makeMesh){
pushMatrix();
directionalLight(255, 255, 255, 1, 1, -1);
directionalLight(127, 127, 127, -1, -1, 1);
/*
//translate(-objectRadius,-objectRadius);
renderMesh.drawFaces(firstMesh);
*/
rotateY(mouseX*1.0f/width*TWO_PI);
rotateX(mouseY*1.0f/height*TWO_PI);
for(int i=0;i<tetrahedra.length;i+=4){
WB_Point center;
pushMatrix();
/*draw the mesh stuff al'a your suggestion here
popMatrix();
}
popMatrix();
}
popMatrix();
}
void keyPressed(){
if (key == 'r') {
if (makeMesh){
makeMesh = false;
newMesh = false;
} else {
makeMesh = true;
newMesh = true;
}
}
}
// These functions come from: http://graphics.stanford.edu/~mdfisher/Kinect.html
float rawDepthToMeters(int depthValue) {
if (depthValue < 2047) {
return (float)(1.0 / ((double)(depthValue) * -0.0030711016 + 3.3309495161));
}
return 0.0f;
}
PVector depthToWorld(int x, int y, int depthValue) {
final double fx_d = 1.0 / 5.9421434211923247e+02;
final double fy_d = 1.0 / 5.9104053696870778e+02;
final double cx_d = 3.3930780975300314e+02;
final double cy_d = 2.4273913761751615e+02;
PVector result = new PVector();
double depth = depthLookUp[depthValue];//rawDepthToMeters(depthValue);
result.x = (float)((x - cx_d) * depth * fx_d);
result.y = (float)((y - cy_d) * depth * fy_d);
result.z = (float)(depth);
return result;
}
Answers
Hi @gersart,
I realise you posted this question more than a year ago and that you've probably moved on but I feel like it'd be better to provide an answer anyway, hoping it will be useful for future forum users.
I had the same problem you're describing (trying to compute 3D triangulation with Hemesh) and with the precious help of this this forum I could come up with a rather simple solution: using the Triangulate library by Nicolas Clavaud instead.
The library is available here
You can find an example sketch here
For a 3D example sketch you can have a look at the script I posted on this thread (post from may the 3rd, it's in Python but really easy to understand).
Hope that helps.
didn't stop you bumping those other threads that were from 2015
@koogs I'm confused, is it a problem ? I did it because I thought it could be useful for future forum users. I've personally spent a lot of time reading all these questions regarding 3D Delaunay triangulation hoping to find a proper solution. Sharing this workaround is a way for me:
Please tell me what is your opinion/guidelines on "bumping" old threads.