Wie man FFT beim Entrauschen von Bildern richtig anwendet


8

Ich schreibe ein Programm (Qt Widgets / C ++) zum Entfernen von Bildrauschen. Als Entrauschungsmethode habe ich die Methode der nicht lokalen Mittel gewählt . Diese Methode hat eine unglaubliche Qualität wiederhergestellter Bilder (deshalb ist sie die einzige Entrauschungsmethode in OpenCV), hat aber enorme Berechnungskosten, so dass ich viele modifizierte Varianten dieser Methode erstellt habe (einige mit Multithreading, einige mit Algorithmus). Aber ich habe ein Problem mit dem, der FFT betrifft

Ich habe alle Schritte dieses Artikels befolgt (nur eine Seite, 1430) und alles funktioniert perfekt, außer dem FFT-Teil, es gibt nur 2 Zeilen darüber in der Zeitung und ich kann nicht verstehen, wie man fft verwenden soll

Dieses Problem hat mich seit Monaten beschäftigt, jede Hilfe oder Einsicht wäre sehr dankbar.

Verkürzte Version der Frage: Wie kann ich schnell die summierte quadratische Differenz zweier Arrays auf dem Bild (eines oben und eines in der Mitte, Werte sind Farben) ermitteln? (O (n ^ 2) ist sehr kostspielig, es gibt viele dieser Arten von Operationen, wie oben in Papier angegeben, die über FFT mit O (n * log n) durchgeführt werden können (sagt, dass diese 2 Arrays irgendwie eine kreisförmige Faltung bilden) )

Geben Sie hier die Bildbeschreibung ein


Was haben Sie letztendlich für die Berechnung von FFT getan? Selbst wenn FFT vorberechnet wird, dauert die punktweise Multiplikation und Addition aller Patch-Elemente wobeiist die Größe des Patches. Wie haben Sie das überwunden? | P |Ö(|P.|)|P.|
Curryage

Antworten:


5

Der Trick im Papier ist der folgende:

  1. ichW.|ich(x+ich)- -ich(y+ich)|2ichxyich
  2. ichich2(x+ich)+ichich2(y+ich)- -2ichich(x+ich)ich(y+ich)=EIN+B.- -2C.
  3. EINB.
  4. C.xyC.xy

Die Fourier-Transformation ist offensichtlich eine 2D-Transformation, da Sie mit 2D-Daten arbeiten. Was Sie für ein bestimmtes Patch erhalten, ist ein 2D-Array komplexer Werte.

Zusätzliche Bemerkungen

Meiner Meinung nach ist dieser Artikel nicht die beste NL-Mittel-Beschleunigungsstrategie. Experimente, die ich bereits 2007/2008 durchgeführt habe, zeigen, dass die Vorauswahl von Patches besser ist (sowohl hinsichtlich der Geschwindigkeit als auch der Qualität der Ergebnisse). Ich habe begonnen , diese Blogging über hier , aber leider für Zeit , die ich bin auf der Suche , die Beiträge zu beenden.

Die ursprünglichen NL-Mittel-Papiere erwähnen blockweise Implementierungen, die interessant sein können. Grundsätzlich gibt es zwei Möglichkeiten, NL-Mittel zu implementieren:

  1. Schreiben einer Entrauschungsschleife für jedes Pixel im Bild
  2. Schreiben Sie für jedes Patch eine Entrauschungsschleife und projizieren Sie die Patches zurück, um ein Bild zu erstellen.

Die erste Impolementation ist der ursprüngliche Ansatz, da 2005 Speicher- und Multicore-CPUs teuer waren. Ich habe mich andererseits für die Nummer 2 der letzten Hardware in den letzten 2 Jahren entschieden. Dies hängt von Ihrer typischen Bildgröße ab und davon, ob Sie Domänentransformationen wie DFT / DCT berechnen möchten (wie im vorgeschlagenen Dokument und in BM3D).


Vielen Dank für Ihre Antwort, genau das habe ich gebraucht, alles war vor langer Zeit fertig und funktionierte, bis auf den vierten Punkt in dieser Liste, aber jetzt ist es viel klarer. Aber noch eine Frage, wenn Sie nichts dagegen haben: Was wird die Fourier-Transformation von Patch x oder y zurückgeben? Array, Vektor oder Einzelwert? Und was ist erforderlich, um die inverse Transformation zu verwenden? Weil ich darüber nachdenke, fft für jedes Pixel (um ihn herum zentrierte Patches) vorab zu berechnen und die Ergebnisse vor dem Entrauschen in ein 2d-Array zu schreiben und dann einfach diese Matrix zu verwenden, um inverses fft zu erhalten, aber ich weiß nicht, ob dies für inverses fft ausreicht
Shf

Oh, und sollte ich 2d fft verwenden oder Patch in 1d Array übersetzen? Übrigens hatte ich sowieso vor, nach dieser patchweisen Implementierung zu schreiben, danke für einen Rat :) etwas Ähnliches auch vor langer Zeit - ipol.im/pub/art/2011/bcm_nlm
Shf

Ich habe die Antwort aktualisiert.
Sansuiso

ok, also kann ich die FFT für Patches vorberechnen, die vor dem Donoising um jedes Pixel zentriert sind, obwohl es viel Speicher benötigt (m n size_of_patch size_of_patch sizeof (double)), aber wenn ich Gewichte zähle, müsste ich immer noch 2 punktweise multiplizieren komplexe Arrays und danach inverse fft auf empfangenen 2d Array, es ist sogar mehr als O (n ^ 2), wenn ich mich nicht irre
Shf

2
C.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.