HLSL Shader за изваждане на фоново изображение

Опитвам се да накарам HLSL Pixel Shader за Silverlight да работи, за да извади фоновото изображение от видео изображение. Може ли някой да предложи по-сложен алгоритъм от този, който използвам, защото алгоритъмът ми не го прави правилно?

float Tolerance : register(C1);
SamplerState  ImageSampler : register(S0);
SamplerState  BackgroundSampler : register(S1);

struct VS_INPUT
{
    float4 Position : POSITION;
    float4 Diffuse  : COLOR0;
    float2 UV0      : TEXCOORD0;
    float2 UV1      : TEXCOORD1;
};

struct VS_OUTPUT
{
    float4 Position  : POSITION;
    float4 Color     : COLOR0;
    float2 UV        : TEXCOORD0;
};


float4 PS( VS_OUTPUT input ) : SV_Target
{
    float4 color = tex2D( ImageSampler, input.UV );
    float4 background = tex2D( BackgroundSampler, input.UV);

    if (abs(background.r - color.r) <= Tolerance && 
                  abs(background.g - color.g) <= Tolerance && 
                  abs(background.b - color.b) <= Tolerance)
    {
      color.rgba = 0;
    }

   return color;

}

За да видите пример за това, имате нужда от компютър с уеб камера:

  1. Отидете на страницата http://xmldocs.net/alphavideo/background.html
  2. Натиснете [Старт на запис].
  3. Преместете тялото си извън сцената и натиснете [Capture Background].
  4. След това преместете тялото си обратно в сцената и използвайте плъзгача, за да регулирате стойността на толерантността към шейдъра.

person Michael S. Scherotter    schedule 06.08.2010    source източник
comment
Бихте ли обяснили как точно не го прави правилно? И трябва да кажа, че съм изненадан, че вашият шейдър изобщо работи.   -  person Denis    schedule 06.08.2010
comment
Разгледайте този пример за адаптивно изваждане на фона в HLSL: vvvv.org/forum/adaptive-background -изваждане   -  person appas    schedule 26.02.2012


Отговори (1)


РЕДАКТИРАНЕ

Единичен пиксел не е полезен за такава задача поради шума. Така че същността на алгоритъма трябва да бъде да измерва сходството между пикселните блокове. Псевдокод на рецепта (базиран на измерване на корелация):

Divide image into N x M grid
For each N,M cell in grid:
   correlation = correlation_between(signal_pixels_of(N,M),
                                     background_pixels_of(N,M)
                                    );
   if (correlation > threshold)
      show_background_cell(N,M)
   else
      show_signal_cell(N,M)

Това е последователен псевдокод, но може лесно да се преобразува в HLSL шейдър. Просто всеки пиксел открива към кой пикселен блок принадлежи и след това измерва корелацията между съответните блокове. И въз основа на тази корелация показва или скрива текущия пиксел.

Опитайте този подход, Успех!

person Agnius Vasiliauskas    schedule 06.09.2010