Esempio n. 1
0
void testApp::update() {
	kinect.update();
	if(kinect.isFrameNew()) { // only recompute the mesh if necessary
		int width = kinect.getWidth();
		int height = kinect.getHeight();
		float* distancePixels = kinect.getDistancePixels(); // distance in centimeters
		mesh.clear();
		mesh.setMode(OF_TRIANGLES_MODE);
		for(int y = 0; y < height - 1; y++) { // don't go to the end
			for(int x = 0; x < width - 1; x++) { // don't go to the end
			
				// get indices for each corner
				int nwi = (y + 0) * width + (x + 0);
				int nei = (y + 0) * width + (x + 1);
				int sei = (y + 1) * width + (x + 1);
				int swi = (y + 1) * width + (x + 0);
				
				// get z values for each corner
				float nwz = distancePixels[nwi];
				float nez = distancePixels[nei];
				float sez = distancePixels[sei];
				float swz = distancePixels[swi];
				
				if(nwz > 0 && nez > 0 && sez > 0 && swz > 0) { // ignore empty depth pixels
					// get real world locations for each corner
					ofVec3f nwv = ConvertProjectiveToRealWorld(x + 0, y + 0, nwz);
					ofVec3f nev = ConvertProjectiveToRealWorld(x + 1, y + 0, nez);
					ofVec3f sev = ConvertProjectiveToRealWorld(x + 1, y + 1, sez);
					ofVec3f swv = ConvertProjectiveToRealWorld(x + 0, y + 1, swz);
					
					// compute normal for the upper left
					ofVec3f normal = getNormal(nwv, nev, swv);
				
					// add the upper left triangle
					mesh.addNormal(normal);
					mesh.addVertex(nwv);
					mesh.addNormal(normal);
					mesh.addVertex(nev);
					mesh.addNormal(normal);
					mesh.addVertex(swv);
					
					// add the bottom right triangle
					mesh.addNormal(normal);
					mesh.addVertex(nev);
					mesh.addNormal(normal);
					mesh.addVertex(sev);
					mesh.addNormal(normal);
					mesh.addVertex(swv);
				}
			}
		}
	}
}
Esempio n. 2
0
void testApp::updateTrianglesSimplify() {	
	// zero edges
	for(int x = roiStart.x; x < roiEnd.x; x++) {
		surface[getSurfaceIndex(x, roiStart.y)] = ConvertProjectiveToRealWorld(x, roiStart.y, zCutoff); // top
		surface[getSurfaceIndex(x, roiEnd.y - 1)] = ConvertProjectiveToRealWorld(x, roiEnd.y - 1, zCutoff); // bottom
	}
	for(int y = roiStart.y; y < roiEnd.y; y++) {
		surface[getSurfaceIndex(roiStart.x, y)] = ConvertProjectiveToRealWorld(roiStart.x, y, zCutoff); // left
		surface[getSurfaceIndex(roiEnd.x - 1, y)] = ConvertProjectiveToRealWorld(roiEnd.x - 1, y, zCutoff); // right
	}
	
	triangles.resize((roiEnd.x - roiStart.x) * (roiEnd.y - roiStart.y) * 2);
	int totalTriangles = 0;
	Triangle* topTriangle;
	Triangle* bottomTriangle;
	float* z = kinect.getDistancePixels();
	for(int y = roiStart.y; y < roiEnd.y - 1; y++) {
		bool stretching = false;
		for(int x = roiStart.x; x < roiEnd.x - 1; x++) {
			bool endOfRow = (x == roiEnd.x - 2);
			
			int nw = getSurfaceIndex(x, y);
			int ne = getSurfaceIndex(x + 1, y);
			int sw = getSurfaceIndex(x, y + 1);
			int se = getSurfaceIndex(x + 1, y + 1);
			
			bool flat = (z[nw] == z[ne] && z[nw] == z[sw] && z[nw] == z[se]);
			if(endOfRow ||
				 (stretching && flat)) {
				// stretch the quad to our new position
				topTriangle->vert2 = surface[ne];
				bottomTriangle->vert1 = surface[ne];
				bottomTriangle->vert2 = surface[se];				
			} else {			
				topTriangle = &triangles[totalTriangles++];
				topTriangle->vert1 = surface[nw];
				topTriangle->vert2 = surface[ne];
				topTriangle->vert3 = surface[sw];
				
				bottomTriangle = &triangles[totalTriangles++];
				bottomTriangle->vert1 = surface[ne];
				bottomTriangle->vert2 = surface[se];
				bottomTriangle->vert3 = surface[sw];
				
				stretching = flat;
			}
		}
	}
	
	triangles.resize(totalTriangles);
}
Esempio n. 3
0
void testApp::update() {
	kinect.update();
	if(kinect.isFrameNew()) {
		registerDepth(kinect.getRawDepthPixels(), &registeredDepth[0]);
		cloud.clear();
		cloud.setMode(OF_PRIMITIVE_POINTS);
		int width = kinect.getWidth();
		int height = kinect.getHeight();
		for(int y = 0; y < height; y++) {
			for(int x = 0; x < width; x++) {
				int i = y * width + x;
				float z = registeredDepth[i]; // in mm
				if(z != 0) { // ignore empty depth pixels
					ofColor curColor = kinect.getColorAt(x, y);
					float absDiff = 0;
					absDiff += abs((float) curColor.r - (float) trackColor.r);
					absDiff += abs((float) curColor.g - (float) trackColor.g);
					absDiff += abs((float) curColor.b - (float) trackColor.b);
					absDiff /= 3;
					trackImage.getPixels()[i] = absDiff;
					
					if(absDiff < mouseX) {
						cloud.addColor(kinect.getColorAt(x, y));
						cloud.addVertex(ConvertProjectiveToRealWorld(x, y, z));
					}
				}
			}
		}
		trackImage.update();
	}
}
void ofxVirtualCamera::updateSurface() {
	float* z = kinect.getDistancePixels();
	int i = 0;
	for(int y = 0; y < camHeight; y++) {
		for(int x = 0; x < camWidth; x++) {
			if(z[i] != 0) {
				surface[i] = ConvertProjectiveToRealWorld(x, y, -z[i]);
			}
			i++;
		}
	}
}
Esempio n. 5
0
void testApp::updateSurface() {
	float* z = kinect.getDistancePixels();
	float alpha = panel.getValueF("temporalBlur");
	float beta = 1 - alpha;
	Mat kinectMat = Mat(480, 640, CV_32FC1, z);
	Mat kinectBuffer = Mat(480, 640, CV_32FC1, z);
	cv::addWeighted(kinectBuffer, alpha, kinectMat, beta, 0, kinectBuffer);
	ofxCv::copy(kinectMat, kinectBuffer);
	
	int i = 0;
	for(int y = 0; y < Yres; y++) {
		for(int x = 0; x < Xres; x++) {
			surface[i] = ConvertProjectiveToRealWorld(x, y, z[i]);
			i++;
		}
	}
}
Esempio n. 6
0
void testApp::update() {
	kinect.update();
	if(kinect.isFrameNew()) {
		int width = kinect.getWidth();
		int height = kinect.getHeight();
		float* distancePixels = kinect.getDistancePixels(); // distance in centimeters
		cloud.clear();
		cloud.setMode(OF_PRIMITIVE_POINTS);
		for(int y = 0; y < height; y++) {
			for(int x = 0; x < width; x++) {
				int i = y * width + x;
				float z = distancePixels[i];
				if(z != 0) { // ignore empty depth pixels
					cloud.addVertex(ConvertProjectiveToRealWorld(x, y, z));
				}
			}
		}
	}
	if(exportPly) {
		exportPlyCloud("cloud.ply", cloud);
		exportPly = false;
	}
}
Esempio n. 7
0
Mat Kinect::retrievePointCloud(Mat& depthImage)
{
	ConvertProjectiveToRealWorld(depthImage);
	return mPointCloud;
}
Esempio n. 8
0
void testApp::draw() {
	ofBackground(245);
    ofSetColor(255);  //everything drawn with white tint
	kinect.drawDepth(0, 0);
	easyCam.begin();
    
    ofScale(1, -1, -1);
    //ofTranslate(0, 0, -200);
    
   

    ofSetColor(0);
	int width = kinect.getWidth();
	int height = kinect.getHeight();
	
	float* distancePixels = kinect.getDistancePixels(); 
    ofMesh cloud;
    cloud.setMode(OF_PRIMITIVE_POINTS);

    float minZ = 1500;
    float minX = 0;
    float minY = 0;
    float dist = 1500;
    float secondZ = 1500;
    float secondX = 0;
    float secondY = 0;
    
	for(int y = 0; y < height; y++) {
		for(int x = 0; x < width; x++) {
			int i = y * width + x;
			float z = distancePixels[i];
            
            if(z !=0 && z < 1500 && drawCloud == true) cloud.addVertex(ConvertProjectiveToRealWorld(x, y, z));
			
            if(z != 0 && z < minZ) {
                minZ= z;
                minX = x;
                minY = y;
                forepoint = ConvertProjectiveToRealWorld(minX, minY, minZ);
			}
            else if ( z !=0 && z > minZ && z-minZ < dist) {
                dist = z - minZ;
                secondZ = z;
                secondX = x;
                secondY = y;
                
            }
		}
	}
    if(drawCloud) cloud.draw();
    
    //secondPoint = ConvertProjectiveToRealWorld(secondX, secondY, secondZ);

    ofSetColor(50);
    if(doDrawing) {
        drawing.addVertex(forepoint);
        //drawing2.addVertex(secondPoint);
    }
    //drawing.draw();
    //drawing2.draw();
    
   
    //ofCircle(secondPoint.x, secondPoint.y, 5);
    
    if(drawCopy) {
        meshCopy.draw();
    }
        
    easyCam.end();
    
    //averaging the data in a region around the forepoint
    ofNoFill();
    int searchRadius = 64;
    int searchDistance = 100;
    int count = 0;
    ofVec3f sum = ofVec3f(0, 0, 0);

    ofRect(minX-searchRadius/2, minY+searchRadius/2, searchRadius, searchRadius);
    for(int x = -searchRadius/2; x < searchRadius/2; x++) {
        for (int y = -searchRadius/2; y < searchRadius/2; y++) {
            int curx = x+minX;
            int cury = y+ minY;
            if( curx < width && curx >0 && y + cury >0 && cury < height) {
                int i = cury*width + curx;
                float z = distancePixels[i];
                if(z!=0 && z-minZ < searchDistance) {
                    sum.x+= curx;
                    sum.y+= cury;
                    //unlike x and y, z is taken from distancePixels[i] so dont adjust for current (x, y) like curx cury
                    sum.z+= z;
                    count++;
                }
            }
        }
    }
    
    //we are only looking at a single point. no perspective issue involed?
    //ofVec3f avg = ConvertProjectiveToRealWorld(sum.x/count, sum.y/count, sum.z/count);
    
    ofSetColor(0, 255, 0);
    ofFill();
    ofCircle(avg.x, avg.y, 5);
    ofSetColor(255, 0, 0);
    ofFill();
    ofCircle(forepoint.x, forepoint.y, 5);
    
    ofSetColor(0);
    ofDrawBitmapString( "space bar to render / t to resume", 50, 100);
    ofDrawBitmapString( ofToString(forepoint.x) + "/" + ofToString(avg.x), 50, 150);
}
Esempio n. 9
0
void testApp::update() {	
	kinect.update();
	if(!panel.getValueB("pause") && kinect.isFrameNew())	{
		zCutoff = panel.getValueF("zCutoff");
		
		float fovWidth = panel.getValueF("fovWidth");
		float fovHeight = panel.getValueF("fovHeight");
		int left = Xres * (1 - fovWidth) / 2;
		int top = Yres * (1 - fovHeight) / 2;
		int right = left + Xres * fovWidth;
		int bottom = top + Yres * fovHeight;
		roiStart = Point2d(left, top);
		roiEnd = Point2d(right, bottom);
		
		ofVec3f nw = ConvertProjectiveToRealWorld(roiStart.x, roiStart.y, zCutoff);
		ofVec3f se = ConvertProjectiveToRealWorld(roiEnd.x - 1, roiEnd.y - 1, zCutoff);
		float width = (se - nw).x;
		float height = (se - nw).y;
		globalScale = panel.getValueF("stlSize") / MAX(width, height);
		
		backOffset = panel.getValueF("backOffset") / globalScale;
		
		cutoffKinect();
		
		if(panel.getValueB("useSmoothing")) {
			smoothKinect();
		}
		
		if(panel.getValueB("useWatermark")) {
			startTimer();
			injectWatermark();
			injectWatermarkTime = stopTimer();
		}
		
		startTimer();
		updateSurface();
		updateSurfaceTime = stopTimer();
		
		bool exportStl = panel.getValueB("exportStl");
		bool useRandomExport = panel.getValueB("useRandomExport");
		
		startTimer();
		if((exportStl && useRandomExport) || panel.getValueB("useRandom")) {
			updateTrianglesRandom();
		} else if(panel.getValueB("useSimplify")) {
			updateTrianglesSimplify();
		} else {
			updateTriangles();
		}
		calculateNormals(triangles, normals);
		updateTrianglesTime = stopTimer();
		
		startTimer();
		updateBack();
		updateBackTime = stopTimer();
		
		startTimer();
		postProcess();
		postProcessTime = stopTimer();
		
		if(exportStl) {
			string pocoTime = Poco::DateTimeFormatter::format(Poco::LocalDateTime(), "%Y-%m-%d at %H.%M.%S");
			
			ofxSTLExporter exporter;
			exporter.beginModel("Kinect Export");
			addTriangles(exporter, triangles, normals);
			addTriangles(exporter, backTriangles, backNormals);
			exporter.saveModel("Kinect Export " + pocoTime + ".stl");
			
#ifdef USE_REPLICATORG
			if(printer.isConnected()) {
				printer.printToFile("/home/matt/MakerBot/repg_workspace/ReplicatorG/examples/Snake.stl", "/home/matt/Desktop/snake.s3g");
			}
#endif
			
			panel.setValueB("exportStl", false);
		}
	}
	
	float diffuse = panel.getValueF("diffuseAmount");
	redLight.setDiffuseColor(ofColor(diffuse / 2, diffuse / 2, 0));
	greenLight.setDiffuseColor(ofColor(0, diffuse / 2, diffuse / 2));
	blueLight.setDiffuseColor(ofColor(diffuse / 2, 0, diffuse / 2));
	
	float ambient = 255 - diffuse;
	redLight.setAmbientColor(ofColor(ambient / 2, ambient / 2, 0));
	greenLight.setAmbientColor(ofColor(0, ambient / 2, ambient / 2));
	blueLight.setAmbientColor(ofColor(ambient / 2, 0, ambient / 2));
	
	float lightY = ofGetHeight() / 2 + panel.getValueF("lightY");
	float lightZ = panel.getValueF("lightZ");
	float lightDistance = panel.getValueF("lightDistance");
	float lightRotation = panel.getValueF("lightRotation");
	redLight.setPosition(ofGetWidth() / 2 + cos(lightRotation + 0 * TWO_PI / 3) * lightDistance,
											 lightY + sin(lightRotation + 0 * TWO_PI / 3) * lightDistance,
											 lightZ);
	greenLight.setPosition(ofGetWidth() / 2 + cos(lightRotation + 1 * TWO_PI / 3) * lightDistance,
												 lightY + sin(lightRotation + 1 * TWO_PI / 3) * lightDistance,
												 lightZ);
	blueLight.setPosition(ofGetWidth() / 2 + cos(lightRotation + 2 * TWO_PI / 3) * lightDistance,
												lightY + sin(lightRotation + 2 * TWO_PI / 3) * lightDistance,
												lightZ);
}
Esempio n. 10
0
void testApp::draw() {
	ofBackground(0);
		
	easyCam.begin();
	int width = kinect.getWidth();
	int height = kinect.getHeight();
	ofScale(1, -1, -1); // orient the point cloud properly
	ofTranslate(0, 0, -1500); // rotate about z = 1500 mm

	float* distancePixels = kinect.getDistancePixels(); // distance in millimeters
	ofMesh cloud;
	cloud.setMode(OF_PRIMITIVE_POINTS);
	float minz = numeric_limits<float>::max();
	float minx = 0, miny = 0;
	for(int y = 0; y < height; y++) {
		for(int x = 0; x < width; x++) {
			int i = y * width + x;
			float z = distancePixels[i];
			if(z != 0) { // ignore empty depth pixels
				ofVec3f cur = ConvertProjectiveToRealWorld(x, y, z);
				cloud.addVertex(cur);
				if(z < minz) {
					minz = z;
					minx = x;
					miny = y;
				}
			}
		}
	}
	//cloud.draw();
	easyCam.end();
	
	ofSetColor(255);
	kinect.drawDepth(0, 0);
	ofSetColor(255, 0, 0);
	ofNoFill();
	int searchRadius = 128;
	//ofRect(minx - searchRadius / 2, miny - searchRadius / 2, searchRadius, searchRadius);
	//ofCircle(minx, miny, 10);
	
	ofVec3f sum;
	int count = 0;
	int maxSearchDistance = 100;
	for(int y = -searchRadius / 2; y < +searchRadius / 2; y++) {
		for(int x = -searchRadius / 2; x < +searchRadius / 2; x++) {
			int curx = x + minx;
			int cury = y + miny;
			if(curx > 0 && curx < width &&
				cury > 0 && cury < height) {
				int i = cury * width + curx;
				float curz = distancePixels[i];
				if(curz != 0 && abs(curz - minz) < maxSearchDistance) {
					sum.x += curx;
					sum.y += cury;
					sum.z += curz;
					count++;
				}
			}
		}
	}
	ofVec3f avg = sum / count;
    if(avg.z > 650 && avg.z <820 && avg.x > 309 && avg.x < 400) {
        ofFill();
        ofSetColor(255, 0, 0);
    }
    else {
        ofFill();
        ofSetColor(0, 255, 0);
    }
	ofCircle(avg.x, avg.y, 10);
	/*
	if(smoothedForepoint == ofVec3f()) {
		smoothedForepoint = avg;
	} else {
		smoothedForepoint.interpolate(avg, .1);
	}
	ofSetColor(255, 0, 255);
	ofCircle(smoothedForepoint.x, smoothedForepoint.y, 10);
	*/
	ofSetColor(255);
	ofDrawBitmapString(ofToString(minz) + "->" + ofToString(avg.x), 10, 20);
}