OpenFrameworksを使った立体物のスキャニングと解析

f:id:dozensdozy:20180623013811p:plainf:id:dozensdozy:20180623013814p:plainf:id:dozensdozy:20180623013818p:plain<目次>

これまで進んだこと

 1. 3Dスキャンデータ(ポリゴン)とスキャナーの軌跡を描画する。

 2. スキャナーの視点とPC画面の視点を一致させる。

 3. 各撮影箇所において、スキャナーが捉えているポリゴンデータを強調表示させる。

これから進めていくこと

 4. 撮影の精度を評価する。

 5. 評価関数を探し、立体物スキャニングの機械学習をする。

<1. 軌跡の描画>

スキャンデータは毎フレーム4x4の行列として保存される。

そこから、回転を表す3x3行列と、座標の3次元ベクトルを取り出し、スキャナーの軌跡を描画した。

<2. スキャナーとPCの視点の同一化>

つまり、

cam.SetPosition(スキャナーの視点方向の3次元ベクトル);

また、各スキャンデータは連番となっているので、キーボード操作で前後の視点に移動できるようにした。

「何番目のデータからの視点か」は、変数 viewpointer を作成して識別させた。

<3. 強調表示>

カメラが各フレームで捉えているメッシュのみ、赤色で強調表示させた。

変数 viewmesh は、強調表示をするか否か、つまり ON/OFF スイッチの機能を果たす。

  • スイッチとして、例えばキーボードの特定のキーを割り当てる。

  • ON のときは、該当メッシュが赤くなる。

  • ON の状態で、視点を前後に移動させると、強調されるメッシュも前後に変わる。

f:id:dozensdozy:20180623013811p:plainf:id:dozensdozy:20180623013814p:plainf:id:dozensdozy:20180623013818p:plain
視点の強調表示:メッシュが重なっている部分が隠れてしまっている

【描画に関する部分】

void ofApp::draw(){
    ofSetBackgroundColor(ofColor::black);
    
    cam.begin();
    ofEnableLighting();
    for (int i = 0; i < num; i++){
        ofPushMatrix(); 
        light.enable();
        ofMultMatrix(mat[i]);
        ofMaterial material;
        if(viewpointer == i and viewmesh == -1){
            material.setDiffuseColor(ofColor::red); //
        }else{
            material.setDiffuseColor(ofColor::white);
        }
        
        material.begin();
        meshes[i][0].draw();
        material.end();
        
        light.disable();
        ofPopMatrix();
        
    }

【キーボード操作の部分】

OpenFrameworksではとても簡単にキーボード操作が書けてしまう。

void ofApp::keyPressed(int key){
    if(key == OF_KEY_UP){ //上矢印キーが押されたら
        if(viewpointer < num){
            viewpointer++; //カメラの位置++
            cam.setPosition(mat[viewpointer].getTranslation());
            cam.setOrientation(mat[viewpointer].getRotate());
        }
    }
    if(key == OF_KEY_DOWN){ //下矢印キーが押されたら
        if(viewpointer > 0){
            viewpointer -- ; //カメラの位置++
            cam.setPosition(mat[viewpointer].getTranslation());
            cam.setOrientation(mat[viewpointer].getRotate());
        }
    }
    if(key == 'p'){
        viewmesh = viewmesh*(-1); // p キーを押すことでON/OFFを切り替えられる
    }
    
}