2012-02-12 14 views
17

ho pensato che questo sarebbe stato più facile, ma dopo un po 'sono finalmente rinunciare a questo, almeno per un paio d'ore ...immagini astronomia impilabile con Python

ho voluto riprodurre questo un finale stelle l'immagine di una serie di immagini timelapse. Ispirato da questo: Inspiration

The original author utilizzato frame video a bassa risoluzione presi con VirtualDub e combinati con imageJ. Ho immaginato di poter riprodurre facilmente questo processo, ma con un approccio più attento alla memoria con Python, così ho potuto usare the original high-resolution images per un risultato migliore.

L'idea del mio algoritmo è semplice, unendo due immagini alla volta e quindi iterando unendo l'immagine risultante con l'immagine successiva. Questo è stato fatto centinaia di volte e correttamente pesato in modo che ogni immagine abbia lo stesso contributo al risultato finale.

Sono abbastanza nuovo per Python (e non sono un programmatore professionista, sarà evidente), ma guardandomi attorno mi sembra che la libreria di immagini Python sia molto standard, quindi ho deciso di usarla (correggere se pensi che qualcos'altro sarebbe meglio).

Ecco quello che ho finora:

#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") 

Questo fa quello che si suppone, ma l'immagine risultante è buio, e se ho semplicemente cerco di valorizzarlo, è evidente che l'informazione è stata persa a causa mancanza di profondità nei valori del pixel. (Non sono sicuro di quale sia il termine corretto, profondità del colore, precisione del colore, dimensioni dei pixel). Ecco il risultato finale con immagini a bassa risoluzione:

Low resolution result

o uno cercavo con la piena 4k da 2k risoluzione (da un altro insieme di foto):

High resolution result with another set of images

Quindi, ho cercato di risolvere il problema impostando la modalità immagine:

firstimage=Image.open("./"+files[0]) 
size = firstimage.size 
finalimage=Image.new("I",size) 

ma a quanto pare Image.blend d o non accetta quella modalità immagine.

ValueError: image has wrong mode

Qualche idea?

(ho anche provato a fare le immagini "meno oscuro" moltiplicandolo prima di loro combinazione con im.point (lambda I: i * 2), ma i risultati sono stati altrettanto male)

+1

Le immagini non sono ugualmente ponderate. Ad esempio, la tua prima immagine ha opacità '1/(1 + 1) = 0.5', mentre la tua nona immagine ha opacità' 0.1'. – Blender

+1

Blender, penso che sia ugualmente ponderato. quando i = 0, 1/(i + 1) = 1, quindi per la prima iterazione l'immagine ha un peso di 0.5 perché l'altra 0.5 è presa dalla seconda immagine (file [1]), e quindi quando i = 2 , il file [2] ha un peso di 0,33, lasciando i primi due combinati con un totale di 0,66 .. cioè 0,33 ciascuno. Quindi la nona immagine ha effettivamente 0.1 alfa, ma ciò significa che i primi 8 hanno un'opacità combinata di 0,9, cioè 0,1 per immagine (considerando il file [0]). – JunCTionS

+3

No, @Blender ha ragione, è necessario un * peso costante per ogni immagine *, che significa '1/len (file)'. Se hai 2 immagini in totale, ogni immagine diventa 0.5. Se hai 10 immagini in totale, ciascuna immagine assume il peso 0.1. –

risposta

20

Il problema qui è che si stanno calcolando la media della luminosità su ciascun pixel. Questo può sembrare sensato ma in realtà non è quello che vuoi tu - le stelle luminose otterranno una "media via" perché si muovono attraverso l'immagine. Prendere le seguenti quattro fotogrammi:

1000 0000 0000 0000 
0000 0100 0000 0000 
0000 0000 0010 0000 
0000 0000 0000 0001 

Se si calcola la media quelli, si otterrà:

0.25 0 0 0 
0 0.25 0 0 
0 0 0.25 0 
0 0 0 0.25 

Quando si desidera:

1000 
0100 
0010 
0001 

Invece di mescolare le immagini è possibile provare a prendere il massimo visto in qualsiasi immagine per ogni pixel.Se hai PIL puoi provare la funzione più leggera in 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") 

Ecco cosa ho ottenuto: Low res image set stacked

EDIT: Ho letto il post su Reddit e vedo che lui in realtà combina due approcci - uno per le tracce della stella e una diversa per la Terra . Ecco una migliore implementazione della media che hai provato, con una corretta ponderazione. Ho usato una matrice numpy per lo storage intermedio invece dell'array uint8 Image.

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') 

Ecco l'immagine, che è quindi possibile combinare con le tracce stella del precedente. Low res images added together

+1

Grande !! Grazie mille. [Ecco il risultato finale con le immagini a grandezza originale originale] (http://i.imgur.com/P9mzc.jpg) (anche se un po 'declassato dalle limitazioni di dimensione di imgur) [1]: http: // i .imgur.com/P9mzc.jpg – JunCTionS

+0

@JunCTionS Nessun problema, sembra davvero buono. In realtà ho letto il commento di Reddit e lui ha fatto la stessa cosa che ho suggerito per le tracce delle stelle, ma qualcosa come il tuo approccio mediano originale per la terra. Avrò un rapido crack e aggiungerlo come edit. – simonb

Problemi correlati