2010-03-27 9 views
27

El problemaEn una fotografía digital, ¿cómo puedo detectar si una montaña está oscurecida por las nubes?

que tienen una colección de fotos digitales de a mountain en Japón. Sin embargo, la montaña a menudo está oscurecida por nubes o niebla.

¿Qué técnicas puedo usar para detectar que la montaña es visible en la imagen? Actualmente estoy usando Perl con el módulo Imager, pero estoy abierto a otras alternativas.

Todas las imágenes se toman desde la misma posición exacta - estas son algunas muestras.

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

Mi solución ingenua

Empecé tomando varias muestras de píxeles horizontales del cono de la montaña y la comparación de los valores de brillo a otras muestras del cielo. Esto funcionó bien para distinguir buena imagen 1 y mala imagen 2.

Sin embargo, en el otoño nevó y la montaña se hizo más brillante que el cielo, como la imagen 3, y mi prueba de brillo simple comenzó a fallar.

La imagen 4 es un ejemplo de una carcasa de borde. Clasificaría esto como una buena imagen ya que parte de la montaña es claramente visible.

ACTUALIZA 1

Gracias por las sugerencias - Estoy feliz de que todo muy sobreestimada mi competencia.

Basado en las respuestas, he comenzado a probar la transformación ImageMagick edge-detect, lo que me da una imagen mucho más simple de analizar.

convert sample.jpg -edge 1 edge.jpg 

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

Asumo que debería utilizar algún tipo de enmascaramiento para deshacerse de los árboles y la mayoría de las nubes.

Una vez que tengo la imagen enmascarada, ¿cuál es la mejor manera de comparar la similitud con una "buena" imagen? Supongo que el comando "compare" es adecuado para este trabajo? ¿Cómo obtengo un valor de 'similitud' numérico de esto?

ACTUALIZACIÓN 2

Creo que puede llegar a alguna parte con la convolución.

Hice mi imagen 'kernel' (parte superior de la imagen a continuación) realizando detección de bordes en una buena imagen. Luego apagué todo el 'ruido' alrededor del contorno de la montaña y luego lo recorté.

Luego utiliza el siguiente código:

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

me encontré con esto para diversas imágenes de la muestra, y me dieron los resultados de la siguiente manera (se muestra la imagen convuelta debajo de cada muestra):

(Lo siento - ¡diferentes imágenes de muestra de la última vez!)

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

Ahora estoy tratando de cuantificar la 'ridgy' es una imagen. Traté de tomar la imagen de brillo medio:

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

Pero esto da no da valores significativos (0,0165, 0,0175 y 0,0174). ¿Alguna mejor manera?

+4

+1 muy bien presentado pregunta – msw

+1

Está subestimando su propia competencia. Ese enlace para "comparar" en la Actualización 1 tiene varios enfoques muy buenos para generar un grado de medida de similitud a través de la convolución, como sugirió Marcelo. Supongo que estás jugueteando con esos mientras escribo. – msw

Respuesta

9

Creo que está trabajando en un nivel demasiado bajo. Un pase rápido a través de un filtro de detección de bordes particionó la imagen configurada muy claramente en (1, 3) y (2, 4). Especialmente si estas imágenes provienen de un punto de vista fijo de la cámara, encontrar una coincidencia con la forma prototípica en (1) sería relativamente fácil algorítmicamente. Incluso su caso de (4) podría darle un dominio de coincidencia parcial que podría determinar heurísticamente si había suficiente montaña para considerar.

+0

Gracias: comencé a jugar con edge detect y actualicé la pregunta. Todavía está un poco atascado en cómo cuantificar cuánta montaña hay. –

4

La respuesta depende de qué tan específico es el problema. Si se trata de la misma montaña desde el mismo punto de vista, ejecute la detección de bordes contra una buena imagen conocida y utilícela como línea base para la convolución contra las imágenes detectadas en el borde del corpus. Si solo le interesa el borde de la montaña, elimine manualmente otras características de la línea base.

+1

Gracias. Por suerte, el problema es muy específico: el punto de vista es fijo. La detección de bordes parece ser el lugar correcto para comenzar. No estoy seguro de la parte de la convulsión. –

+0

(Disculpa la respuesta diferida, zona horaria diferente). La convolución de dos imágenes exhibirá picos que indican algún tipo de similitud. Si todo lo que quiere saber es si hay suficiente montaña visible, calcule la convolución entre una imagen que contiene solo el borde de la montaña y la imagen que está probando. Un fuerte pico cerca del centro de la imagen lo dirá todo. –

5

Algunas recomendaciones específicas, basándose en lo que tienes ya:

  1. Tome su mejor imagen (algo así como la imagen 1), que se ejecutan a través de la detección de bordes, abrir el resultado en cualquier editor gráfico (EM La pintura lo hará) y limpiar todo excepto el límite superior de la montaña (la línea "sombrero chino"). Este es tu kernel de convolución. Puede recortarlo (¡no cambiar el tamaño!) Desde arriba y abajo para ahorrar tiempo en el siguiente paso.
  2. Utilice la función Convolve de PerlMagick (parece que ya se siente cómodo con Perl e ImageMagick) para convolucionar el kernel con unas pocas imágenes. En la imagen resultante, debe ver una punta afilada correspondiente a la posición "correcta" del núcleo (coincidiendo con la montaña de la imagen).
  3. La altura relativa (hasta el nivel de ruido ambiental) de este pico será mayor cuando la montaña sea más visible. Al tomar varias imágenes representativas, es posible que pueda determinar un umbral que separe las buenas imágenes de las malas.
  4. Hagas lo que hagas, habrá falsos positivos y falsos negativos. Estar preparado.
+0

Gracias por la guía paso a paso. Esto es realmente útil para el nivel en el que estoy. Sin embargo, estoy un poco inseguro de cómo funciona el paso 2, ¿cómo paso la imagen 'kernel' a la función Convolucionar? Parece que solo toma una matriz de coeficientes? –

+0

@Gavin: Kernel == matrix.He tratado de encontrar una explicación adecuada de las circunvoluciones en línea para ti, pero no he podido encontrar nada; tal vez deberías probarlo tú mismo. – AVB

+0

Después de mucho hackear, utilicé $ test_image-> GetPixels() como coeficientes - ¿es eso válido? Actualicé la publicación nuevamente. –

Cuestiones relacionadas