Programmatisch wackelige oder unscharfe Bilder finden

8

Die meisten modernen mobilen Kameras haben eine Familie von Techniken namens Bildstabilisierung, um wackelige Effekte in Fotos aufgrund der Bewegung des Kameraobjektivs oder der zugehörigen Hardware zu reduzieren. Aber immer noch eine ganze Reihe von mobilen Kameras erzeugen wackelige Fotos. Gibt es einen zuverlässigen Algorithmus oder eine Methode, die auf mobilen Geräten implementiert werden kann, speziell auf Android, um herauszufinden, ob ein gegebenes Bild wackelig ist oder nicht? Ich erwarte nicht, dass der Algorithmus das Eingabebild stabilisiert, aber der Algorithmus / die Methode sollte zuverlässig einen definitiven Booleschen Wert zurückgeben, egal ob das Bild wackelig ist oder nicht. Es muss nicht Java sein, sondern kann auch C / C ++ sein, so dass man es über das native Kit erstellen und die APIs der obersten Ebene zugänglich machen kann. Die folgende Abbildung beschreibt das erwartete Ergebnis. Diese Frage beschäftigt sich auch mit einzelnen Bildproblemen, daher funktionieren in diesem Fall mehrere framesbasierte Lösungen nicht. Es geht speziell um Bilder, nicht um Videos.

    
Subin Sebastian 22.08.2014, 10:26
quelle

3 Antworten

3

Würden nicht unscharfe Bilder das implizieren a) Kanten sind verschwommen, so dass jeder farbverlaufsbasierte Operator im Vergleich zur Leuchtdichte im Bild niedrige Werte hat b) Kanten sind unscharf, so dass jeder krümmungsbasierte Operator niedrige Werte hat c) für wackelige Bilder werden die Pixel mit anderen Pixeln in der Richtung des Shakes (einer Translation oder einer Rotation) korreliert

Ich habe dein Bild in Gimp gemacht, Sobel für a) und Laplacian für b) (verfügbar in openCV), und habe Bilder, die im obigen Teil viel dunkler sind.

Das Kalibrieren von Schwellenwerten für allgemeine Bilder wäre ziemlich schwierig, denke ich.

    
user3970006 23.08.2014, 19:24
quelle
2

Haben Sie es mit einem Videostream oder einem einzelnen Bild zu tun?

Im Falle eines Videostreams : Am besten berechnen Sie die Differenz zwischen jeweils zwei benachbarten Frames. Und markieren Sie jedes Pixel mit Differenz. Wenn die Anzahl solcher Pixel niedrig ist - befinden Sie sich in einem nicht wackeligen Rahmen. Beachten Sie, dass bei dieser Methode nicht geprüft wird, ob das Bild scharf ist, sondern nur, um Bewegungsunschärfe im Bild zu vermeiden. Ihre Implementierung sollte Folgendes enthalten:

  1. Für jedes Bild 'i' - normalisieren Sie das Bild (arbeiten Sie mit Graustufe, wenn Sie mit Fließkommazahlen arbeiten, normalisieren Sie den Mittelwert auf 0 und die Standardabweichung auf 1)
  2. Speichern Sie den vorherigen Videoframe.
  3. Ermitteln Sie bei jedem neuen Videorahmen die pixelweise Differenz zwischen den Bildern und zählen Sie die Anzahl der Pixel, für die die Differenz einen Schwellenwert überschreitet. Wenn die Anzahl solcher Pixel zu hoch ist (sagen wir & gt; 5% des Bildes), bedeutet dies, dass die Bewegung zwischen dem vorherigen Bild und dem aktuellen Bild groß ist und Sie Bewegungsunschärfe erwarten. Wenn die Person das Telefon festhält, sehen Sie einen starken Rückgang der Pixelanzahl, die sich geändert hat.
  4. Wenn Ihre Bilder nicht im Fließpunkt, sondern im Fixpunkt (zB 0..255) dargestellt werden, können Sie die Histogramme der Bilder vor der Subtraktion, um das Rauschen zu reduzieren.
  5. Solange Sie Bilder mit Bewegung erhalten, lassen Sie diese Rahmen einfach fallen und zeigen Sie dem Benutzer eine Nachricht an: "Halten Sie Ihr Telefon fest". Sobald Sie ein gutes stabilisiertes Bild erhalten haben, verarbeiten Sie es, aber behalten Sie sich das vorherige Bild und machen Sie die Subtraktion für jedes Video-Bild.

Der obige Algorithmus sollte stark genug sein (ich habe ihn in einem meiner Projekte benutzt, und es hat wie eine Magie funktioniert).

Im Falle eines einzelnen Bildes : Der obige Algorithmus löst keine unscharfen Bilder und ist für ein einzelnes Bild irrelevant.

  1. Um den Fokus zu lösen, empfehle ich, Bildkanten zu berechnen und zu zählen die Anzahl der Pixel mit starken Kanten (höher als a Schwelle). Sobald Sie eine hohe Anzahl von Pixeln mit Kanten erhalten haben (sagen & gt; 5% des Bildes), sagen Sie, dass das Bild scharf ist. Dieser Algorithmus ist bei weitem nicht perfekt und kann viele Fehler machen, abhängig von der Textur des Bildes. Ich empfehle, X, Y und diagonale Kanten zu verwenden, aber glätten Sie das Bild vor der Kantenerkennung, um das Rauschen zu reduzieren.
  2. Ein stärkerer Algorithmus würde alle Kanten (Ableitungen) nehmen und ihr Histogramm berechnen (wie viele Pixel im Bild diese spezifische Kantenintensität hatten). Dies wird durchgeführt, indem zuerst ein Bild von Kanten berechnet wird und dann ein Histogramm des Kantenbildes berechnet wird. Jetzt können Sie die Form des Histogramms (die Verteilung der Kantenstärke) analysieren. Nehmen Sie zum Beispiel nur die oberen 5% der Pixel mit den stärksten Kanten und berechnen Sie die Varianz ihrer Kantenintensität.
  3. Wichtige Tatsache: In unfokussierten Bildern erwarten Sie, dass die Mehrheit der Pixel eine sehr geringe Kantenreaktion, wenige eine mittlere Kantenreaktion und fast Null mit starker Kantenreaktion haben. In Bildern mit perfektem Fokus haben Sie immer noch die Mehrheit der Pixel mit einer niedrigen Kantenreaktion, aber das Verhältnis zwischen mittlerer Antwort und starker Antwort ändert sich. Sie können es deutlich in der Histogrammform sehen. Deshalb empfehle ich, nur ein paar Prozent der Pixel mit der stärksten Kantenreaktion zu verwenden und nur mit ihnen zu arbeiten. Der Rest ist nur ein Geräusch. Sogar ein einfacher Algorithmus, der das Verhältnis zwischen der Anzahl von Pixeln mit starker Antwort dividiert durch die Menge von Pixeln mit mittleren Kanten nimmt, ist ziemlich gut.

Fokusproblem in Video :

  1. Wenn Sie einen Videostream haben, können Sie die oben beschriebenen Algorithmen für problematische Fokuserkennung verwenden, aber anstatt konstante Schwellenwerte zu verwenden, aktualisieren Sie sie einfach, während das Video läuft. Letztendlich konvergieren sie zu besseren Werten als vordefinierte Konstanten.

Letzte Anmerkung: Das Problem der Fokuserkennung in einem einzelnen Bild ist sehr schwierig. Es gibt eine Menge akademischer Arbeiten (mit Fourier-Transform-Wavelets und anderen "Big algorithmic cannons"). Aber das Problem bleibt sehr schwierig, denn wenn man ein verschwommenes Bild betrachtet, kann man nicht wissen, ob die Kamera die Unschärfe mit falschem Fokus erzeugt oder ob die ursprüngliche Realität bereits verschwommen ist (z. B. weiße Wände sind sehr verschwommen, Bilder aufgenommen) in einer Dunkelheit neigen dazu, auch bei perfektem Fokus verschwommen zu sein, Bilder von Wasseroberfläche, Tischoberfläche neigen dazu, verschwommen zu sein). Jedenfalls gibt es nur wenige Threads im Stapelüberlauf bezüglich des Fokus im Bild. Wie dieses . Bitte lies sie.

    
DanielHsH 26.08.2014 10:16
quelle
1

Sie können auch die Fourier-Transformation des Bildes berechnen, und wenn in den Bins mit hoher Frequenz eine geringe Anhäufung vorhanden ist, ist das Bild wahrscheinlich unscharf. JTransform ist eine sinnvolle Bibliothek, die FFTs anbietet, wenn Sie diese Route hinunterfahren möchten.

Es gibt auch einen ziemlich ausführlichen Blogeintrag hier über verschiedene Methoden, die verwendet werden könnten

Es gibt auch eine weitere Stapelüberlauffrage fragt dies aber mit OpenCV , hat OpenCV auch Java-Bindings und kann in Android-Projekten verwendet werden, daher könnte diese Antwort auch hilfreich sein.

    
pont 27.08.2014 07:16
quelle