2016-08-15 15 views
5

개방형 프레임 워크를 사용하여 듀얼 어안 비디오 (ricoh theta S 카메라에서 수신)를 (iOS 애플리케이션 용) 등변 각형 포맷으로 변환했습니다.듀얼 어안 비디오를 정사각형으로 변환

듀얼 어안 이미지 샘플 : enter image description here

투영법 이미지 샘플 :

equirectangular.frag

// based on ThetaShaderPack_20150926 (http://stereoarts.jp/) written by Nora. 
#ifdef GL_ES 
// define default precision for float, vec, mat. 
precision highp float; 
#endif 

#define PI 3.14159265358979 
#define _THETA_S_Y_SCALE (640.0/720.0) 

uniform sampler2D mainTex; 
uniform float radius; 
uniform vec4 uvOffset; 

varying vec2 texCoordVarying; 

void main (void) { 
    vec2 revUV = texCoordVarying.st; 
    if (texCoordVarying.x <= 0.5) { 
     revUV.x = revUV.x * 2.0; 
    } else { 
     revUV.x = (revUV.x - 0.5) * 2.0; 
    } 

    revUV *= PI; 

    vec3 p = vec3(cos(revUV.x), cos(revUV.y), sin(revUV.x)); 
    p.xz *= sqrt(1.0 - p.y * p.y); 

    float r = 1.0 - asin(p.z)/(PI/2.0); 
    vec2 st = vec2(p.y, p.x); 

    st *= r/sqrt(1.0 - p.z * p.z); 
    st *= radius; 
    st += 0.5; 

    if (texCoordVarying.x <= 0.5) { 
     st.x *= 0.5; 
     st.x += 0.5; 
     st.y = 1.0 - st.y; 
     st.xy += uvOffset.wz; 
    } else { 
     st.x = 1.0 - st.x; 
     st.x *= 0.5; 
     st.xy += uvOffset.yx; 
    } 

    st.y = st.y * _THETA_S_Y_SCALE; 

    gl_FragColor = texture2D(mainTex, st); 
} 

equirectanguler.vert

: enter image description here

내가 쉐이더 이하 사용 아래 코드

uniform mat4 projectionMatrix; 
uniform mat4 modelViewMatrix; 
uniform mat4 textureMatrix; 
uniform mat4 modelViewProjectionMatrix; 

attribute vec4 position; 
attribute vec4 color; 
attribute vec3 normal; 
attribute vec2 texcoord; 

varying vec2 texCoordVarying; 

void main() { 
    texCoordVarying = texcoord; 
    gl_Position = modelViewProjectionMatrix * position; 
} 

: 여기 main.mm

#include "ofApp.h" 

int main() { 

    // here are the most commonly used iOS window settings. 
    //------------------------------------------------------ 
    ofiOSWindowSettings settings; 
    settings.enableRetina = false; // enables retina resolution if the device supports it. 
    settings.enableDepth = false; // enables depth buffer for 3d drawing. 
    settings.enableAntiAliasing = false; // enables anti-aliasing which smooths out graphics on the screen. 
    settings.numOfAntiAliasingSamples = 0; // number of samples used for anti-aliasing. 
    settings.enableHardwareOrientation = false; // enables native view orientation. 
    settings.enableHardwareOrientationAnimation = false; // enables native orientation changes to be animated. 
    settings.glesVersion = OFXIOS_RENDERER_ES2; // type of renderer to use, ES1, ES2, ES3 
    settings.windowMode = OF_FULLSCREEN; 
    ofCreateWindow(settings); 

    return ofRunApp(new ofApp); 
} 

``` 

`offApp.mm` 

``` 
#include "ofApp.h" 

//-------------------------------------------------------------- 
void ofApp::setup(){  
    ofDisableArbTex(); 

    devices = theta.listDevices(); 
    bool isDeviceConnected = false; 
    for(int i = 0; i < devices.size(); i++){ 
     if(devices[i].deviceName == "RICOH THETA S"){ 
      theta.setDeviceID(devices[i].id); 
      isDeviceConnected = true; 
     } 
    } 
    if(!isDeviceConnected){ 
     ofLog(OF_LOG_ERROR, "RICOH THETA S is not found."); 
    } 
    theta.initGrabber(360, 568); 

    shader.load("shaders/equirectanguler"); 

    fbo.allocate(320, 568); 

    sphere = ofSpherePrimitive(568, 64).getMesh(); 
    for(int i=0;i<sphere.getNumTexCoords();i++){ 
     sphere.setTexCoord(i, ofVec2f(1.0) - sphere.getTexCoord(i)); 
    } 
    for(int i=0;i<sphere.getNumNormals();i++){ 
     sphere.setNormal(i, sphere.getNormal(i) * ofVec3f(-1)); 
    } 

    offset.set("uvOffset", ofVec4f(0,0.0,0,0.0), ofVec4f(-0.1), ofVec4f(0.1)); 
    radius.set("radius", 0.445, 0.0, 1.0); 
    showSphere.set("showSphere", false); 
    thetaParams.add(offset); 
    thetaParams.add(radius); 
    gui.setup(thetaParams); 
    gui.add(showSphere); 

    cam.setAutoDistance(false); 
    cam.setDistance(0); 
} 

//-------------------------------------------------------------- 
void ofApp::update(){ 
    theta.update(); 
} 

//-------------------------------------------------------------- 
void ofApp::draw(){ 
    if(theta.isFrameNew()){ 

     fbo.begin(); 
     ofClear(0); 
     shader.begin(); 
     shader.setUniformTexture("mainTex", theta.getTexture(), 0); 
     shader.setUniforms(thetaParams); 
     theta.draw(0, 0, 320, 568); 
     shader.end(); 
     fbo.end(); 

    } 

    if(!showSphere){ 

     fbo.draw(0, 0, 320, 568); 

    }else{ 

     ofEnableDepthTest(); 
     cam.begin(); 
     fbo.getTexture().bind(); 
     sphere.draw(); 
     fbo.getTexture().unbind(); 
     cam.end(); 

    } 

    ofDisableDepthTest(); 
    gui.draw(); 
} 

//-------------------------------------------------------------- 
void ofApp::exit(){ 

} 

//-------------------------------------------------------------- 
void ofApp::touchDown(ofTouchEventArgs & touch){ 

} 

//-------------------------------------------------------------- 
void ofApp::touchMoved(ofTouchEventArgs & touch){ 

} 

//-------------------------------------------------------------- 
void ofApp::touchUp(ofTouchEventArgs & touch){ 

} 

//-------------------------------------------------------------- 
void ofApp::touchDoubleTap(ofTouchEventArgs & touch){ 

} 

//-------------------------------------------------------------- 
void ofApp::touchCancelled(ofTouchEventArgs & touch){ 

} 

//-------------------------------------------------------------- 
void ofApp::lostFocus(){ 

} 

//-------------------------------------------------------------- 
void ofApp::gotFocus(){ 

} 

//-------------------------------------------------------------- 
void ofApp::gotMemoryWarning(){ 

} 

//-------------------------------------------------------------- 
void ofApp::deviceOrientationChanged(int newOrientation){ 

} 

offApp.h

#pragma once 

#include "ofxiOS.h" 
#include "ofxGui.h" 

class ofApp : public ofxiOSApp { 

    public: 
     void setup(); 
     void update(); 
     void draw(); 
     void exit(); 

     void touchDown(ofTouchEventArgs & touch); 
     void touchMoved(ofTouchEventArgs & touch); 
     void touchUp(ofTouchEventArgs & touch); 
     void touchDoubleTap(ofTouchEventArgs & touch); 
     void touchCancelled(ofTouchEventArgs & touch); 

     void lostFocus(); 
     void gotFocus(); 
     void gotMemoryWarning(); 
     void deviceOrientationChanged(int newOrientation); 

    ofVideoGrabber theta; 
    vector<ofVideoDevice> devices; 
    ofShader shader; 
    ofFbo fbo; 
    ofEasyCam cam; 
    ofVboMesh sphere; 

    ofParameter<ofVec4f> offset; 
    ofParameter<float> radius; 
    ofParameter<bool> showSphere; 
    ofParameterGroup thetaParams; 
    ofxPanel gui; 
}; 

그리고는 결과입니다 iphone5s에 가 enter image description here

pls는 내가 마일 걸 지적 ssed.

답변

1

저는 OpenFrameworks에서 GPUImage으로 전환하고 iOS 장치에서 듀얼 어안 비디오를 등변 각 포맷으로 변환 할 수 있습니다.

동일한 셰이더 프로그램에 사용되었습니다. check my repository

+0

GPUImage 프레임 워크 내에서 하나의 어안 이미지를 풀 때 사용한 함수를 가리켜 주시겠습니까? – mm24

+0

필자는 입력으로 mp4 이중 어안 동영상을 사용했습니다. 출력물은 사각형이 아닌 무비 파일입니다. 그리고 그렇게하기 위해 맞춤 필터를 작성했습니다. 저는 GPUImage를 사용하여 동영상에서 텍스처를 얻고 위의 사용자 정의 셰이더를 사용하여이를 투 등법으로 변환합니다. (셰이더 프로그램 참조 https://github.com/yasuhirohoshino/thetaRealtimeEquirectangular) –