Apilamiento de imágenes astronómicas con Python.
image python-imaging-library (1)
El problema aquí es que está promediando el brillo en cada píxel. Esto puede parecer sensato, pero en realidad no es lo que quieres en absoluto: las estrellas brillantes se "promediarán" porque se mueven a través de la imagen. Toma los siguientes cuatro cuadros:
1000 0000 0000 0000
0000 0100 0000 0000
0000 0000 0010 0000
0000 0000 0000 0001
Si los promedias, obtendrás:
0.25 0 0 0
0 0.25 0 0
0 0 0.25 0
0 0 0 0.25
Cuando quieres:
1000
0100
0010
0001
En lugar de mezclar las imágenes, puede intentar tomar el máximo visto en cualquier imagen para cada píxel. Si tienes PIL, puedes probar la función más ligera en ImageChops.
from PIL import ImageChops
import os, Image
files = os.listdir("./")
finalimage=Image.open("./"+files[0])
for i in range(1,len(files)):
currentimage=Image.open("./"+files[i])
finalimage=ImageChops.lighter(finalimage, currentimage)
finalimage.save("allblended.jpg","JPEG")
Aquí está lo que tengo:
EDITAR: Leí la publicación de Reddit y vi que en realidad combinó dos enfoques, uno para los senderos de las estrellas y otro para la Tierra. Aquí hay una mejor implementación del promedio que ha intentado, con la ponderación adecuada. Utilicé una matriz numpy para el almacenamiento intermedio en lugar de la matriz de imágenes uint8.
import os, Image
import numpy as np
files = os.listdir("./")
image=Image.open("./"+files[0])
im=np.array(image,dtype=np.float32)
for i in range(1,len(files)):
currentimage=Image.open("./"+files[i])
im += np.array(currentimage, dtype=np.float32)
im /= len(files) * 0.25 # lowered brightness, with magic factor
# clip, convert back to uint8:
final_image = Image.fromarray(np.uint8(im.clip(0,255)))
final_image.save(''all_averaged.jpg'', ''JPEG'')
Aquí está la imagen, que luego podrías combinar con los rastros de estrellas del anterior.
Pensé que esto iba a ser más fácil, pero después de un tiempo finalmente voy a renunciar a esto, al menos por un par de horas ...
Quería reproducir esta imagen de estrellas finales a partir de un conjunto de imágenes de lapso de tiempo. Inspirado por esto:
El autor original usó cuadros de video de baja resolución tomados con VirtualDub y combinados con imageJ. Imaginé que podría reproducir fácilmente este proceso pero con un enfoque más consciente de la memoria con Python, así que podría usar las imágenes originales de alta resolución para una mejor salida.
La idea de mi algoritmo es simple, fusionar dos imágenes a la vez y luego iterar combinando la imagen resultante con la siguiente imagen. Esto se hace cientos de veces y se pesa adecuadamente para que cada imagen tenga la misma contribución al resultado final.
Soy bastante nuevo en Python (y no soy un programador profesional, eso será evidente), pero al mirar alrededor, me parece que la Python Imaging Library es muy estándar, así que decidí usarlo (corríjame si lo cree). otra cosa sería mejor).
Esto es lo que tengo hasta ahora:
#program to blend many images into one
import os,Image
files = os.listdir("./")
finalimage=Image.open("./"+files[0]) #add the first image
for i in range(1,len(files)): #note that this will skip files[0] but go all the way to the last file
currentimage=Image.open("./"+files[i])
finalimage=Image.blend(finalimage,currentimage,1/float(i+1))#alpha is 1/i+1 so when the image is a combination of i images any adition only contributes 1/i+1.
print "/r" + str(i+1) + "/" + str(len(files)) #lousy progress indicator
finalimage.save("allblended.jpg","JPEG")
Esto hace lo que se supone que debe hacer, pero la imagen resultante es oscura, y si simplemente trato de mejorarla, es evidente que la información se perdió debido a la falta de profundidad en los valores de píxeles. (No estoy seguro de cuál es el término correcto aquí, profundidad de color, precisión de color, tamaño de píxel). Aquí está el resultado final usando imágenes de baja resolución:
o una que estaba intentando con la resolución completa de 4k por 2k (de otro conjunto de fotos):
Entonces, traté de arreglarlo configurando el modo de imagen:
firstimage=Image.open("./"+files[0])
size = firstimage.size
finalimage=Image.new("I",size)
pero al parecer Image.blend no acepta ese modo de imagen.
ValueError: la imagen tiene un modo incorrecto
¿Algunas ideas?
(También intenté que las imágenes fueran "menos oscuras" al multiplicarlas antes de combinarlas con im.point (lambda i: i * 2) pero los resultados fueron igual de malos)