2010-03-27 7 views
27

Le problèmeSur une photo numérique, comment puis-je détecter si une montagne est obscurcie par des nuages?

J'ai une collection de photos numériques de a mountain au Japon. Cependant, la montagne est souvent obscurcie par les nuages ​​ou le brouillard. Quelles techniques puis-je utiliser pour détecter que la montagne est visible dans l'image?

Quelles techniques puis-je utiliser pour détecter que la montagne est visible dans l'image? J'utilise actuellement Perl avec le module Imager, mais ouvert aux alternatives.

Toutes les images proviennent de la même position exacte - il s'agit de quelques exemples.

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

Ma solution naïve

j'ai commencé en prenant plusieurs échantillons de pixels horizontaux du cône de montagne et en comparant les valeurs de luminosité à d'autres échantillons du ciel. Cependant, à l'automne, il a neigé et la montagne est devenue plus claire que le ciel, comme l'image 3, et mon test de luminosité simple a commencé à échouer.

L'image 4 est un exemple d'un cas de bordure. Je classerais cela comme une bonne image car une partie de la montagne est clairement visible.

MISE À JOUR 1

Merci pour les suggestions - Je suis heureux que vous tous largement surestimés ma compétence. Basé sur les réponses, j'ai commencé à essayer la transformation ImageMagick edge-detect, ce qui me donne une image beaucoup plus simple à analyser.

convert sample.jpg -edge 1 edge.jpg 

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

Je suppose que je devrais utiliser une sorte de masquage pour se débarrasser des arbres et la plupart des nuages.

Une fois que j'ai l'image masquée, quelle est la meilleure façon de comparer la similarité à une «bonne» image? Je suppose que la commande "compare" convient à ce travail? Comment puis-je obtenir une valeur de «similarité» numérique à partir de cela?

MISE À JOUR 2

Je pense que je suis quelque part avec convolve en venir.

J'ai fait mon image 'noyau' (en haut de l'image ci-dessous) en effectuant une détection de bord sur une bonne image. J'ai ensuite noirci tout le 'bruit' autour du contour de la montagne et l'ai ensuite recadré.

J'ai ensuite utilisé le code suivant:

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(); 

J'ai couru ceci pour diverses exemples d'images, et j'ai obtenu des résultats comme ci-dessous (l'image convoluée est illustré ci-dessous chaque échantillon):

(Désolé - Différentes images d'échantillons de la dernière fois!)

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

Maintenant, je suis en train de quantifier 'ridgy' une image est. J'ai essayé de prendre l'image de luminosité moyenne:

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

Mais cela donne ne donne pas de valeurs significatives (0,0165, 0,0175 et 0,0174). De meilleures façons?

+4

+1 très bien présenté question – msw

+1

Vous sous-estimez votre propre compétence. Ce lien vers «comparer» dans la mise à jour 1 comporte un certain nombre de très bonnes approches pour générer un degré de similarité par convolution, comme le suggérait Marcelo. Je m'attends à ce que vous jouiez avec ceux que je tape. – msw

Répondre

9

Je pense que vous travaillez à un niveau trop bas. Un passage rapide à travers un filtre de détection de bord a divisé l'ensemble d'images très distinctement en (1, 3) et (2, 4). En particulier, si ces images proviennent d'un point de vue de caméra fixe, trouver une correspondance avec la forme prototypique de (1) serait relativement facile d'un point de vue algorithmique. Même votre cas de (4) pourrait vous donner un domaine de correspondance partielle que vous pourriez heuristiquement déterminer s'il y avait assez de montagne à considérer.

+0

Merci - J'ai commencé à jouer avec Edge detect et mis à jour la question. Encore un peu coincé sur la façon de quantifier combien de montagne est là. –

4

La réponse dépend de la spécificité du problème. Si c'est la même montagne du même point de vue, exécutez la détection de bord et de bord par rapport à une bonne image connue et utilisez-la comme base de référence pour la convolution des images détectées par les bords du corpus. Si ce n'est que le bord de la montagne qui vous intéresse, supprimez manuellement les autres entités de la ligne de base.

+1

Merci. Heureusement, le problème est très spécifique - le POV est corrigé. La détection des contours semble être le bon endroit pour commencer. Je ne suis pas sûr de la partie convolving. –

+0

(Désolé pour la réponse différée, fuseau horaire différent.) La convolution de deux images présentera des pointes qui indiquent une sorte de similitude. Si tout ce que vous voulez savoir est de savoir si assez de la montagne est visible, calculez la convolution entre une image contenant juste le bord de la montagne et l'image que vous testez. Un fort pic près du centre de l'image dira tout. –

5

Quelques recommandations spécifiques, fondés sur ce que vous avez déjà:

  1. Prenez votre meilleure image (quelque chose comme l'image 1), l'exécuter par la détection de bord, ouvrez le résultat dans un éditeur graphique (MS La peinture fera l'affaire) et nettoiera tout sauf la limite supérieure de la montagne (la ligne "chapeau chinois"). C'est vous le noyau de convolution. Vous pouvez recadrer (pas redimensionner!) De haut et de bas pour gagner du temps à l'étape suivante.
  2. Utilisez la fonction Convolve de PerlMagick (vous semblez déjà à l'aise avec Perl et ImageMagick) pour convoluer le noyau avec quelques images. Sur l'image résultante, vous devriez voir un pic pointu correspondant à la position "correcte" du noyau (coïncidant avec la montagne dans l'image).
  3. La hauteur relative (au niveau du bruit environnant) de cette pointe sera plus grande lorsque la montagne sera mieux visible. En prenant plusieurs images représentatives, vous pourriez être en mesure de déterminer un seuil qui sépare les bonnes images des mauvaises. Quoi que vous fassiez, il y aura des faux positifs et des faux négatifs. Soyez prêt.
+0

Merci pour le guide étape par étape. Ceci est vraiment utile pour le niveau auquel je suis. Cependant, je suis un peu incertain comment fonctionne l'étape 2 - comment puis-je passer l'image «noyau» à la fonction Convolve - il semble prendre uniquement une matrice de coefficients? –

+0

@Gavin: Kernel == matrice.J'ai essayé de trouver une explication appropriée des circonvolutions en ligne pour vous, mais je n'ai rien trouvé - peut-être que vous devriez essayer vous-même. – AVB

+0

Après beaucoup de piratage, j'ai utilisé $ test_image-> GetPixels() comme coefficients - est-ce valable? J'ai mis à jour le poste à nouveau. –

Questions connexes