読者です 読者をやめる 読者になる 読者になる

Twenties Dirtbag

イギリスの大学院で脳の勉強をしてきた25歳、今はボルダリングジムを経営中。基本的にどうでもいいはなしです。

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が手に入らなかったので、計算量が多いためのコマ落ちかな。と自分の中で勝手に結論を出してしまい、別の方法でやることにしました。

f:id:flowertyyyy:20170220183604p:plain

 

それは、単純に分析した輪郭線の位置情報を

 

    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の円をおいているという状態です。これだと実行できました。(おそらくポリゴンをつくるより正確性は下がりますが。)
f:id:flowertyyyy:20170220185059p:plain


参考:
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;
            
    }

}