2010-03-27 3 views
27

Das ProblemWie erkenne ich in einem digitalen Foto, ob ein Berg von Wolken verdeckt ist?

Ich habe eine Sammlung von digitalen Fotos von a mountain in Japan. Allerdings ist der Berg oft von Wolken oder Nebel verdeckt.

Welche Techniken kann ich verwenden, um zu erkennen, dass der Berg im Bild sichtbar ist? Ich verwende derzeit Perl mit dem Imager Modul, aber offen für Alternativen.

Alle Bilder werden von genau derselben Position aufgenommen - dies sind einige Beispiele.

Sample Images http://www.freeimagehosting.net/uploads/7304a6e191.jpg

Meine naive Lösung

Ich begann durch mehrere horizontale Pixelproben des Bergkegel zu nehmen und die Helligkeitswerte auf andere Proben aus dem Himmel zu vergleichen. Dies funktionierte gut, um gutes Bild 1 und schlechtes Bild 2 zu unterscheiden.

Allerdings schneite es im Herbst und der Berg wurde heller als der Himmel, wie Bild 3, und mein einfacher Helligkeitstest begann zu versagen.

Bild 4 ist ein Beispiel für einen Randfall. Ich würde dies als ein gutes Bild einstufen, da ein Teil des Berges deutlich zu sehen ist.

UPDATE 1

Vielen Dank für die Anregungen - Ich bin glücklich, Sie alle in beträchtlichem Ausmaß meine Kompetenz überschätzt.

Basierend auf den Antworten habe ich versucht, die ImageMagick edge-detect Transformation, die mir ein viel einfacheres Bild zu analysieren gibt.

convert sample.jpg -edge 1 edge.jpg 

Edge detected samples http://www.freeimagehosting.net/uploads/caa9018d84.jpg

Ich nehme ich eine Art Maskierung benutzen soll, um von den Bäumen loszuwerden und die meisten der Wolken.

Sobald ich das maskierte Bild habe, was ist der beste Weg, die Ähnlichkeit mit einem "guten" Bild zu vergleichen? Ich denke, der Befehl "compare" ist für diesen Job geeignet? Wie bekomme ich daraus einen numerischen "Ähnlichkeits" -Wert?

UPDATE 2

glaube ich irgendwo mit convolve werden zu bekommen.

Ich habe mein "Kernel" -Bild (oben im Bild unten) gemacht, indem ich Kantenerkennung auf einem guten Bild durchgeführt habe. Ich verdunkelte dann den ganzen Lärm um den Umriss des Berges und schnitt ihn dann ab.

habe ich dann den folgenden Code:

use Image::Magick; 

# Edge detect the test image 
my $test_image = Image::Magick->new; 
$test_image->Read($ARGV[0]); 
$test_image->Quantize(colorspace=>'gray'); 
$test_image->Edge(radius => 1); 

# Load the kernel 
my $kernel_image = Image::Magick->new; 
$kernel_image->Read('kernel-crop.jpg'); 

# Convolve and show the result 
$kernel_image->Convolve(coefficients => [$test_image->GetPixels()]); 
$kernel_image->Display(); 

ich dies für verschiedene Beispielbilder lief, und ich habe Ergebnisse, wie unten (das gefaltete Bild unterhalb jeder Probe gezeigt wird):

(Leider - verschiedene Beispielbilder vom letzten Mal!)

alt text http://www.freeimagehosting.net/uploads/f9a5a34980.jpg

Jetzt versuche ich, wie 'ridgy' zu quantifizieren ein Bild ist. Ich versuchte, nehmen Sie das Bild durchschnittliche Helligkeit:

$kernel_image->Scale('1x1'); 
die $kernel_image->GetPixel(x=>1,y=>1)[0]; 

Aber dies gibt keine sinnvollen Werte (0,0165, 0,0175 und 0,0174) nicht geben. Irgendwelche besseren Möglichkeiten?

+4

+1 sehr gut präsentierte Frage – msw

+1

Sie unterschätzt Ihre eigene Kompetenz. Dieser Link zum "Vergleichen" in Update 1 hat eine Reihe sehr guter Ansätze, um einen Grad an Ähnlichkeitsmaß durch Faltung zu erzeugen, wie Marcelo vorgeschlagen hat. Ich nehme an, du tüftelst mit denen, während ich tippe. – msw

Antwort

9

Ich denke, dass Sie auf einem zu niedrigen Niveau arbeiten. Ein schneller Durchlauf durch einen Kantenerkennungsfilter unterteilt die Bildmenge sehr deutlich in (1, 3) und (2, 4). Insbesondere wenn diese Bilder von einem festen Kamera-Standpunkt stammen, wäre das Finden einer Übereinstimmung mit der prototypischen Form in (1) relativ einfach algorithmisch. Selbst Ihr Fall von (4) könnte Ihnen eine Domäne des teilweisen Abgleichs geben, die Sie heuristisch bestimmen könnten, ob dort genug Berg vorhanden wäre, um zu berücksichtigen.

+0

Danke - Ich habe angefangen mit Kantenerkennung zu spielen und habe die Frage aktualisiert. Immer noch ein bisschen hängen geblieben, wie viel Berg ist dort zu quantifizieren. –

4

Die Antwort hängt davon ab, wie spezifisch das Problem ist. Wenn es sich um den gleichen Berg vom selben POV handelt, führe eine Kanten- und Kantendetektion gegen ein bekanntes gutes Bild durch und verwende es als Basis für das Falten gegen kantendetektierte Bilder aus dem Korpus. Wenn Sie nur an der Kante des Berges interessiert sind, entfernen Sie manuell andere Features von der Baseline.

+1

Danke. Zum Glück ist das Problem sehr spezifisch - der POV ist behoben. Die Kantenerkennung scheint der richtige Start zu sein. Ich bin mir etwas unsicher über die Faltung. –

+0

(Sorry für die verzögerte Antwort; andere Zeitzone.) Die Faltung von zwei Bildern zeigt Spikes, die auf eine Art Ähnlichkeit hindeuten. Wenn Sie nur wissen möchten, ob genug von dem Berg sichtbar ist, berechnen Sie die Faltung zwischen einem Bild, das nur die Kante des Berges enthält, und dem Bild, das Sie testen. Eine starke Spitze nahe der Mitte des Bildes wird allen erzählen. –

5

Einige spezifische Empfehlungen, aufbauend auf, was Sie bereits haben:

  1. Nehmen Sie sich am besten Bild (so etwas wie Bild 1), es durch Kantendetektion auszuführen, öffnen Sie das Ergebnis in jedem grafischen Editor (MS Farbe wird tun) und alles außer der Bergobergrenze (die "chinesische Hutlinie") säubern. Das ist dein Convolution-Kernel. Sie können es von oben und von unten zuschneiden (nicht skalieren!), Um im nächsten Schritt etwas Zeit zu sparen.
  2. Verwenden Sie die Convolve Funktion von PerlMagick (Sie scheinen bereits mit Perl und ImageMagick vertraut), um den Kernel mit ein paar Bildern zu falten. Auf dem resultierenden Bild sollten Sie eine scharfe Spitze sehen, die der "richtigen" Position des Kerns entspricht (fällt mit dem Berg im Bild zusammen).
  3. Die relative (zur Höhe des Umgebungslärms) Höhe dieser Spitze wird größer sein, wenn der Berg besser sichtbar ist. Indem Sie mehrere repräsentative Bilder aufnehmen, können Sie möglicherweise einen Schwellenwert festlegen, der gute von schlechten Bildern trennt.
  4. Was auch immer Sie tun, es wird False Positives und False Negatives geben. Sei vorbereitet.
+0

Vielen Dank für die Schritt-für-Schritt-Anleitung. Dies ist wirklich hilfreich für das Niveau, auf dem ich bin. Allerdings bin ich ein wenig unsicher, wie Schritt 2 funktioniert - wie übergebe ich das "Kernel" -Bild an die Convolve-Funktion - es scheint nur eine Matrix von Koeffizienten zu nehmen? –

+0

@Gavin: Kernel == Matrix.Ich habe versucht, eine passende Erklärung von Faltungen online für Sie zu finden, konnte aber nichts finden - vielleicht sollten Sie es selbst versuchen. – AVB

+0

Nach viel Hacking habe ich $ test_image-> GetPixels() als Koeffizienten verwendet - ist das gültig? Ich habe den Beitrag erneut aktualisiert. –

Verwandte Themen