Ist es möglich, einen Shader zu verwenden, um den „Unterschied“ zwischen zwei Texturen zu finden? (XNA / HLSL)

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

  •  19-09-2019
  •  | 
  •  

Frage

Ich habe eine einfachen Webcam-basierte Anwendung gemacht, dass die „Ränder der Bewegung“ detektiert, so zieht eine Textur, die zeigt, wo die Pixel des aktuellen Rahmens zum vorherigen Bild deutlich unterschiedlich sind. Dies ist mein 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);

Gibt es eine Möglichkeit, diese Berechnung auf der GPU-Shadern abzuladen (es kann bei etwa 25/26 fps gehen die obige Methode verwenden, aber das ist ein bisschen langsam)? Ich habe ein grundlegendes Verständnis davon, wie HLSL Shadern Arbeit und keine vollständige Lösung erwarten, ich möchte nur wissen, ob dies möglich wäre, und wie die „Differenz“ von der Shader Texturdaten zu bekommen, und wenn dies wäre tatsächlich schneller .

Vielen Dank im Voraus.

War es hilfreich?

Lösung

In Bezug auf Ihren Kommentar oben über die Entscheidung, einen Dual-Thread-Ansatz, um Ihr Problem zu verwenden, überprüfen Sie die .Net Parallel Extensions CTP von Microsoft aus. microsoft.com

Wenn Sie planen, nicht auf eine XBox360 auf dem Einsatz diese Bibliothek arbeitet gut mit XNA, und ich habe in einigen Schleifen und Wiederholungen massive Verbesserungen in der Geschwindigkeit gesehen.

Sie würden im Grunde müssen nur ein paar Zeilen Code ändern, zum Beispiel:

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

würde sich ändern:

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

, um automatisch jeden Kern in Ihrem Prozessor dazu beitragen, dass aus mit der Zahl Knirschen. Es ist schnell und sehr gut.

Viel Glück!

Andere Tipps

Sie könnten zwei Texturen innerhalb der Pixel-Shader-Probe, dann die Differenz schreiben als Farbwert. Wenn Sie ein Render Ziel , die Farbe Informationen, die Sie aus dem Shader ouput werden in dieser Textur anstelle des Framebuffer gespeichert werden.

Ich weiß nicht, welche Art von Geschwindigkeit gewinnen Sie erwarten würden, um zu sehen, aber das ist, wie ich es tun würde.

* edit - Oh, und ich vergaß zu sagen, beachten Sie das Probenahmesystem Sie verwenden, wie es die Ergebnisse beeinflussen. Wenn Sie Ihren Algorithmus direkt an die GPU übersetzen wollen, verwenden Punktabtastung mit zu beginnen.

Das Sobeloperator oder so etwas wie es in Game-Engines und anderen Echtzeit-Anwendungen verwendet wird, für die Kantenerkennung. Es ist trivial als Pixel-Shader zu schreiben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top