@riccardochi wrote:
Good morning,
I am relatively new with c++, and I am doing a project using ofxKinect to track motion change and use that change to release Ink using ofxInkSim.
Now, I am aware that the way the code is laid down is not the best, and that is because I am merging the ofxKinect example with ofxInkSim addon, which is not as tidy as I wished.
Basically I’m using the ofxContourFinder to detect the blobs, and I am releasing ink at the center of each blob.
When I run ofxInkSim on a separate project the colors work perfectly and there does not seem to be any graphics problem.
Here is how the inks looks when they aren’t conjoint with the ofxKinect code:
https://ibb.co/nBNCKTQWhen I run the code of the compound projects there seems to be some sort of graphics problem making the ink blending in a weird way. Also the colors seem to be at a very high contrast.
To combine the 2 projects I simply used ProjectGenerator and included all the ofx addons, and then I copied-pasted each section from the past code.
I really hope someone knows if the ofxKinect applies some graphics to the whole project, and how to limit those only to the blob detection.
I am close to finalizing the project, and getting stuck here is quite upsetting…
I’m attaching the ofApp.h code just in case someone wants to look at it.#include "ofApp.h" //-------------------------------------------------------------- void ofApp::setup() { ofSetLogLevel(OF_LOG_VERBOSE); // enable depth->video image calibration kinect.setRegistration(true); kinect.init(); //kinect.init(true); // shows infrared instead of RGB video image kinect.init(false, false); // disable video image (faster fps) kinect.open(); // opens first available kinect //kinect.open(1); // open a kinect by id, starting with 0 (sorted by serial # lexicographically)) //kinect.open("A00362A08602047A"); // open a kinect using it's unique serial # // print the intrinsic IR sensor values if(kinect.isConnected()) { ofLogNotice() << "sensor-emitter dist: " << kinect.getSensorEmitterDistance() << "cm"; ofLogNotice() << "sensor-camera dist: " << kinect.getSensorCameraDistance() << "cm"; ofLogNotice() << "zero plane pixel size: " << kinect.getZeroPlanePixelSize() << "mm"; ofLogNotice() << "zero plane dist: " << kinect.getZeroPlaneDistance() << "mm"; } #ifdef USE_TWO_KINECTS kinect2.init(); kinect2.open(); #endif colorImg.allocate(kinect.width, kinect.height); grayImage.allocate(kinect.width, kinect.height); grayThreshNear.allocate(kinect.width, kinect.height); grayThreshFar.allocate(kinect.width, kinect.height); nearThreshold = 230; farThreshold = 70; bThreshWithOpenCV = true; ofSetFrameRate(frameRate); // set frame rate (how often it detects change). default was 60. // zero the tilt on startup angle = 0; kinect.setCameraTiltAngle(angle); // start from the front bDrawPointCloud = false; // –--------------------------------------------------------- inkSim.setup(); gui.setup(inkSim.getUniformInfo()); fbo.allocate(ofGetWidth(), ofGetHeight()); ofDirectory dir; dir.open("imgs"); dir.listDir(); tests.resize(dir.size()); for (int i = 0; i < dir.size(); i++) { string path = dir.getFile(i).getAbsolutePath(); ofLoadImage(tests.at(i), path); } dir.close(); } //-------------------------------------------------------------- void ofApp::update() { ofBackground(0, 0, 0); kinect.update(); // there is a new frame and we are connected if(kinect.isFrameNew()) { // load grayscale depth image from the kinect source grayImage.setFromPixels(kinect.getDepthPixels()); // we do two thresholds - one for the far plane and one for the near plane // we then do a cvAnd to get the pixels which are a union of the two thresholds if(bThreshWithOpenCV) { grayThreshNear = grayImage; grayThreshFar = grayImage; grayThreshNear.threshold(nearThreshold, true); grayThreshFar.threshold(farThreshold); cvAnd(grayThreshNear.getCvImage(), grayThreshFar.getCvImage(), grayImage.getCvImage(), NULL); } else { // or we do it ourselves - show people how they can work with the pixels ofPixels & pix = grayImage.getPixels(); int numPixels = pix.size(); for(int i = 0; i < numPixels; i++) { if(pix[i] < nearThreshold && pix[i] > farThreshold) { pix[i] = 255; } else { pix[i] = 0; } } } // update the cv images grayImage.flagImageChanged(); // find contours which are between the size of 20 pixels and 1/3 the w*h pixels. // also, find holes is set to true so we will get interior contours as well.... contourFinder.findContours(grayImage, 10, (kinect.width*kinect.height)/2, 20, false); } #ifdef USE_TWO_KINECTS kinect2.update(); #endif //------------------------------- inkSim.update(); } //-------------------------------------------------------------- void ofApp::draw() { ofSetColor(255, 255, 255); if(bDrawPointCloud) { easyCam.begin(); drawPointCloud(); easyCam.end(); } else { // draw from the live kinect //kinect.drawDepth(370, 10, 400, 300); // depth map //kinect.draw(420, 10, 400, 300); // show kinect image grayImage.draw(420, 10, 400, 300); // default was (10, 320, 400, 300) contourFinder.draw(420, 10, 400, 300); // We save this round's blobs here and then copy it to the previousBlobs std::vector<std::vector<int>> tempBlobs; for( int i=0; i<(int)contourFinder.blobs.size(); i++ ) { ofxCvBlob blob = contourFinder.blobs[i]; // Calc centre points if you don't wanna use centroids // int x = blob.boundingRect.x + blob.boundingRect.width/2; // int y = blob.boundingRect.y + blob.boundingRect.height/2; int x = blob.centroid.x; int y = blob.centroid.y; int colorIndex = getBlobColor(x, y); std::vector<int> v = {x, y, colorIndex}; tempBlobs.push_back(v); //for cycle if (counter++ == 60) { counter = 0; //drawInk = true; //} else { drawInk = false; }; // Start buffer fbo.begin(); ofClear(0); // Ciclo for starts for (int i = 0; i < 1; i++) // number of ink-blobs per click { float rad = ofRandom(3, 7); //ofRandom(minRadius, maxRadius); float depth = 255; //opacità //ofMap(rad, 2, 10, 255, 200, true); // Positioning the blob int blobX = x +- ofRandom(0, 30); // ofRandon(minimumDistanceFromClick, maxDistanceFromClick); int blobY = y +- ofRandom(0, 30); // Filling the blob ofPushStyle(); ofSetHexColor(colors[colorIndex]); // Drawing the blob ofDrawCircle(blobX, blobY, rad); ofPopStyle(); } fbo.end(); // Draw buffer inkSim.begin(); fbo.draw(0, 0); inkSim.end(); } } // Now copy tempBlobs to previousBlobs previousBlobs.clear(); for( int i=0; i<(int)tempBlobs.size(); i++ ) { previousBlobs.push_back(tempBlobs[i]); } inkSim.draw(); } // draw instructions ofSetColor(255, 255, 255); stringstream reportStream; if(kinect.hasAccelControl()) { reportStream << "accel is: " << ofToString(kinect.getMksAccel().x, 2) << " / " << ofToString(kinect.getMksAccel().y, 2) << " / " << ofToString(kinect.getMksAccel().z, 2) << endl; } else { reportStream << "Note: this is a newer Xbox Kinect or Kinect For Windows device," << endl << "motor / led / accel controls are not currently supported" << endl << endl; } reportStream << "press p to switch between images and point cloud, rotate the point cloud with the mouse" << endl << "using opencv threshold = " << bThreshWithOpenCV <<" (press spacebar)" << endl << "set near threshold " << nearThreshold << " (press: + -)" << endl << "set far threshold " << farThreshold << " (press: < >) num blobs found " << contourFinder.nBlobs << ", fps: " << ofGetFrameRate() << endl << "press c to close the connection and o to open it again, connection is: " << kinect.isConnected() << endl; if(kinect.hasCamTiltControl()) { reportStream << "press UP and DOWN to change the tilt angle: " << angle << " degrees" << endl << "press 1-5 & 0 to change the led mode" << endl; } ofDrawBitmapString(reportStream.str(), 20, 652); } void ofApp::drawPointCloud() { int w = 640; int h = 480; ofMesh mesh; mesh.setMode(OF_PRIMITIVE_POINTS); int step = 2; for(int y = 0; y < h; y += step) { for(int x = 0; x < w; x += step) { if(kinect.getDistanceAt(x, y) > 0) { mesh.addColor(kinect.getColorAt(x,y)); mesh.addVertex(kinect.getWorldCoordinateAt(x, y)); } } } glPointSize(3); ofPushMatrix(); // the projected points are 'upside down' and 'backwards' ofScale(1, -1, -1); ofTranslate(0, 0, -1000); // center the points a bit ofEnableDepthTest(); mesh.drawVertices(); ofDisableDepthTest(); ofPopMatrix(); } //-------------------------------------------------------------- void ofApp::exit() { kinect.setCameraTiltAngle(0); // zero the tilt on exit kinect.close(); #ifdef USE_TWO_KINECTS kinect2.close(); #endif } //-------------------------------------------------------------- void ofApp::keyPressed (int key) { switch (key) { case ' ': bThreshWithOpenCV = !bThreshWithOpenCV; break; case'p': bDrawPointCloud = !bDrawPointCloud; break; case '>': case '.': farThreshold ++; if (farThreshold > 255) farThreshold = 255; break; case '<': case ',': farThreshold --; if (farThreshold < 0) farThreshold = 0; break; case '+': case '=': nearThreshold ++; if (nearThreshold > 255) nearThreshold = 255; break; case '-': nearThreshold --; if (nearThreshold < 0) nearThreshold = 0; break; case 'w': kinect.enableDepthNearValueWhite(!kinect.isDepthNearValueWhite()); break; case 'o': kinect.setCameraTiltAngle(angle); // go back to prev tilt kinect.open(); break; case '0': kinect.setCameraTiltAngle(0); // zero the tilt kinect.close(); break; case '1': kinect.setLed(ofxKinect::LED_GREEN); break; case '2': kinect.setLed(ofxKinect::LED_YELLOW); break; case '3': kinect.setLed(ofxKinect::LED_RED); break; case '4': kinect.setLed(ofxKinect::LED_BLINK_GREEN); break; case '5': kinect.setLed(ofxKinect::LED_BLINK_YELLOW_RED); break; case '6': kinect.setLed(ofxKinect::LED_OFF); break; case OF_KEY_UP: angle++; if(angle>30) angle=30; kinect.setCameraTiltAngle(angle); break; case OF_KEY_DOWN: angle--; if(angle<-30) angle=-30; kinect.setCameraTiltAngle(angle); break; case 'm': gui.toggleVisible(); break; case 'r': gui.resetToDefault(); break; case 'c': inkSim.clear(); break; case 'f': int angRange = ofRandom(100, 200); int angMin = ofRandom(360); fbo.begin(); ofClear(0); for (int i = 0; i < 500; i++) { int ang = ofRandom(angMin, angRange); if (ang > 360) ang -= 360; float rad = ofRandom(2, 10); float depth = 255;//ofMap(rad, 2, 10, 255, 200, true); ofColor c = getInkColor(ang, 255, depth); ofPushStyle(); ofSetColor(c); ofDrawCircle(ofRandomWidth(), ofRandomHeight(), rad); ofPopStyle(); } fbo.end(); inkSim.begin(); fbo.draw(0, 0); inkSim.end(); break; } } int ofApp::getBlobColor(int x, int y) { for (int i = 0; i < (int)previousBlobs.size(); i++) { int px = previousBlobs[i][0]; int py = previousBlobs[i][1]; if ( sqrt( (x - px)*(x - px) + (y - py)*(y - py) ) < identityDistance ) { return previousBlobs[i][2]; } } return ofRandom(0, sizeof(colors) ); } //-------------------------------------------------------------- void ofApp::mouseDragged(int x, int y, int button) { } //-------------------------------------------------------------- void ofApp::mousePressed(int x, int y, int button) { } //-------------------------------------------------------------- void ofApp::mouseReleased(int x, int y, int button) { } //-------------------------------------------------------------- void ofApp::mouseEntered(int x, int y){ } //-------------------------------------------------------------- void ofApp::mouseExited(int x, int y){ } //-------------------------------------------------------------- void ofApp::windowResized(int w, int h) { }
Posts: 1
Participants: 1