littlewing

人間とコンピューターとメディアの接点をデザインするために考えたこと

THETA Sの動画をopenframeworksで全天球再生(その1)

RICHO Theta Sで撮影した動画をopenFrameworksを利用して全天球再生できたのでメモ

その後うまくいった方法は↓の(その2)の記事を見てください


映像を最終的にはOpenCVで加工利用したいため、oFでスケッチ

  • リアルタイム映像ではなく、保存済み動画の再生
  • 元動画(1920x960 mp4形式)はそのままbin/data/に突っ込んで利用。
  • FBOでリアルタイムに解像度を落として利用。
  • oF 0.8.4 + Xcode 7.1 + Mac Book Pro

現状、再生用動画の解像度とFPSの関係は

  • 960x480 ...約10FPS
  • 480x240 ...約25-30FPS

再生はできるのですが、まだ改善の余地はある気がしています。

  • 元画像を小さくすればどうなるか?
  • リアルタイム処理の軽減
  • 処理対象を再生領域のみに
  • iOS 未対応。※現状ビルドはできるのですが、なぜか映らず。

THETAの静止画をoFで利用した以下の記事

おまけ:RICOH THETAのJPG画像を平面-球変換してOpenGLで表示する - cvl-robot's diary

を参考にして、動画用に修正を加えています。

採用しているアルゴリズム自体が動画には向いていないかもしれません。 手っ取り早く表示したい人には参考になるかなと思います。

ただ、openCVで加工したりの発展には持って行きやすそうなので、 また時間を見つけて改善をしたいです。

  • ofApp.h(抜粋)
    ofImage img;
    ofMesh mesh;
    ofEasyCam cam;
    ofVideoPlayer myPlayer;
    ofFbo fbo;
  • ofApp.cpp(抜粋)
#include "ofApp.h"
#define _USE_MATH_DEFINES
#include <math.h>


//--------------------------------------------------------------
void ofApp::setup(){
    ofSetVerticalSync(true);

    myPlayer.loadMovie("XXXXXX.mp4");//filename.mp4
    myPlayer.play();
    
    fbo.allocate(960, 480, GL_RGB); //縮小後の解像度


    fbo.begin();
    myPlayer.draw(0, 0, fbo.getWidth(), fbo.getHeight());
    fbo.end();
    
    ofPixels pix;
    fbo.readToPixels(pix);
    
    
    // we're going to load a ton of points into an ofMesh
    mesh.setMode(OF_PRIMITIVE_POINTS);
    
    
    ofEnableDepthTest();
    glEnable(GL_POINT_SMOOTH); // use circular points instead of square points
    glPointSize(5); // make the points bigger 解像度によって調整が必要

    

 
    float r = 10.0f; // radius
    cam.setAutoDistance(false);
    cam.setPosition(0,0,0);
    cam.lookAt(ofVec3f(r,0,0),ofVec3f(0,0,1));
    cam.setDistance(1.0);
}

//--------------------------------------------------------------
void ofApp::update(){
    
    
    myPlayer.update();

    if(myPlayer.isFrameNew()){
        
        fbo.begin();
        myPlayer.draw(0, 0, fbo.getWidth(), fbo.getHeight());
        fbo.end();
        
        ofPixels pix;
        
        fbo.readToPixels(pix);
        
        mesh.clear();
        mesh.clearVertices();
        mesh.clearColors();
        
        float r = 10.0f; // radius
        for(int y = 0; y < (int)fbo.getHeight(); y++){
            for(int x = 0; x < (int)fbo.getWidth(); x++){
                ofColor cur = pix.getColor(x, y);
                
                cur.a = 255;
                
                float theta = (float)y * M_PI / fbo.getHeight();
                float phi = -(float)x * 2.0f * M_PI / fbo.getWidth();
                float px = r * sin(theta) * cos(phi);
                float py = r * sin(theta) * sin(phi);
                float pz = r * cos(theta);
                

                mesh.addColor(cur);
                ofVec3f pos(px, py, pz);
                mesh.addVertex(pos);
            }
        }
        

    }



}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackgroundGradient(ofColor::gray, ofColor::black, OF_GRADIENT_CIRCULAR);
    
    // even points can overlap with each other, let's avoid that
    cam.begin();
    mesh.draw();
    cam.end();
    
    ofDisableDepthTest();
    fbo.draw(0, 0, 160, 80);
  //  ofDrawBitmapString(ofToString(ofGetFrameRate()) + "fps", 20, 20);
    ofSetWindowTitle(ofToString(ofGetFrameRate(), 0));
}

//--------------------------------------------------------------
以下略

(VRスコープ付録付)RICOH THETA パーフェクトガイド THETA S/m15両対応 (インプレスムック DCM MOOK)

(VRスコープ付録付)RICOH THETA パーフェクトガイド THETA S/m15両対応 (インプレスムック DCM MOOK)

  • 作者: 中井精也,丸田あつし,鍵井靖章,なぎら健壱,石井寛子,橋本塁,水野秀比古,柏倉陽介,加藤健志,荻窪圭,宇佐見健,染瀬直人,シンヤB,ゆきぴゅー
  • 出版社/メーカー: インプレス
  • 発売日: 2015/11/26
  • メディア: ムック
  • この商品を含むブログを見る

自分撮り ll(THETA棒)(シータ棒)

自分撮り ll(THETA棒)(シータ棒)