☰
StarNet++实战:用神经网络轻松移除深空照片中的恒星
2026/9/29 18:08:24 网站建设 项目流程

1. 先说清楚:StarNet 到底是干什么的

可能第一次听说 StarNet 的朋友会下意识以为这又是个什么高深框架或平台,实际上它是我最近两年在深空摄影后期里用得最勤的一个神经网络工具,全名一般叫StarNet++。如果只看名字里的“Star”,你可能猜不到它真正干的事情很纯粹:把天文照片里的恒星从画面里“摘”出去,生成一张只有星系、星云、暗尘埃等延展天体的无星版本。

为什么这件事值得专门写一篇完整的技术笔记?因为只要你拍过深空,大概率都经历过这种痛:M31 仙女座星系明明拍了几十张叠加,处理完以后星系盘面细节还可以,但图片上密密麻麻的星点一压亮度就糊,一拉对比度就炸,星点周围还容易拖出奇怪的光晕。这时候最常规的思路是用 Photoshop 或者传统方式慢慢修,要么用星点蒙版一层层抠,费时费力还经常搞出“塑料感”。而 StarNet 直接让神经网络去预测画面里恒星的位置和光强分布,几秒钟就能把恒星和延展天体分离开。

这篇笔记主要写给三类人:一是玩深空摄影、被星点困扰了很久的后期党;二是刚开始接触深度学习但想在图像分割这个方向找个实战案例的学生;三是单纯好奇神经网络如何做像素级分离的吃瓜群众。我会从原理、参数、实操、踩坑四个部分掰开讲,尽量让你看完之后不仅能跑通模型,也能自己判断它的边界在哪。

注意:StarNet 名字在不同领域还有别的同名产品,例如室内定位库、区块链项目,本文只讨论天文图像处理场景下的 StarNet++。

2. StarNet 凭什么能把星星“摘”掉

2.1 它做的不是抠图,而是图像语义分离

很多人第一次拿到 StarNet 的处理结果,第一反应是“这不就是抠图嘛”。确实,从效果上看,它确实把星点从原图中分离出来,输出一张纯背景图和一张纯星点图。但本质上它跟我们手工用套索、魔棒、色彩范围那些完全不是一回事。

手工抠星点的核心逻辑是找边界——你告诉软件哪里是星点边缘,然后软件沿着边缘生成选区。可深空图像里的恒星根本不存在清晰的边界。视宁度、大气色散、望远镜的衍射效应都会让星点变成一个弥散的光斑,光斑和高光附近的星云信号混在一起,边界模糊到没法用“边缘”去定义。

StarNet 的做法是全局预测。它把整张图输入一个卷积神经网络,网络输出的是每个像素属于“恒星辐射”的概率图,然后根据这个概率图把原始图像拆成两个通道:一颗星点干净到可以忽略的延展天体图,以及一张只保留星点光强分布的点源图。换句话说,它不是在找边,而是在理解“哪些光子来自恒星”这个物理过程。

2.2 为什么用神经网络而不是传统算法

传统上,天文学家分离恒星其实有一套成熟办法:先用 PSF(点扩散函数)模型拟合每个星点的光强分布,然后用拟合结果把星点减掉。这个方法在只有几十颗亮星的星场里非常好用,但在深空照片里根本不现实。

我拍一幅 M31,两三百颗能肉眼分辨的星点,还有大量暗到几乎淹没在背景噪声里的低信噪比恒星,PSF 拟合法得逐颗设置初始参数,稍微有点星点重叠或者背景梯度就有大面积残差,算下来可能要忙一晚上。神经网络不一样,它在海量合成图像上学习过“恒星在不同亮度、不同背景、不同噪声水平下长什么样”,一进一出一张图全处理完,速度是传统方法的上百倍。

这里面有一个很关键的设计选择:StarNet 选择在合成数据上训练,而不是真实观测数据。真实照片的“正确答案”根本没法人工标注——你没法手工画出每个像素的光子到底是来自恒星还是星系。合成数据则是一边用点源模型生成无数个形态各异的星点,叠加上已知的延展星云模拟图像和噪声模型。这样训练数据里的“分割真值”是完全精确的,让模型学会了分离而不是死记硬背某一幅图。

2.3 从输入到输出,模型处理的核心细节

从工程实现角度,StarNet 的流程其实很直接。输入一张灰度 FITS(也可以是 TIFF),模型会对每个像素输出一个 0 到 1 之间的权重系数,接近 1 表示该像素大概率属于恒星,接近 0 表示大概率属于延展天体。然后通过一个叫“像素级乘法”的操作:

无星图 = 原图 × (1 − 星点权重) 星点图 = 原图 × 星点权重

注意这个乘法的物理意义:它不仅把星点中心的强信号删除,还在星点周围建立起一圈平滑的过渡带。整张图任意像素的能量都不会凭空消失,两张输出图加起来严格等于原始图像,没有任何信息损失,只是被打散到两个“图层”里了。

这一点的价值在使用中会体现得很明显。因为你拿星点图可以随意做锐化、缩星、加颜色,拿无星图可以放心大幅拉伸对比度而不必担心星点爆掉。处理完以后把两张图叠加回来,输出的结果比原图干净得多。

  • 输入格式:单通道 FITS、TIFF、PNG 都可以
  • 输出通道:星点蒙版(star mask)和无星背景(starless)
  • 模型文件:PyTorch 架构,权重文件需要单独下载

3. 实操:三种最常见的 StarNet 使用方法

3.1 方式一:独立命令行调用

StarNet 最早是以 Python 脚本形式发布的,如果你习惯用终端处理图像,这种方式最灵活。首先把仓库克隆到本地,建一个虚拟环境安装依赖:

git clone https://github.com/starnet-maksymowych/starnet_plusplus.git cd starnet_plusplus python -m venv starnet_env source starnet_env/bin/activate pip install -r requirements.txt

安装完成后,命令行调用语法其实非常直观。以处理一张名叫m31_lum.fits的图像为例:

python starnet.py --input m31_lum.fits --output_dir ./output/ --model_path ./models/starnet_rgb.onnx

跑完之后输出目录里会出现两个文件:m31_lum_starless.fits和m31_lum_starmask.fits。这里有个值得注意的参数:--model_path指向的模型文件有多个版本,常见的是灰度starnet_bw和彩色starnet_rgb两种。灰度版本处理 L 通道快很多,彩色版本适合直接处理单反或冷冻相机的彩色图像。

3.2 方式二:PixInsight 整合工作流

如果你和我一样主力后期工具是 PixInsight,完全不需要绕道命令行。比较省心的做法是直接安装社区打包好的 StarNet 脚本模块。装好之后,在主界面 Process 菜单里就能看到 StarNet 项,双击加载,然后拖到目标图像上即可。

PixInsight 里的流程通常是这样:

  • 把线性图像正确裁剪后,先复制一份,对复制件做一次简单的 MaskedStretch 以增强星点可见度
  • 对拉伸后的图像运行 StarNet,生成星点蒙版
  • 把蒙版拉回图像,你会发现它自动作用于线性图像本身,亮度、星点大小都跟你的预处理状态匹配

这个过程看似只是点了几下鼠标,但有个重要问题:StarNet 对非线性图像的预测效果远好于线性图。因为线性图像里星点核心亮度和周边星云的对比差异太大,神经网络难以准确判断。而经过 MaskedStretch 之后,动态范围被压缩,星点和延展天体的分布更接近模型在合成数据里见过的状态,预测准确率会高很多。

3.3 方式三:Siril 里的轻量集成

还有一部分同好用 Siril 做后期,它从 1.2 版本起也能调用 StarNet。Siril 里的入口在菜单“图像处理—星点移除”下,前提是你提前把 StarNet 的可执行文件路径填进配置里。

我的经验是,Siril 集成适合快速预览,比如你只想看某个目标“去星之后长什么样”,或者对比不同处理路线,就用它直接出一张图。但如果你要做精细合成,还是建议回到 PixInsight 或者命令行,因为 Siril 这个模块暴露的参数很少,中间产物不如前两者可控。

4. 实战记录:以 M31 为例的恒星移除全流程

4.1 素材准备与预处理

这里我拿一张积累约 8 小时曝光的 M31 窄带 L 通道来做示例。头一天拍摄完,我已经用 WBPP 完成了校准、对齐和叠加,最后得到一张线性 FITS。在真正运行 StarNet 之前,我通常还会做两步必要准备:

  • 裁剪掉因为对齐产生的黑边,不然边缘的黑色区域会让神经网络产生误判
  • 用 DBE 做一次背景均匀化处理,去掉轻微的天空梯度,减小背景中的伪造纹理

这两步看起来不起眼,但直接影响后面星点蒙版的质量。如果背景里有明显的梯度或者暗角,网络可能会把部分背景纹理误认为延展天体信号,导致星点图里缺了该剔的东西,无星图里反而留下一些怪异的亮斑。

4.2 星点分离与蒙版检查

对这张 M31 L 通道,我用 PixInsight 内置 StarNet 流程,先生成了一份经过 MaskedStretch 的预览图,然后让模型算出星点蒙版。检查蒙版时我通常直接看三个地方:

  • 亮星系核周围:这里最容易翻车,因为 M31 的星系核本身就是极亮区域,神经网络可能把它当成超大星点之一给摘掉
  • 暗弱尘埃带附近:这部分画面中既有弥散的暗尘埃,又有零星暗星点,是考验模型分离能力的高难度区域
  • 画面边缘:边缘的畸变和噪声如果太强,蒙版上会出现明显的不连续块

实测下来 StarNet 的表现比 PSF 拟合法稳定得多。星系核没有被当成恒星摘走,边缘虽然有几处蒙版小瑕疵,但用 0.5 像素的轻微羽化就能抹平。

4.3 无星版本处理与合成

拿到干净的无星图之后,真正的乐趣从这开始。无星图里的像素不包含星点能量,你可以放心地把黑电平拉到很低,也可以给结构做很强的反卷积或 HDR 变换,不用担心亮星周围出现黑圈或者色差。

我用无星版本做了这些处理:

  1. 对照星点蒙版做了几轮 LocalHistogramEqualization,把 M31 尘埃带和外侧旋臂的纹理层次拉开
  2. 对无星图整体加了一点 SCNR 绿色降噪,因为去星之后原本被星点掩盖的绿色噪声显露出来了
  3. 把原图的星点图缩到适当大小,强化了亮星色彩,再作为叠加层混合回去

最后一步叠合时有个分水岭:你是想保留“满天星点”的真实观感,还是做“缩星”后的干净深空风格。我选择缩星后星点略小但色彩饱和,再在中央高光区域加一点星芒效果,最终成图比单处理原图时质感高了一个档次。

5. 常见故障与避坑实录

5.1 显存不足与高分辨率图卡顿

StarNet 虽然是轻量级网络,但它对输入分辨率非常敏感。我最初用一张 6240×4168 的全尺寸单反图直接跑,结果 GPU 显存直接顶满报错。解决办法不是换显卡,而是把图像缩放,一般缩到 1000~1600 像素宽度效果和全尺寸差异肉眼几乎看不出来。

还有一个很少有人提的点:显存不够时不要急着降低画质,可以先切分图像分块处理。网上有封装好的脚本支持把大图切成四块或者九块,分别推理再拼接,我用这个方法处理过亿级像素的马赛克拼图,效果和整图推理基本一致。

5.2 星点去除不干净或亮星出现伪影

最常见的解释其实是“你的预处理这一步没有达标”。如果输入图像里有强烈的竖纹、坏行或者没有校准好的偏置,神经网络会把这些伪装成恒星信号的特征,导致蒙版上全是乱七八糟的白点。

另外要注意一点:StarNet 对红蓝两个通道的权重并不完全相同,彩色图像里如果蓝通道有明显色差,星点边缘容易留下蓝色残留。我的补救方案是先做一次星点对齐(用 PSF 对星点中心做亚像素配准),再跑 StarNet,结果会干净很多。

5.3 星点蒙版在交接上的微妙失误

用 StarNet 生成蒙版后,很多人习惯直接拿蒙版当图层透明度直接做处理,这其实是个坑。因为蒙版是浮点权重图,范围是 0 到 1,而你在编辑软件里常常默认它是 8 位或 16 位整数。换算过程中如果不做归一化,蒙版的暗部细节会整段丢失。

我自己的做法是:在 PixInsight 里始终以浮点格式保存蒙版,跨软件处理时导出成 32 位 TIFF。如果实在要导出 16 位,请记得在导出前给蒙版乘一个 65535 的缩放系数,否则切回 16 位整型后,原本小于 1/65535 的微弱权重全部变成 0,星点周边羽化效果直接被磨平。

6. 一些个人经验和后续可以尝试的方向

跑了大半年 StarNet,我最大的体会是:它不是一个替代人工的“一键修图”工具,而是一个重构后期工作流的“第七块拼图”。过去一套片子要处理两三天,主要时间耗在星点的反复微调上,而现在我把星点分离这一步交给网络之后,更多精力用在延展天体的层次表现和色彩还原上。

最后再分享几个我在实际操作中觉得特别值得记住的细节:

  • 如果目标画面里有特别亮的木星、金星这类太阳系天体,StarNet 很容易误判为“超亮恒星”,生成蒙版时会把整个天体连同它的镜头光晕一起扣掉。遇到这种图,建议先把行星区域手动遮盖一下再跑。
  • 我习惯保存两份中间结果:一份是刚分离完的原始无星图,一份是处理到一半的弱拉伸版本。这样如果某种后期策略效果不理想,可以从任意一步重新开始,而不必从头跑模型。
  • 后续想尝试的方向是彩色窄带图像的分离。当前 StarNet 在 RGB 合成后的窄带图上表现还可以,但窄带原始信号直接分离时仍会出现Ha与RGB通道错位的问题。如果你也在这方面试过,欢迎多交流踩坑心得。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询