Stap 4: Scan jezelf met Kinect
Modelbuilder Processing Library
Modelbuilder biedt tools die maakt ons leven een stuk makkelijker maken en manipuleren van 3D-geometrie in verwerking.
De bibliotheek moet worden gebruikt met het aftastenproces heet ModelBuilder ontworpen door Marius Watz, die kan worden verkregen hier.
Installeer het als OpenNI Processing library (in de vorige stap) door het verplaatsen van de map in uw omslag van de bibliotheken van Processing.
Meestal, documenten -> Processing -> bibliotheken (zie afbeelding 2)
De schets die ik gebruikt voor het scannen van mezelf was van het type uit uit het boek 'Dingen Zie boeken maken' in hoofdstuk 5, de volledige code niet beschikbaar ergens anders.
Het boek geeft de uitleg van de details van de schets en hoe het werkt. Dit is een zeer goed boek, aanbevolen ik!
Ik een paar lijnen van de schets te maken geschikt what I 'm doing voor het project gewijzigd.
Hier is de schets:
import processing.opengl.*; import unlekker.util.*; import unlekker.modelbuilder.*; import SimpleOpenNI.*; SimpleOpenNI kinect; boolean scanning = false; //int maxZ = 2000; int maxZ = 800; int spacing = 3; UGeometry model; UVertexList vertexList; void setup() { //size(1024, 768, OPENGL); size(640, 480, OPENGL); kinect = new SimpleOpenNI(this); kinect.enableDepth(); model = new UGeometry(); vertexList = new UVertexList(); } void draw() { background(0); kinect.update(); translate(width / 2, height / 2, -1000); rotateX(radians(180)); if(scanning) { model.beginShape(TRIANGLES); } PVector[] depthPoints = kinect.depthMapRealWorld(); // cleanup pass for(int y = 0; y < 480; y += spacing) { for(int x = 0; x < 640; x += spacing) { int i = y * 640 + x; PVector p = depthPoints[i]; // if the point is on the edge or if it has no depth if(p.z < 10 || p.z > maxZ || y == 0 || y == 480 - spacing || x == 0 || x == 640 - spacing) { // replace it with a point the depth of the backplane (i.e. maxZ) PVector realWorld = new PVector(); PVector projective = new PVector(x, y, maxZ); // to get the point in the right place, we need to translate // from x/y to realWorld coordinates to match our other points: kinect.convertProjectiveToRealWorld(projective, realWorld); depthPoints[i] = realWorld; } } } for(int y = 0; y < 480 - spacing; y += spacing) { for(int x = 0; x < 640 - spacing; x += spacing) { if(scanning) { int nw = x + y * 640; int ne = (x + spacing) + y * 640; int sw = x + (y + spacing) * 640; int se = (x + spacing) + (y + spacing) * 640; model.addFace(new UVec3(depthPoints[nw].x, depthPoints[nw].y, depthPoints[nw].z), new UVec3(depthPoints[ne].x, depthPoints[ne].y, depthPoints[ne].z), new UVec3(depthPoints[sw].x, depthPoints[sw].y, depthPoints[sw].z)); model.addFace(new UVec3(depthPoints[ne].x, depthPoints[ne].y, depthPoints[ne].z), new UVec3(depthPoints[se].x, depthPoints[se].y, depthPoints[se].z), new UVec3(depthPoints[sw].x, depthPoints[sw].y, depthPoints[sw].z)); } else { stroke(255); int i = y * 640 + x; PVector currentPoint = depthPoints[i]; if(currentPoint.z < maxZ) { point(currentPoint.x, currentPoint.y, currentPoint.z); } } } } if(scanning) { model.calcBounds(); model.translate(0, 0, -maxZ); float modelWidth = (model.bb.max.x - model.bb.min.x); float modelHeight = (model.bb.max.y - model.bb.min.y); UGeometry backing = Primitive.box(modelWidth / 2, modelHeight / 2, 10); model.add(backing); model.scale(0.01); model.rotateY(radians(180)); model.toOrigin(); model.endShape(); String filename = "Scan02.stl"; //for (int i = 0; i <100; i++) { // filename.substring(4) = '0' + 1/10; // filename.substring(5) = '0' + 1%10; //create file if it does not exist on SD Card // if (!SD.exist(filename)) { // break; // } //} //SimpleDateFormat logFileFmt = new SimpleDateFormat("'scan_'yyyyMMddHHmmss'.stl'"); //model.writeSTL(this, logFileFmt.format(new Date())); model.writeSTL(this, filename); scanning = false; } } void keyPressed() { println(maxZ); if(keyCode == UP) { maxZ += 100; } if(keyCode == DOWN) { maxZ -= 100; } if(key == ' ') { scanning = true; model.reset(); } }