2011-01-23 21 views
5

Necesito implementar el chroma keying (eliminación de un fondo de color sólido) en una aplicación de openFrameworks.chroma key with openframeworks/opengl

Reproduciré muchos (10 o más) videos simultáneamente (en el mismo fotograma), y los dibujaré en la pantalla junto con fondos alternativos. Puedo lograr un efecto chroma-key iterando a través de los píxeles de cada fotograma y estableciendo valores alfa para cada uno en función de un umbral verde, pero con tantos videos a la vez, este golpeteo de píxeles se vuelve prohibitivo.

¿Hay un modo de mezcla OpenGL fácil o una operación de enmascaramiento que puede evitar dibujar todos los píxeles de un determinado valor de color? ¿O existe otra biblioteca C++ compatible con openFrameworks o openFrameworks que pueda hacer esto de manera eficiente?

Alternativamente, ¿existe una buena forma (eficiente en el uso del espacio) de almacenar canales alfa en archivos de video compatibles con Quicktime? Vamos a almacenar terabytes de video (semanas de grabación continua), por lo que es importante que usemos formatos de espacio eficiente.

Una nota: el color de la clave cromática en los archivos fuente será "perfecto": se agrega digitalmente. Entonces, si hay algún tipo de umbralización o truco de lógica bit a bit para hacer esto, eso podría funcionar también.


EDITAR: Esto es lo que funcionó, siguiendo la sugerencia de VJO para un sombreado de píxeles. Utilizamos glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), y la siguiente sombreado de píxeles (para el color magenta como sustituido):

"datos/shaders/chromakey.frag":

#extension GL_ARB_texture_rectangle : enable 

uniform sampler2DRect src_tex_unit0; 
vec4 color; 

void main(void) 
{ 
     vec2 st = gl_TexCoord[0].st; 
     vec4 sample = texture2DRect(src_tex_unit0, st); 
     gl_FragColor = sample; 
     if((sample.r > 0.5) && (sample.g < 0.5) && (sample.b > 0.5)) { 
       gl_FragColor.a = 0.0; 
     } 
} 

"datos/shaders/chromakey.vert":

void main() 
{ 
    gl_Position = ftransform(); 
    gl_TexCoord[0] = gl_MultiTexCoord[0]; 
} 

El C++ clases de proxy para los shaders - shaderChromakey.h:

#include "ofMain.h" 
#include "ofxShader.h" 
#include "ofxFBOTexture.h" 

class shaderChromakey{ 

    public: 
     void setup(int fboW, int fboH); 

     void beginRender(); 
     void endRender(); 

     void draw(int x, int y, int width, int height); 

     ofxShader shader; 

     ofxFBOTexture fbo; 

}; 

s haderChromakey.cpp:

#include "shaderChromakey.h" 

//-------------------------------------------------------------- 
void shaderChromakey::setup(int fboW, int fboH){ 

    ofBackground(255,255,255); 
    ofSetVerticalSync(true); 

    fbo.allocate(fboW, fboH, true); 

    shader.loadShader("shaders/chromakey"); 
} 

//-------------------------------------------------------------- 
void shaderChromakey::beginRender(){ 
    fbo.swapIn(); 
} 

//-------------------------------------------------------------- 
void shaderChromakey::endRender(){ 
    fbo.swapOut(); 
} 

//-------------------------------------------------------------- 
void shaderChromakey::draw(int x, int y, int width, int height){ 

    shader.setShaderActive(true); 
    fbo.draw(x, y, width, height); 
    shader.setShaderActive(false); 
} 

crear una instancia del shader, en el proyecto:

shaderChromakey chromakey; 
chromakey.setup(HORIZONTAL, VERTICAL) 

En el bucle de tracción, para que el shader:

chromakey.beginRender(); 
    // draw chomakeyed frame here 
chromakey.endRender(); 

Respuesta

2

Usted podría utilizar glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA) y luego cuando habilitas la mezcla, puedes usar un sombreador de píxeles para hacer lo que quieras si el píxel es de un color específico (establece alfa en 0).