2012-02-12 21 views
17

堆疊天文圖片我認爲這將是更容易,但一段時間後,我終於放棄了這一點,至少在幾個小時......與Python

我想重現此尾隨從timelapse套圖片的星形圖象。受此啓發: Inspiration

The original author使用了VirtualDub拍攝的低分辨率視頻幀並與imageJ結合使用。我想我可以很容易地重現這個過程,但是使用Python的更有記憶力的方法,所以我可以使用the original high-resolution images來獲得更好的輸出。

我的算法思路很簡單,一次合併兩個圖像,然後通過將生成的圖像與下一個圖像合併進行迭代。這樣做了幾百次,並適當權衡,以便每個圖像對最終結果具有相同的貢獻。我對Python很新穎(而且我不是專業的程序員,這很明顯),但是在我看來,Python成像庫是非常標準的,所以我決定使用它(正確的如果你認爲別的會更好的話)。

這是我到目前爲止有:

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

這做什麼它應該,但產生的圖像是暗的,如果我只是一味的提升呢,很明顯這些信息被丟失,由於缺乏深度以像素值表示。 (我不確定此處的適當術語是什麼,顏色深度,顏色精度,像素大小)。 下面是使用低分辨率圖像的最終結果:

Low resolution result

或一個我一直在與2K分辨率的全4K嘗試(從另一組照片):

High resolution result with another set of images

所以,我試圖通過設置圖像模式來修復它:

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

但顯然Image.blend d oes不接受該圖像模式。

ValueError: image has wrong mode

任何想法?

(我也試圖將它們與im.point合併之前使圖像「少暗」乘以它(拉姆達我:我* 2),但結果一樣糟糕)

+1

您的圖像的權重並不相同。例如,您的第一張圖片的不透明度爲1 /(1 + 1)= 0.5,而您的第9張圖片的不透明度爲0.1。 – Blender 2012-02-12 19:00:05

+1

攪拌機,我認爲它是同等重量。當i = 0時,1 /(i + 1)= 1,則對於第一次迭代,圖像具有0.5的權重,因爲另一個0.5被第二圖像(文件[1])取得,並且當i = 2 ,文件[2]的權重爲0.33,前兩者合計爲0.66,即0.33。所以第9張圖像確實有0.1個alpha,但這意味着前8個圖像的組合不透明度爲0.9,即每個圖像0.1(考慮文件[0])。 – JunCTionS 2012-02-12 19:12:48

+3

不,@Blender是對的,你需要每個圖像*的恆定權重,意思是'1/len(files)'。如果您總共有2張圖片,則每張圖片的重量爲0.5。如果總共有10張圖像,則每張圖像的重量爲0.1。 – 2012-02-12 23:41:50

回答

20

這裏的問題是,你正在平均每個像素的亮度。這看起來很合理,但實際上並不是你想要的 - 明亮的恆星會因爲它們在圖像上移動而「平均」。看看下面的四個幀:

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

如果你平均的,你會得到:

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

當你想:

1000 
0100 
0010 
0001 

而是融合,你可以嘗試拍攝的圖像在每個像素的任何圖像中最大可見。如果你有PIL,你可以嘗試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") 

這裏是我的了: Low res image set stacked

編輯:我讀了reddit的帖子,看到他實際上結合了兩種方法 - 一個用於星跡和另一個用於地球。這裏有一個更好的實施平均你嘗試,適當的權重。我使用了一個numpy數組來存儲中間存儲,而不是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') 

這裏是圖像,然後你可以結合前一個星形軌跡。 Low res images added together

+1

太棒了!非常感謝你。 [1]:http:// i(圖片來源:http://i.imgur.com/P9mzc.jpg) (儘管由imgur的尺寸限制降低了一點) .imgur.com/P9mzc.jpg – JunCTionS 2012-02-13 10:52:15

+0

@JUNCTionS不用擔心,看起來非常好。我實際上閱讀了Reddit的評論,他做了和我爲明星小道所建議的一樣的事情,但是像你原先對地球的平均方法一樣。我會快速解決這個問題,並將其添加爲編輯。 – simonb 2012-02-14 04:34:41