我制作了一个简单的基于网络摄像头的应用程序来检测“运动边缘”,因此绘制一个纹理,显示当前帧的像素与前一帧的显着不同的位置。这是我的代码:
// 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着色器的工作原理有一个基本的了解,并且不希望有完整的解决方案,我只是想知道这是否可能以及如何从着色器中获取“差异”纹理数据,如果这实际上更快
提前致谢。
答案 0 :(得分:3)
您可以在像素着色器中对两个纹理进行采样,然后将差异写为颜色值。如果设置Render Target,则从着色器输出的颜色信息将存储在此纹理中而不是帧缓冲区中。
我不知道你期望看到什么样的速度增益,但我就是这样做的。
*编辑 - 哦,我忘了说,请注意您使用的采样类型,因为它会影响结果。如果您希望算法直接转换为GPU,请使用点采样开始。
答案 1 :(得分:2)
关于您上面关于决定使用双线程方法解决问题的评论,请查看Microsoft的.Net Parallel Extensions CTP。 microsoft.com
如果您不打算部署到XBox360,这个库可以很好地使用XNA,并且我已经看到在某些循环和迭代中大幅提升了速度。
您基本上只需更改几行代码,例如:
for (int i = 0; i < currentData.Length; i++)
{
// ...
}
将更改为:
Parallel.For(0, currentData.Length, delegate(int i)
{
// ...
});
自动使处理器中的每个核心都有数字运算帮助。它快速而优秀。
祝你好运!答案 2 :(得分:0)
Sobel operator或类似的东西在游戏引擎和其他实时应用程序中用于边缘检测。写为像素着色器是微不足道的。