python - 用 Python 堆叠天文图像

标签 python image python-imaging-library astronomy color-depth

我认为这会更容易,但过了一段时间我终于放弃了,至少几个小时......

我想从一组延时摄影中重现这张尾随的星星图像。受此启发: Inspiration

The original author使用通过 VirtualDub 拍摄并与 imageJ 结合的低分辨率视频帧。我想我可以很容易地重现这个过程,但使用 Python 的方法更注重内存,所以我可以使用 the original high-resolution images以获得更好的输出。

我的算法思路很简单,一次合并两张图片,然后通过合并得到的图片和下一张图片进行迭代。这样做了数百次,并对其进行了适当的权衡,以便每张图像对最终结果都有相同的贡献。

我对 python 还很陌生(而且我不是专业的程序员,这很明显),但是环顾四周,在我看来 Python Imaging Library 是非常标准的,所以我决定使用它(纠正我如果您认为其他东西会更好)。

这是我目前所拥有的:

#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 x 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) 组合之前将它们相乘来使图像“不那么暗”,但结果同样糟糕)

最佳答案

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

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

关于python - 用 Python 堆叠天文图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9251580/

相关文章:

python - 这个python图像模糊函数有什么问题?

python - Tkinter ttk 背景样式的自定义未显示

python - 通过 ssh 打开另一个处理程序到 python 中的远程主机

java - 如何在下载图像之前确定图像大小和尺寸

java.lang.OutOfMemoryError : Failed to allocate a allocation until OOM 错误

Javascript:在页面上多次更改 <a href> 以匹配 <img src>

python - 在 Windows 上的 Django 应用程序中使用 PIL 时遇到问题

python - 为什么在Pillow-python中调整图像大小会删除Image.format?

javascript - 显示由 python pillow 模块生成的字节的图像

python - 计算并了解 Pandas 中哪些列缺少值的替代方法