2010-08-06 15 views
2

J'essaye d'obtenir un Pixel Shader HLSL pour Silverlight pour travailler afin de soustraire l'image d'arrière-plan d'une image vidéo. Quelqu'un peut-il suggérer un algorithme plus sophistiqué que celui que j'utilise parce que mon algorithme ne le fait pas correctement?HLSL Shader pour soustraire l'image d'arrière-plan

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; 

} 

Pour voir un exemple de cela, vous avez besoin d'un ordinateur avec une webcam:

  1. Aller à la page http://xmldocs.net/alphavideo/background.html
  2. Appuyez sur [Démarrer l'enregistrement].
  3. Sortez votre corps de la scène et appuyez sur [Fond d'écran de capture].
  4. Replacez ensuite votre corps dans la scène et utilisez le curseur pour ajuster la valeur Toleance au shader.
+0

Pourriez-vous expliquer exactement comment "ne le fait pas correctement"? Et je dois dire que je suis surpris que votre shader fonctionne du tout. – Denis

+0

Jetez un coup d'œil à cet exemple de soustraction d'arrière-plan adaptative en HLSL: http://vvvv.org/forum/adaptive-background-substraction – appas

Répondre

2

EDIT

pixel est pas utile pour cette tâche, à cause du bruit. L'essence de l'algorithme devrait donc être de mesurer la similarité entre les blocs de pixels. Recette pseudo-code (basé sur correlation mesure):

 
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) 

Ce code est pseudo séquentiel, mais il pourrait être facilement converti en shaders HLSL. Simplement chaque pixel détecte à quel bloc de pixels il appartient, et après cela mesure la corrélation entre les blocs correspondants. Et basé sur cette corrélation montre ou cache le pixel actuel. Essayez cette approche, Bonne chance!