openFrameworks アプリケーションでクロマ キーイング (無地の背景の削除) を実装する必要があります。
多くの (10 以上の) ビデオを (同じフレームで) 同時に再生し、別の背景と共にそれらを画面に描画します。各フレームのピクセルを反復処理し、緑のしきい値に基づいて各ピクセルのアルファ値を設定することで、クロマキーのような効果を実現できますが、一度に非常に多くのビデオを使用すると、このピクセル バンギングは禁止されます。
特定の色値のすべてのピクセルを描画することを回避できる、簡単な OpenGL ブレンド モードまたはマスキング操作はありますか? または、これを効率的に実行できる別の openFrameworks または openFrameworks 互換の C++ ライブラリはありますか?
または、アルファ チャネルを QuickTime 互換のビデオ ファイルに格納する (スペース効率の良い) 方法はありますか? 数テラバイトのビデオ (数週間の連続録画) を保存することになるため、スペース効率の高い形式を使用することが重要です。
1 つの注意: ソース ファイルのクロマキー カラーは「完全」であり、デジタルで追加されます。したがって、これを行うための何らかのしきい値処理またはビットごとのロジックのトリックがあれば、それも機能する可能性があります。
編集: ピクセル シェーダーに対する VJo の提案に従って、これが機能しました。glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
と、次のピクセル シェーダーを使用しました (マゼンタを置換色として)。
"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];
}
シェーダーの C++ プロキシ クラス -- 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);
}
シェーダーをインスタンス化するには、プロジェクトで次のようにします。
shaderChromakey chromakey;
chromakey.setup(HORIZONTAL, VERTICAL)
描画ループで、シェーダーを有効にするには:
chromakey.beginRender();
// draw chomakeyed frame here
chromakey.endRender();