27 votes

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

Le problème

J'ai une collection de photos numériques d' une montagne au Japon. Cependant, la montagne est souvent obscurci par les nuages ou le brouillard.

Quelles sont les techniques que je peux utiliser pour détecter que la montagne est visible dans l'image? Je suis actuellement en utilisant Perl avec l' Imageur module, mais ouvert à d'autres options.

Toutes les images sont prises à partir de la même position - ces quelques exemples.

Sample Images

Ma solution naïve

J'ai commencé par la prise de plusieurs pixel horizontal échantillons de la montagne cône et en comparant les valeurs de luminosité à d'autres échantillons provenant du ciel. Cela a bien fonctionné pour différencier une bonne image 1 et de la mauvaise image 2.

Cependant, à l'automne il a neigé et la montagne devient plus lumineux que le ciel, comme l'image 3, et mon luminosité simple test a commencé à échouer.

Image 4 est un exemple d'un cas limite. Je classerais ce qu'une bonne image depuis quelques de la montagne est clairement visible.

Mise à JOUR 1

Merci pour les suggestions - je suis heureux que vous tous les largement sur-estimé ma compétence.

Sur la base des réponses, j'ai commencé à essayer le ImageMagick bord-détecter les transformer, ce qui me donne beaucoup plus simple de l'image à analyser.

convert sample.jpg -edge 1 edge.jpg

Edge detected samples

Je suppose que je devrais utiliser une sorte de masquage pour se débarrasser de l'arbre et de 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 pense que les "comparer" commande adapté pour ce travail? Comment puis-je obtenir un numérique "similitude" la valeur de tout cela?

Mise à JOUR 2

Je pense que j'ai peut-être trouvé quelque part avec de convolution.

J'ai fait mon 'noyau' de l'image (en haut de l'image ci-dessous) en effectuant bord de détecter sur une bonne image. J'ai ensuite masqués, tout le "bruit" autour de la silhouette de la montagne, et rognée.

Ensuite, j'ai 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 ce pour divers exemples d'images, et j'ai obtenu des résultats comme ci-dessous (l'image convoluée est indiqué en dessous de chaque échantillon):

(Désolé - différents exemples d'images de la dernière fois!)

alt text

Maintenant, je suis en train d'essayer de quantifier comment "ridgy" une image. J'ai essayé de prendre l'image la luminosité moyenne:

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

Mais ce qui donne ne donne pas de valeurs significatives (0.0165, de 0,0175 et 0.0174). Les meilleures façons?

9voto

msw Points 25319

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

5voto

AVB Points 2924

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

  1. Prenez votre meilleure image (quelque chose comme l'image 1), le lancer à travers la détection de contours, ouvrez le résultat dans l'éditeur graphique (MS Paint fera) et propre à tout sauf à la montagne de la limite supérieure (le "chapeau chinois" de ligne). C'est le noyau de convolution. Vous pouvez la recadrer (pas de redimensionner!) à partir de ci-dessus et ci-dessous pour gagner du temps dans l'étape suivante.
  2. Utiliser l' Convolve fonction de PerlMagick (vous semblez déjà à l'aise avec Perl et ImageMagick) pour le noyau de convolution avec un peu d'images. Sur l'image, vous devriez voir une forte hausse correspondant à la "bonne" position du noyau (coïncidant avec la montagne dans l'image).
  3. La relative (par rapport au niveau de bruit ambiant) hauteur de ce pic sera plus grande quand la montagne est plus visible. Par la prise de plusieurs images représentatives que vous pourriez être en mesure de déterminer un seuil pour séparer des images de bonne de la mauvaise.
  4. Quoi que vous fassiez, il y aura des faux positifs et des faux négatifs. Être préparé.

4voto

Marcelo Cantos Points 91211

La réponse dépend de la spécificité du problème. S'il s'agit de la même montagne à partir du même point de vue, exécutez et détectez les contours par rapport à une bonne image connue, et utilisez-la comme ligne de base pour effectuer une convolution contre les images détectées par les contours du corpus. Si ce n'est que le bord de la montagne qui vous intéresse, supprimez manuellement les autres fonctionnalités de la ligne de base.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X