Schnelles Berechnen der "verschmutzten" Bereiche zwischen zwei ähnlichen Bildern

8

Ich habe zwei sehr ähnliche Bilder (speziell zwei Screenshots) und versuche die beste (schnellste) Art zu finden, welche Bereiche des Bildes sich verändert haben (als ein Array von Rechtecken, die die verschiedenen Bereiche repräsentieren)

Einige Kriterien:

  • Es muss nicht pixelgenau sein, sondern muss alle kleinen Änderungen enthalten (d. h. es wäre akzeptabel, dass eine einzelne Pixeländerung einen großen Fehlerspielraum aufweist)
  • Es muss schnell sein (Idealerweise sollten 2x 1920x1080 Bilder & lt; 20 ms auf einem typischen Verbraucher, der heute gekauft wurde,
  • nehmen)
  • Es erfordert keinen konfigurierbaren Schwellenwert (aber wenn es eine Lösung gibt, die dies ermöglicht, wäre das ein schöner Bonus)
  • Es kann angenommen werden, dass die Eingangsbilder immer perfekte verlustfreie Bilder sind.

Ich habe zwei funktionierende Lösungen, aber eine ist eine Brute-Force-Pixel-für-Pixel-Berechnung, die natürlich sehr langsam ist. Und für den anderen habe ich versucht, die beiden Bilder in Stücke unterschiedlicher Größe aufzuteilen und Prüfsummen für jedes Stück zu berechnen, aber das ist auch ziemlich langsam.

Nur für diejenigen, die sich fragen, was ich baue - es ist eine Art dümmer (und langsamer) Remote-Desktop, der in einem Browser ohne Plugins verwendet werden kann.

    
PhonicUK 13.08.2012, 09:56
quelle

2 Antworten

3

Sie müssen einen Pixel-pro-Pixel-Vergleich durchführen. Ich denke nicht, dass es so langsam sein sollte. Zum Beispiel der Code:

%Vor%

läuft in etwa 40 ms auf meinem Laptop. Wenn es nur Graustufen ist, läuft es unter 20 ms. Wenn Sie echte Bilddaten verwenden würden, würde diff [i]! = 0 eine Änderung der beiden Bilder anzeigen.

Ihre Lösung ist möglicherweise langsam, wenn Sie die Pixelwerte mit Bitmap.GetPixel oder einer anderen langsamen Methode lesen. Wenn das der Fall ist, schlage ich vor, auf die Bitmap.LockBits zu schauen oder eine unsichere Methode zu verwenden.

    
sam1589914 13.08.2012, 10:23
quelle
3

Meine vorherige Antwort wurde wegen ihres Formats gelöscht, ich werde sie besser schreiben.

Ich habe Sie gefragt, ob Sie GPU verwenden, um die Bildunterschiede zwischen Ihren beiden Bildern zu berechnen. Diese Lösung könnte Ihre Rechenzeit erheblich verbessern, da die GPU im Vergleich zur CPU-Berechnung sehr parallel ist.

Mit C # könnten Sie versuchen, XNA für diesen Zweck zu verwenden. Tatsächlich habe ich einen kleinen Test mit einem Single-Pass-HLSL (es ist, was verwendet wird, um GPU mit direct3D zu programmieren) Pixel Shader:

%Vor%

Die Berechnung auf dem XNA-Teil ist wirklich einfach. Unter Verwendung des Basis-Snippets von XNA mit Visual Studio habe ich die Zeichenfunktion einfach wie folgt geschrieben:

%Vor%

im1 und im2 sind die zwei 1920 * 1080 farbigen bmp-Bilder, die als Texture2D geladen sind, und e ist die file.fx, die als Effekt geladen wird.

Mit dieser Technik erhalte ich eine 17 / 18ms Rechenzeit auf einem ziemlich normalen Computer (Laptop mit I5-2410m @ 2,3 Ghz, 4 GB RAM, Nvidia Geforce GT525m.

Hier ist die Ausgabe des Programms, mit dem Unterschied Bild gezeigt (Entschuldigung das ist stark gezoomt, weil ich nicht 1920 * 1080 Bildschirm haben: & gt;), und außerdem sind die beiden Bilder im1 und im2 mit einigen kleinen Unterschieden zwischen ihnen : Ссылка

Ich bin ziemlich neu in der GPU-Programmierung, also wenn ich einen großen Fehler gemacht habe, wie die Zeit berechnet werden sollte oder sonst irgendwas, dann sag es mir bitte!

Edit: Das erste, was zu beachten ist, ich habe gerade gelesen, dass "es eine nicht-triviale Operation sein wird, da GPUs nicht sehr gut mit Verzweigungen umgehen".

Mit freundlichen Grüßen

    
Al_th 13.08.2012 19:35
quelle

Tags und Links