3

我制作了一个简单的基于网络摄像头的应用程序,它检测“运动边缘”,因此绘制了一个纹理,显示当前帧的像素与前一帧显着不同的位置。这是我的代码:

// LastTexture is a Texture2D of the previous frame.
// CurrentTexture is a Texture2D of the current frame.
// DifferenceTexture is another Texture2D.
// Variance is an int, default 100;

Color[] differenceData = new Color[CurrentTexture.Width * CurrentTexture.Height];
Color[] currentData = new Color[CurrentTexture.Width * CurrentTexture.Height];
Color[] lastData = new Color[LastTexture.Width * LastTexture.Height];

CurrentTexture.GetData<Color>(currentData);
LastTexture.GetData<Color>(lastData);

for (int i = 0; i < currentData.Length; i++)
{
    int sumCD = ColorSum(currentData[i]); // ColorSum is the same as c.R + c.B + c.G where c is a Color.
    int sumLD = ColorSum(lastData[i]);
    if ((sumCD > sumLD - Variance) && (sumCD < sumLD + Variance))
        differenceData[i] = new Color(0, 0, 0, 0); // If the current pixel is within the range of +/- the Variance (default: 100) variable, it has not significantly changes so is drawn black.
    else
        differenceData[i] = new Color(0, (byte)Math.Abs(sumCD - sumLD), 0); // This has changed significantly so is drawn a shade of green.
}

DifferenceTexture = new Texture2D(game1.GraphicsDevice, CurrentTexture.Width, CurrentTexture.Height);
DifferenceTexture.SetData<Color>(differenceData);

LastTexture = new Texture2D(game1.GraphicsDevice,CurrentTexture.Width, CurrentTexture.Height);
LastTexture.SetData<Color>(currentData);

有没有办法使用着色器将此计算卸载到 GPU(使用上述方法可以达到大约 25/26 fps,但这有点慢)?我对 HLSL 着色器的工作原理有基本的了解,并不期望有完整的解决方案,我只想知道这是否可能以及如何从着色器中获取“差异”纹理数据,以及这实际上是否会更快.

提前致谢。

4

3 回答 3

3

您可以在像素着色器中对两个纹理进行采样,然后将差异写出为颜色值。如果设置了Render Target,则从着色器输出的颜色信息将存储在此纹理中,而不是帧缓冲区中。

我不知道你希望看到什么样的速度提升,但我就是这样做的。

*编辑-哦,我忘了说,请注意您使用的采样类型,因为它会影响结果。如果您希望您的算法直接转换到 GPU,请使用点采样开始。

于 2009-07-25T14:42:19.780 回答
2

关于您上面关于决定使用双线程方法解决问题的评论,请查看 Microsoft 的 .Net Parallel Extensions CTP。微软网站

如果你不打算部署到 XBox360,这个库与 XNA 配合得很好,而且我已经看到在某些循环和迭代中速度有了很大的提高。

您基本上只需要更改几行代码,例如:

for (int i = 0; i < currentData.Length; i++)
{
    // ...
}

将更改为:

Parallel.For(0, currentData.Length, delegate(int i)
{
   // ...
});

自动使处理器中的每个内核帮助处理数字。它又快又好。

祝你好运!

于 2009-07-26T21:29:40.367 回答
0

Sobel 算子或类似的东西用于游戏引擎和其他边缘检测的实时应用程序。编写为像素着色器很简单。

于 2011-04-18T22:25:05.623 回答