2010-08-06 155 views
2

我想让Silverlight的HLSL像素着色器工作从视频图像中减去背景图像。任何人都可以提出比我使用更复杂的算法,因为我的算法没有正确执行它?HLSL着色器减去背景图像

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. 然后将您的身体移回到场景中,并使用滑块来调整着色器的Toleance值。
+0

你能解释它究竟是如何“不正确地做”吗?而且我不得不说我的着色器一点都不令人惊讶。 – Denis 2010-08-06 05:33:44

+0

查看HLSL中自适应背景减法的示例:http://vvvv.org/forum/adaptive-background-substraction – appas 2012-02-26 12:08:28

回答

2

编辑

单个像素不是这样的任务非常有用,因为噪音。所以算法的本质应该是测量像素块之间的相似度。配方伪代码(基于correlation测量):

 
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着色。简单地说,每个像素检测它属于哪个像素块,然后测量相应块之间的相关性。并根据相关性显示或隐藏当前像素。

试试这个方法吧, 祝你好运!