用Python叠加天文图像

2024-04-28 14:47:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我以为这会容易些,但过了一会儿我终于放弃了,至少几个小时。。。

我想从一组永恒的图片中复制出一个尾随的恒星图像。灵感来源: 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

或者一张我尝试的4k分辨率为2k的照片(来自另一组照片):

High resolution result with another set of images

所以,我试图通过设置图像模式来修复它:

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

但显然Image.blend不接受该图像模式。

ValueError: image has wrong mode

有什么想法吗?

(我也尝试过在将图像与im.point(lambda I:I*2)组合之前将其相乘,以使图像“不太暗”,但结果同样糟糕)


Tags: theto图像imagesizelenosfiles
1条回答
网友
1楼 · 发布于 2024-04-28 14:47:00

这里的问题是你在平均每个像素的亮度。这可能看起来很合理,但实际上根本不是你想要的——明亮的恒星会被“平均”掉,因为它们会沿着图像移动。取以下四帧:

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图像数组。

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

相关问题 更多 >