Pregunta

Necesito implementar la tecla de croma (eliminación de un fondo de color sólido) en una aplicación OpenFrameWorks.

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

¿Existe un modo de combinación o operación de enmascaramiento fácil de OpenGL que pueda evitar dibujar todos los píxeles de un cierto valor de color? ¿O hay otra biblioteca C ++ compatible con OpenFrameWorks o OpenFrameWorks que puede hacer esto de manera eficiente?

Alternativamente, ¿hay una buena forma (de eficiencia espacial) de almacenar el alfa-canal 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 eficiencia espacial.

Una nota: el color de tecla de croma en los archivos de origen será "perfecto", se agrega digitalmente. Entonces, si hay algún tipo de umbral o truco de lógico bit a bit para hacer esto, eso también podría funcionar.


EDITAR: Esto es lo que funcionó, siguiendo la sugerencia de Vjo para un sombreador de píxeles. Nosotros usamos glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), y el siguiente sombreador de píxeles (para magenta como el color reemplazado):

"Data/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;
        }
}

"Data/Shaders/Chromakey.vert":

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

Las clases de proxy C ++ para los sombreadores - 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;

};

shaderChromakey.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);
}

Para instanciar el sombreador, en el proyecto:

shaderChromakey chromakey;
chromakey.setup(HORIZONTAL, VERTICAL)

En el bucle de dibujo, para habilitar el sombreador:

chromakey.beginRender();
    // draw chomakeyed frame here
chromakey.endRender();
¿Fue útil?

Solución

Podrías usar glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA) Y luego, cuando habilita la mezcla, puede usar un sombreador de píxeles para hacer lo que quiera si el píxel es de color específico (establezca alfa en 0).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top