OF:雪のなかで人影が遊ばせたらエラーが出た話
openFrameworksを勉強する際に、とても参考にしているのがこここじ研(openFrameworks)なんですが、この、「雪のなかで人影が遊ぶ」を実行していこうとした際に、エラーが出たので他のやり方でやってみた結果を書いていきます。
上のリンク先の「シルエットと雪との相互作用を実現」というところの、シルエットをポリゴンに変換する際のこちら↓
// make a polygon shadows[j].get()->clear();
shadows[j].get()->addVertexes(shadowLines[j]);
shadows[j].get()->triangulatePoly(30);
shadows[j].get()->setPhysics(1.0, 0.5, 0.1);
shadows[j].get()->create(world2d.getWorld());
のところで、「signal SIGABRT」というエラーが出てきてビルドはできたのですが、Workしない状態となってました。そのエラーの原因をいろいろとGoogle itしたのですが、なかなかこれと言った解決のためのKeyが手に入らなかったので、計算量が多いためのコマ落ちかな。と自分の中で勝手に結論を出してしまい、別の方法でやることにしました。
それは、単純に分析した輪郭線の位置情報を
for(int i = 0; i < finder.nBlobs; i++){ for(int j = 0; j < finder.blobs[i].pts.size(); j++){ ofPoint pos = finder.blobs[i].pts[j]; ofPtr<ofxBox2dCircle> circle = ofPtr<ofxBox2dCircle>(new ofxBox2dCircle); circle.get() -> setup(world2d.getWorld(), pos.x, pos.y, 3); ContourCircles.push_back(circle); } }
これで取得して、そこに半径3の円をおいているという状態です。これだと実行できました。(おそらくポリゴンをつくるより正確性は下がりますが。)
参考:
Amazon CAPTCHA
#include "ofApp.h" //-------------------------------------------------------------- void ofApp::setup(){ // window ofBackground(80, 80, 120); ofSetWindowShape(640, 480); // box2d world2d.init(); world2d.setFPS(60.0); world2d.setGravity(0, 2); // snow snow.load("snow.png"); snow.setAnchorPoint(0.5, 0.5); // ground world2d.createGround(0, 480, 640, 480); // setup OpneNI kinect.setup(); kinect.setRegister(true); kinect.setMirror(true); kinect.addDepthGenerator(); kinect.start(); minDist = 500; maxDist = 1500; shadowImage.allocate(640, 480); invertImage.allocate(640, 480); // shadow of a person for (int i = 0; i < MAX_BLOBS; i++){ shadows[i] = ofPtr<ofxBox2dPolygon>(new ofxBox2dPolygon); } } void ofApp::makeSnow(float x, float y, float size){ // create a new circle ofPtr<ofxBox2dCircle> circle = ofPtr<ofxBox2dCircle>(new ofxBox2dCircle); // set attributes to this circle circle.get() -> setPhysics(1.0, 0.5, 0.1); circle.get() -> setup(world2d.getWorld(), x, y, size); circle.get() -> setVelocity(ofRandom(-1.0, 1.0), ofRandom(-1.0, 1.0)); // add this circle to "circles" vector circles.push_back(circle); } bool objectkiller(ofPtr<ofxBox2dBaseShape> shape) { float yPos = shape.get() -> getPosition().y; return (yPos >= 500); } //-------------------------------------------------------------- void ofApp::update(){ // shadow kinect.update(); unsigned short *depthData = kinect.getDepthRawPixels().getData(); unsigned char *shadowData = shadowImage.getPixels().getData(); for (int k = 0 ; k < 640 * 480; k++) { shadowData[k] = (minDist < depthData[k] && depthData[k] < maxDist)? 255:0; } shadowImage.flagImageChanged(); invertImage = shadowImage; invertImage.invert(); // find contours shadowImage.threshold(threshold); for(int i = 0; i < ContourCircles.size(); i++){ ContourCircles[i]->destroy(); } ContourCircles.clear(); finder.findContours(shadowImage, 1000, 640*480/4, 4, false); for(int i = 0; i < finder.nBlobs; i++){ for(int j = 0; j < finder.blobs[i].pts.size(); j++){ ofPoint pos = finder.blobs[i].pts[j]; ofPtr<ofxBox2dCircle> circle = ofPtr<ofxBox2dCircle>(new ofxBox2dCircle); circle.get() -> setup(world2d.getWorld(), pos.x, pos.y, 3); ContourCircles.push_back(circle); } } /* numShadows = finder.nBlobs; for (int j = 0; j < MAX_BLOBS; j++) { shadowLines[j].clear(); shadows[j].get()->clear(); if (j < numShadows) { // make a contour for (int k = 0; k < finder.blobs[j].pts.size(); k+=60){ shadowLines[j].addVertex(finder.blobs[j].pts[k]); } shadowLines[j].close(); shadowLines[j].simplify(); // make a polygon shadows[j].get()->clear(); shadows[j].get()->addVertexes(shadowLines[j]); shadows[j].get()->triangulatePoly(5); shadows[j].get()->setPhysics(1.0, 0.5, 0.1); shadows[j].get()->create(world2d.getWorld()); } } */ // make a new snow if (ofRandom(0, 100) < 40) { makeSnow(ofRandom(-40, 680), -40, ofRandom(5, 10)); } // box2d ofRemove(circles, objectkiller); //update the world world2d.update(); } //-------------------------------------------------------------- void ofApp::draw(){ shadowImage.draw(640, 0, 640, 480); // draw shadow ofSetColor(80, 80, 120); //ofSetColor(255, 255, 255); invertImage.draw(0, 0, 640, 480); // draw contours /* ofSetLineWidth(3); ofSetColor(140, 140, 200); for (int j = 0; j < numShadows; j++){ shadowLines[j].draw(); } */ //shadowImage.draw(0, 0, 640, 480); // draw contours finder.draw(0, 0, 640, 480); // draw the ContourCircles ofSetColor(255, 255, 255); for(int i = 0; i < ContourCircles.size(); i++){ ContourCircles[i]->draw(); } // draw each circle ofSetColor(255, 255, 255); for (int i = 0; i < circles.size(); i++) { ofPoint pos = circles[i].get() -> getPosition(); float size = circles[i].get() -> getRadius()*10.0; snow.draw(pos, size, size); } // draw the number of circles and fps ofSetColor(255, 100, 100); char buf[100]; sprintf(buf, "%ld circles", circles.size()); ofDrawBitmapString(buf, 20, 20); sprintf(buf, "%5.2f fps", ofGetFrameRate()); ofDrawBitmapString(buf, 20, 40); sprintf(buf, "%1d fps", threshold); ofDrawBitmapString(buf, 20, 60); } //-------------------------------------------------------------- void ofApp::keyPressed(int key){ switch(key){ case '+': threshold ++; if(threshold > 255) threshold = 255; break; case '-': threshold --; if(threshold < 0) threshold = 0; break; } }