I have made a simple webcam based application that detects the “edges of motion” so draws a texture that shows where the pixels of the current frame are significantly different to the previous frame. This is my code:
// 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);
Is there a way to offload this calculation to the GPU using shaders (it can go at about 25/26 fps using the above method, but this is a bit slow)? I have a basic understanding of how HLSL shaders work and don’t expect a full solution, I just want to know if this would be possible and how to get the “difference” texture data from the shader and if this would actually be any faster.
Thanks in advance.
Regarding your comment above about deciding to use a dual thread approach to your problem, check out the .Net Parallel Extensions CTP from Microsoft. microsoft.com
If you’re not planning on deploying to an XBox360, this library works great with XNA, and I’ve seen massive speed improvements in certain loops and iterations.
You would basically only have to change a couple lines of code, for example:
would change to:
to automatically make each core in your processor help out with the number crunching. It’s fast and excellent.
Good luck!