Identificación automática de imágenes de la suerte para fotografía de paisaje.

Recientemente hice una prueba de un proyecto para fotografiar una determinada zona de escalada en roca desde una variedad de direcciones. Tomé fotos en un par de momentos diferentes del día desde el mismo lugar, probé diferentes exposiciones y tomé 16 fotos para las configuraciones que parecían las mejores. El mejor golpe de la mejor sesión fue este(miniatura abajo). Originalmente había pensado que intentaría apilar imágenes, pero el resultado de apilar las 16 tomas parecía peor (menos detalle) que la mejor toma individual. La turbulencia atmosférica era claramente visible a través de la lente, cuando el cálido sol de la tarde golpeaba el lado oeste de la roca. Aunque obtuve algunas tomas por la mañana con luz indirecta, en realidad mostraban menos detalles debido a la falta de sombras y contraste, y los niveles de luz más bajos. No hay una ubicación desde la que pueda obtener la perspectiva correcta de mi sujeto desde cerca, por lo que todas mis imágenes tendrán que tomarse con una lente de 135 mm o 300 mm desde lejos.

Roca Tahquitz

¿Hay alguna forma de automatizar el proceso de buscar las imágenes de la suerte de un conjunto de fotos de paisajes como este? Dado que las personas que obtienen imágenes afortunadas con fotografía astronómica a veces hacen cientos de tomas, asumo que automatizan esto de alguna manera, pero no sé si los algoritmos que usan son apropiados para la fotografía de paisajes. Este proyecto implicará mucho manejo y caminatas, por lo que estaría feliz de tomar cientos de exposiciones seguidas si es probable que sea útil. Estoy buscando una solución de código abierto que funcione en Linux, preferiblemente algo que pueda hacer desde la línea de comandos.

¿O es probable que obtenga mejores resultados usando una técnica de video? Impresionantes resultados se describen aquí . Pero parece que para hacer esto necesitas poder disparar alrededor de 10 cuadros por segundo, y no he descubierto si mi cámara puede hacer esto. (Tengo una Fuji x-e1.)

[EDITAR] Habiendo buscado un poco más en la web, creo que tengo algunas respuestas parciales a mi propia pregunta. (1) Todos los astrónomos aficionados que usan imágenes de la suerte parecen estar usando Windows y distribuyendo software de Windows "shareware". (2) En realidad, todas las técnicas astronómicas implican elegir una "estrella de referencia", que se supone que es una fuente puntual. Si tiene una estrella de referencia de este tipo, entonces es bastante trivial obtener una medida de la calidad de la imagen. Uno común parece ser el índice de Strehl, que es básicamente la intensidad máxima de la imagen de su estrella de referencia. Entonces, si estas impresiones son correctas, entonces puede tener sentido para mí intentar implementar mi propio algoritmo de selección de imágenes para paisajes.

Es posible que deba definir exactamente lo que quiere decir con "suerte"... Ese es un término bastante vago que no tiene una asignación inmediata a las cualidades técnicas de una imagen... Sospecho que lo que está imaginando va a ser muy subjetivo.
@twalberg: Me refiero a este tipo de cosas: en.wikipedia.org/wiki/Lucky_imaging Hasta donde yo sé, "imagen de la suerte" es el término estándar. Supongo que los algoritmos utilizados para seleccionar imágenes de la suerte de grandes conjuntos incorporan una noción relativamente bien definida de "suerte", pero no sé cuál es esa noción, o si es tan apropiada para los paisajes como para la astronomía. Esa es esencialmente mi pregunta.
Ah... No estaba familiarizado con el término, nunca había sumergido mis dedos de los pies en el estanque de la astrofotografía todavía... Sin embargo, después de leer eso, lo primero que me viene a la mente serían algunas de las herramientas que incluye ImageMagick para comparar imágenes: puede comparar cada par de imágenes y usar algún tipo de métrica (RMS o algo similar) agrupar las imágenes para poder elegir un lote que sea "más similar" según esa métrica ... No muy automatizado listo para usar , pero no debería ser demasiado difícil hacer un poco de pegamento de shell o python para unirlo...
Lo que hice subjetivamente con mis imágenes fue elegir una determinada característica de la roca que tenía una característica nítidamente definida y de alto contraste, y simplemente acerqué cada imagen y busqué cuáles mostraban esa imagen con mayor nitidez. Cuando revisé otras partes de la imagen, parecía que era consistente.
@twalberg: podría comparar cada par de imágenes y usar algún tipo de métrica (RMS o algo similar) agrupar las imágenes para poder elegir un lote que sea "más similar" según esa métrica Sí, se me ocurrió esa idea, pero luego creo que podría encontrar que las peores imágenes eran similares a las peores. Otra posibilidad podría ser tomar una FFT y buscar un espectro de potencia con muchas frecuencias altas, o tal vez simplemente tomar el valor RMS del laplaciano discreto. Pero estoy seguro de que no soy el primero en pensar en esto, y prefiero no reinventar la rueda.
La técnica de video a la que se vinculó funcionaría igual de bien con fotografías. La única diferencia es que el tiempo de cómputo del registro de cada foto probablemente sería cuadráticamente más largo que el tiempo de cómputo del registro de cada cuadro de video (simplemente en virtud de que las fotografías tienen una resolución mucho mayor que el video). Pero la técnica sigue siendo la misma. No veo la necesidad de disparar > 10 fps.
Probablemente sería mejor disparar a una velocidad de fotogramas más baja. Eso le permitiría tener más variedad en las condiciones atmosféricas durante un período de tiempo más largo para la misma cantidad de fotogramas.
@MichaelClark: Los 10 fotogramas por segundo no son lo rápido que estoy disparando. Es lo rápido que creo que probablemente tengas que disparar para usar la técnica de video descrita en el enlace. Si entiendo correctamente, esa técnica explota la correlación de un cuadro al siguiente.
@BenCrowell Mi comentario fue una respuesta al de scottbb.
La imagen a la que se vinculó en wikimedia no se ve tan mal. ¿Disparaste en raw o jpeg? Además, ¿exactamente qué lentes estás usando?
@MikeDixon: Gracias :-) Lo hice en formato JPG, con un catadióptrico de 300 mm f/7, desde una distancia de 4,8 km. El único procesamiento posterior digital fue el recorte y una leve mejora del contraste.
Creo que si se filmó en bruto y se procesó mejor, se podría lograr un mejor resultado. Además, disparar con una lente mejor ayudaría bastante. Como dije antes, la imagen no es horrible, pero probablemente le vendría bien un poco de desempañado, claridad y nitidez. Incluso en jpeg pude hacer que se viera mucho mejor.
La técnica de video en el documento vinculado utiliza imágenes tomadas con una resolución sustancialmente menor que VGA en comparación con la resolución de 12mp del cuadro vinculado. Basado en el artefacto de color en el ejemplo de un solo color, puede ser más adecuado para video monocromático que para color.
@BenCrowell No creo que la técnica explote el tiempo o la correlación de cuadro a cuadro. Incluso si lo hiciera, estoy absolutamente seguro de que la técnica podría adaptarse al registro de filtro mediano, para permitir una temporización entre fotogramas básicamente arbitraria (dentro de los límites de los cambios de contenido debido a la iluminación por el ángulo del sol, etc.). La razón por la que confío en eso es porque he escrito un código para hacer algo muy similar al enfoque vinculado. El tiempo entre fotogramas no era una restricción (el vídeo era la fuente, que tenía un Δt implícito, pero no era un factor en los cálculos).
@MichaelClark Ciertamente hay algo de valor en disparar a una velocidad de fotogramas alta, pero no creo que sea absolutamente necesario. Es más una situación de "más información es algo bueno". Pero desde un punto de vista estocástico, es posible que tenga razón: un intervalo de muestreo más largo probablemente suavizaría las variaciones atmosféricas.

Respuestas (3)

Esta no es una respuesta definitiva a mi propia pregunta, pero es demasiado larga para un comentario.

Implementé la idea de usar el RMS Laplacian. La idea es que si el brillo de la imagen está representado por una matriz de píxeles a[i,j], entonces en cualquier punto (i,j), tenemos la aproximación discreta al Laplaciano L=a[i-1, j]+a[i+1,j]+a[i,j-1]+a[i,j+1]-4a[i,j]. Esto mide la nitidez de las características de la imagen. Por ejemplo, si la imagen estuviera desenfocada, L sería menor. El valor RMS del Laplaciano, R, es la raíz cuadrada de la media del cuadrado del Laplaciano.

Aquí está mi código que calcula R para una imagen PNG de entrada:

#!/usr/bin/ruby

# To batch convert a bunch of JPGs to png:
# perl -e '$i=0; foreach $f(<*.JPG>) {$s=sprintf("%03d",$i); $c="convert $f $s.png"; print "$c\n"; system($c); $i=$i+1;}'

require 'oily_png'

# require 'hsluv'
  # http://www.hsluv.org
  # https://github.com/hsluv/hsluv-ruby
  # sudo gem install hsluv

# Sloppy and probably not physiologically valid, but fast.
# Returns an integer from 0 to 255*3.
def color_to_brightness(c)
  return ChunkyPNG::Color::r(c)+ChunkyPNG::Color::g(c)+ChunkyPNG::Color::b(c)
end


def rms_laplacian_from_file(input_file)
  image = ChunkyPNG::Image.from_file(input_file)
  n = 0
  sum = 0
  sum_sq = 0
  w = image.width
  h = image.height
  1.upto(w-2) { |i|
    ### if i%1000==0 then print "i=#{i}\n" end # show progress
    next unless i>w/3 && i<(2*w)/3 ## for efficiency, only use center of frame
    1.upto(h-2) { |j|
      next unless j>h/3 && j<(2*h)/3 ## for efficiency, only use center of frame
      next unless rand(10)==0 # for efficiency
      a = Hash.new
      (-1).upto(1) { |k|
        (-1).upto(1) { |l|
          c = image[i+k,j+l] # color, represented as a 4-byte rgba value
          a[[k,l]] = color_to_brightness(c)
        }
      }
      laplacian = a[[1,0]]+a[[-1,0]]+a[[0,1]]+a[[0,-1]]-4*a[[0,0]]
      n = n+1
      sum = sum + laplacian
      sum_sq = sum_sq + laplacian*laplacian
    }
  }
  sum = sum.to_f/n
  sum_sq = sum_sq.to_f/n
  rms = Math::sqrt(sum_sq-sum*sum)
  return rms
end

ARGV.each { |input_file|
  rms = rms_laplacian_from_file(input_file)
  print "#{input_file} -- rms=#{rms}\n"
}

Esto se implementa en Ruby y se ejecuta en Linux utilizando la biblioteca oily_png de código abierto. Si alguien está interesado en probarlo, no debería requerir casi ninguna modificación para ejecutarse en otras plataformas, si tiene Ruby y oily_png instalados.

Para probar que mide la nitidez, tomé la primera imagen de mi conjunto de 16, medí R y luego agregué un desenfoque gaussiano de 5 píxeles usando GIMP y volví a medir R. El resultado fue R = 30.8 antes del desenfoque, y R =7,8 después. Así que esto parece confirmar que mide la nitidez.

Mis 16 imágenes están numeradas del 000 al 015. Mirando las imágenes a simple vista, previamente había seleccionado la imagen 003 como la mejor. Esa fue la imagen a la que publiqué un enlace en la pregunta.

Ejecuté mi código en las 16 tomas que había tomado y obtuve el siguiente resultado:

000.png -- rms=30.809465960392004
001.png -- rms=31.215359700578606
002.png -- rms=31.909926250066476
003.png -- rms=31.83243374839454
004.png -- rms=31.310612756003305
005.png -- rms=30.353258897447564
006.png -- rms=30.61244684985801
007.png -- rms=30.882745734215135
008.png -- rms=28.667104210689384
009.png -- rms=29.862966602367973
010.png -- rms=29.72001987743495
011.png -- rms=30.51274847773823
012.png -- rms=30.84316910530572
013.png -- rms=29.21751498027252
014.png -- rms=29.067434969521976
015.png -- rms=30.831305018709617

De las 16 imágenes, mi elección tuvo el segundo valor R más alto. Esto parecería confirmar que esta estadística podría ser útil como alternativa a inspeccionar imágenes y juzgarlas subjetivamente a simple vista.

Mi implementación es bastante lenta y, para compensarlo, hice algunas cosas para mejorar su rendimiento. Solo inspecciono la mitad del campo y solo muestro el Laplaciano en 1/10 de los puntos. En una implementación más optimizada, estos atajos podrían eliminarse si se desea.

Más tarde se me ocurrió que podría haber una forma mucho más sencilla de hacer esto. Una imagen con más detalles no debería comprimirse tan bien, por lo que el archivo JPG más grande podría ser simplemente el mejor. Efectivamente, hacer un ls -lS para enumerar los archivos en orden de tamaño decreciente dio una lista que estaba casi en el mismo orden que los archivos ordenados por R decreciente:

-rw-rw-r-- 1 bcrowell bcrowell 16970354 Oct 25 15:48 003.png
-rw-rw-r-- 1 bcrowell bcrowell 16927174 Oct 25 15:48 002.png
-rw-rw-r-- 1 bcrowell bcrowell 16903104 Oct 25 15:48 004.png
-rw-rw-r-- 1 bcrowell bcrowell 16882373 Oct 25 15:47 000.png
-rw-rw-r-- 1 bcrowell bcrowell 16861082 Oct 25 15:47 001.png
-rw-rw-r-- 1 bcrowell bcrowell 16817527 Oct 25 15:48 006.png
-rw-rw-r-- 1 bcrowell bcrowell 16816529 Oct 25 15:49 011.png
-rw-rw-r-- 1 bcrowell bcrowell 16793982 Oct 25 15:49 012.png
-rw-rw-r-- 1 bcrowell bcrowell 16786443 Oct 25 15:48 009.png
-rw-rw-r-- 1 bcrowell bcrowell 16773575 Oct 25 15:48 005.png
-rw-rw-r-- 1 bcrowell bcrowell 16771759 Oct 25 15:49 010.png
-rw-rw-r-- 1 bcrowell bcrowell 16765674 Oct 25 15:48 007.png
-rw-rw-r-- 1 bcrowell bcrowell 16764562 Oct 25 15:49 015.png
-rw-rw-r-- 1 bcrowell bcrowell 16750179 Oct 25 15:48 008.png
-rw-rw-r-- 1 bcrowell bcrowell 16732854 Oct 25 15:49 013.png
-rw-rw-r-- 1 bcrowell bcrowell 16684073 Oct 25 15:49 014.png
Buen trabajo. Lo que encuentro interesante y consistente con la práctica no cuantitativa convencional es que las imágenes de la primera toma son las mejores imágenes (según los criterios). Tal vez esto fue solo suerte. Tal vez fue solo un juicio fotográfico ordinario sobre cuándo cerrar el obturador. Un gráfico podría ayudar.
En términos de compresión, más ruido aleatorio dará como resultado archivos más grandes y ese ruido puede estar en uno o varios de los canales de color en lugar o además del canal de luminancia sobre el que opera el algoritmo. Con valores ISO bajos y sujetos bien iluminados, es menos probable que esto sea un problema... aunque elegir sujetos adecuados cuando se aplica el tamaño del archivo como indicador de nitidez es quizás una cuestión de juicio fotográfico.

¿Hay alguna forma de automatizar el proceso de buscar las imágenes de la suerte de un conjunto de fotos de paisajes como este?

Según tengo entendido, su definición de "imagen de la suerte" es más nítida que el promedio. Dado que muchas cámaras utilizan la medición de la nitidez de (una región de) una imagen en sus mecanismos de enfoque automático 1 , está claro que existe alguna forma de automatizar su medición. Sin embargo, las ventajas de los diferentes enfoques y la posibilidad de combinarlos es un tema de investigación activa, por lo que no puede esperar una respuesta definitiva. Por ejemplo , algoritmo robusto de enfoque automático para imágenes de bajo contraste utilizando una nueva medida de contraste , Jinshan Tang et. al., Sensors (2011) dice que

Se han utilizado muchas medidas de contraste para el AF pasivo... Los resultados indican que los métodos de medición espacial 2D como Tenengrad, detección de bordes Prewitt y Laplacian ofrecen el mejor rendimiento en términos de precisión y unimodalidad. Sin embargo, son muy sensibles al ruido y no son resistentes a las diferentes condiciones de la escena, como las condiciones de poca luz.

Por el contrario, los métodos basados ​​en la varianza son rápidos y robustos. La idea básica es calcular la varianza de la intensidad de la imagen. La imagen se enfoca mejor cuando la variación alcanza un máximo. Un método típico en el dominio de la transformada de coseno discreta (DCT) es calcular los coeficientes de CA de las imágenes, que también se pueden usar para representar información sobre la función de varianza de la luminancia.

Dado que no está limitado al rendimiento en tiempo real en un procesador de baja potencia en la cámara, probablemente podría implementar múltiples enfoques e intentar combinar sus puntajes. Usted habla de apilar, así que asumo que tiene varias tomas tomadas desde la misma posición en aproximadamente las mismas condiciones de luz: podría valer la pena pensar en unir en lugar de apilar, de modo que seleccione la foto que tenga el mejor contraste en un área, y la foto que tiene el mejor contraste en otra, y unirlas. No estoy seguro de hasta qué punto el software de costura existente admite este tipo de puntada de selección de contraste.


1 Para ser precisos, aquellos que utilizan el enfoque automático de detección de contraste en lugar del enfoque automático de detección de fase. Y sí, sé que las DSLR con vista en vivo usan PDAF con el espejo hacia abajo y CDAF en vista en vivo.

Probablemente esto esté demasiado lejos para ser de mucho interés, pero: el laplaciano en una dimensión aumenta el contenido de alta frecuencia al multiplicar el espectro de Fourier por el cuadrado de la frecuencia. (Espero haberlo hecho bien). Por lo tanto, amplifica el ruido y la señal. Podría ser interesante ver si un detector de bordes podría extraer características de interés. Dado un detector de bordes en particular, tal vez la foto con la longitud total del borde más larga sea de interés. Esto podría ser solo una persecución, pero ¿quizás no?