Шейдер HLSL для вычитания фонового изображения

Я пытаюсь заставить пиксельный шейдер HLSL для 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. Переместите свое тело за пределы сцены и нажмите [Захват фона].
  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