Frage

Ich muss die Chroma -Keying (Entfernen eines festen Farbhintergrunds) in einer OpenFrameWorks -Anwendung implementieren.

Ich werde viele (10 oder mehr) Videos gleichzeitig (im selben Rahmen) spielen und sie zusammen mit alternativen Hintergründen auf den Bildschirm ziehen. Ich kann einen Chroma-Key-ähnlichen Effekt erzielen, indem ich die Pixel jedes Frame durch Iterien durch Iterien durch Iterien basiert, basierend auf einem grünen Schwellenwert, aber mit so vielen Videos gleichzeitig wird diese Pixel-Banging unerschwinglich.

Gibt es einen einfachen OpenGL -Mischmodus oder Maskierungsvorgang, mit dem alle Pixel eines bestimmten Farbwerts das Zeichnen eines bestimmten Farbwerts vermeiden können? Oder gibt es eine weitere OpenFrameworks oder OpenFrameWorks-kompatible C ++-Bibliothek, die dies effizient bewirkt?

Gibt es alternativ eine gute (platzeffiziente) Möglichkeit, Alpha-Kanal in QuickTime-kompatiblen Videodateien zu speichern? Wir werden Terabyte von Videos (Wochen der kontinuierlichen Aufnahme) aufbewahren. Daher ist es wichtig, dass wir platzeffiziente Formate verwenden.

Ein Hinweis: Die Chroma-Key-Farbe in den Quelldateien ist "perfekt"-sie wird digital hinzugefügt. Wenn es also eine Art Schwellenwert oder bitweise logische Trick gibt, könnte dies auch funktionieren.


BEARBEITEN: Hier ist das, was funktioniert hat und VJOs Vorschlag für einen Pixel -Shader folgt. Wir verwendeten glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), und der folgende Pixel -Shader (für Magenta als ersetzte Farbe):

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

"Daten/Shaders/Chromakey.vert":

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

Die C ++ - Proxy -Klassen für die 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;

};

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

So instanziieren Sie den Shader im Projekt:

shaderChromakey chromakey;
chromakey.setup(HORIZONTAL, VERTICAL)

In der Zeichnungsschleife, um den Shader zu aktivieren:

chromakey.beginRender();
    // draw chomakeyed frame here
chromakey.endRender();
War es hilfreich?

Lösung

Du könntest benutzen glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_DST_ALPHA) Und wenn Sie das Mischen aktivieren, können Sie einen Pixel -Shader verwenden, um das zu tun, was Sie wollen, wenn das Pixel eine bestimmte Farbe hat (Alpha auf 0 einstellen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top