Est-il possible d'utiliser un shader pour trouver la « différence » entre les deux textures? (XNA / HLSL)

StackOverflow https://stackoverflow.com/questions/1182158

  •  19-09-2019
  •  | 
  •  

Question

Je l'ai fait d'une simple application webcam qui détecte les « bords du mouvement » dessine donc une texture qui montre où les pixels de l'image actuelle sont significativement différentes à l'image précédente. Ceci est mon 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);

Y at-il un moyen de délester ce calcul au GPU en utilisant les shaders (il peut aller à environ 25/26 fps en utilisant la méthode ci-dessus, mais cela est un peu lent)? J'ai une compréhension de base de la façon dont HLSL shaders travail et ne vous attendez pas une solution complète, je veux juste savoir si cela serait possible et comment obtenir les données de texture « différence » du shader et si cela serait effectivement plus vite .

Merci d'avance.

Était-ce utile?

La solution

En ce qui concerne votre commentaire ci-dessus au sujet de décider d'utiliser une approche à double fil à votre problème, consultez le CTP .Net Parallel Extensions de Microsoft. microsoft.com

Si vous ne prévoyez pas sur le déploiement d'une Xbox360, cette bibliothèque fonctionne très bien avec XNA, et je l'ai vu des améliorations de vitesse massives dans certaines boucles et itérations.

Vous auriez essentiellement que de changer une ligne de code couple, par exemple:

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

changerait à:

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

pour effectuer automatiquement chaque noyau dans votre processeur aider avec le nombre crissant. Il est rapide et excellent.

Bonne chance!

Autres conseils

Vous pouvez déguster deux textures dans le pixel shader, puis écrire la différence comme la valeur de couleur. Si vous configurez un Rendu cible, la couleur informations Ouput du shader sera stocké dans cette texture au lieu du framebuffer.

Je ne sais pas quel genre de gain en vitesse que vous attendez de voir, mais comment je le ferais.

* edit - Oh, et j'ai oublié de dire, être au courant du type d'échantillonnage que vous utilisez, car il aura une incidence sur les résultats. Si vous voulez que votre algorithme pour traduire directement au GPU, utilisez l'échantillonnage de points pour commencer.

Le opérateur de Sobel ou quelque chose comme il est utilisé dans les moteurs de jeux et d'autres applications en temps réel pour la détection de bord. Il est trivial d'écrire comme un pixel shader.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top